From b3509dec610a633a05e38a491a7adaa346d3ee5a Mon Sep 17 00:00:00 2001 From: Renbo Date: Fri, 8 Nov 2024 11:31:18 +0800 Subject: [PATCH 01/17] [BA] update to qemu-kvm-6.2.0-53.2.src.rpm to #bug11660 update to qemu-kvm-6.2.0-53.2.src.rpm Signed-off-by: Renbo --- 0001-Add-Acpi-support.patch | 1348 -- 0001-anolis-csv-i386-add-CSV-context.patch | 205 - 0002-Support-rtc.patch | 370 - ...add-command-to-initialize-CSV-contex.patch | 204 - 0003-Add-loongarch-machine.patch | 5752 ------ ...add-command-to-load-data-to-guest-me.patch | 164 - 0004-Add-target-loongarch64.patch | 15917 ---------------- ...add-command-to-load-vmcb-to-guest-me.patch | 107 - 0005-Add-linux-headers-and-linux-user.patch | 1663 -- ...populate-CPUID-0x8000_001F-when-CSV-.patch | 41 - 0006-Add-disas-gdb.patch | 3183 --- ...CSV-guest-do-not-need-register-unreg.patch | 35 - 0007-Modify-kvm-cpu-vga-qapi.patch | 477 - ...86-csv-load-initial-image-to-private.patch | 44 - 0008-Modify-compile-script.patch | 36 - ...-vga-force-full-update-for-CSV-guest.patch | 47 - 0009-Add-loongarch64-rh-devices.mak.patch | 3227 ---- ...D-SEV-to-include-Live-migration-flow.patch | 69 - ...dd-AMD-SEV-specific-migration-parame.patch | 253 - ...st-support-introduce-ConfidentialGue.patch | 67 - ...provide-callback-to-setup-outgoing-c.patch | 135 - ...do-not-create-launch-context-for-an-.patch | 48 - ...add-support-to-encrypt-the-outgoing-.patch | 324 - ...add-support-to-load-incoming-encrypt.patch | 224 - ...for-SEV-shared-regions-list-and-KVM_.patch | 293 - ...pport-to-migrate-shared-regions-list.patch | 103 - ...-add-support-to-send-encrypted-pages.patch | 338 - ...rce-encrypted-status-for-flash0-flas.patch | 44 - ...V-live-migration-bump-downtime-limit.patch | 64 - ...86-kvm-Add-support-for-MSR-filtering.patch | 201 - ...for-userspace-MSR-filtering-and-hand.patch | 118 - ...-ram-Force-encrypted-status-for-VGA-.patch | 33 - ...86-sev-Clear-shared_regions_list-whe.patch | 58 - ...-ram-Fix-calculation-of-gfn-correpon.patch | 57 - ...86-csv-Move-is_hygon_cpu-to-header-f.patch | 85 - ...86-csv-Read-cert-chain-from-file-whe.patch | 131 - ...86-csv-add-support-to-queue-the-outg.patch | 270 - ...86-csv-add-support-to-encrypt-the-ou.patch | 204 - ...86-csv-add-support-to-queue-the-inco.patch | 171 - ...86-csv-add-support-to-load-incoming-.patch | 108 - ...-ram-Accelerate-the-transmission-of-.patch | 229 - ...-ram-Accelerate-the-loading-of-CSV-g.patch | 37 - ...86-csv-Add-support-for-migrate-VMSA-.patch | 416 - ...rget-i386-get-set-migrate-GHCB-state.patch | 175 - ...86-kvm-Return-resettable-when-emulat.patch | 39 - ...olis-kvm-Add-support-for-CSV2-reboot.patch | 170 - ...-map-shared-region-for-CSV-virtual-m.patch | 384 - ...ders-update-kernel-headers-to-includ.patch | 79 - ...add-support-to-migrate-the-outgoing-.patch | 453 - ...add-support-to-migrate-the-incoming-.patch | 204 - ...add-support-to-migrate-the-outgoing-.patch | 137 - ...add-support-to-migrate-the-incoming-.patch | 109 - ...86-sev-Add-support-for-reuse-ASID-fo.patch | 192 - 1074-newfeature-support-vpsp.patch | 190 - ...t-i386-Add-Hygon-Dhyana-v3-CPU-model.patch | 43 - ...-i386-Add-new-Hygon-Dharma-CPU-model.patch | 133 - 1077-target-i386-add-FSRM-to-TCG.patch | 35 - 1078-target-i386-add-FZRM-FSRS-FSRC.patch | 67 - ...386-Add-new-CPU-model-SapphireRapids.patch | 226 - ...support-for-CMPCCXADD-in-CPUID-enume.patch | 59 - ...support-for-AMX-FP16-in-CPUID-enumer.patch | 60 - ...support-for-AVX-IFMA-in-CPUID-enumer.patch | 58 - ...support-for-AVX-VNNI-INT8-in-CPUID-e.patch | 108 - ...support-for-AVX-NE-CONVERT-in-CPUID-.patch | 59 - ...support-for-PREFETCHIT0-1-in-CPUID-e.patch | 58 - ...st-feature-level-according-to-FEAT_7.patch | 43 - ...new-bit-definitions-of-MSR_IA32_ARCH.patch | 40 - ...support-for-MCDT_NO-in-CPUID-enumera.patch | 110 - ...i386-Add-new-CPU-model-GraniteRapids.patch | 181 - ...support-for-AMX-COMPLEX-in-CPUID-enu.patch | 57 - ...-i386-Add-new-CPU-model-SierraForest.patch | 207 - ...arget-i386-Export-RFDS-bit-to-guests.patch | 45 - ...few-security-fix-bits-in-ARCH_CAPABI.patch | 50 - ...oduce-SapphireRapids-v3-to-add-missi.patch | 45 - ...recated-bpf_program__set_socket_filt.patch | 37 - ...rt-MSR_ARCH_CAPABILITIES-bits-to-gue.patch | 45 - 81-kvm-anolis.rules => 81-kvm-rhel.rules | 0 Add-lbt-support-for-kvm.patch | 154 - ...to-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch | 28 - Add-usb-storage-config-for-loongarch.patch | 26 - Fix-LoongArch-KVM-header-macros.patch | 32 - ...cture-macro-of-LoongArch-to-HOST_LOO.patch | 27 - ...and-fpu-option-to-compat-with-kernel.patch | 31 - Fix-smp.cores-value.patch | 35 - ...-where-qemu-specifies-the-boot-order.patch | 140 - ...tion-lack-and-Modify-the-maximum-num.patch | 44 - Modify-the-ioctl-command-of-kvm.patch | 32 - Support-TPM.patch | 518 - Support-vfio-config.patch | 47 - ...pace-code-cleanup-on-7A-virt-machine.patch | 276 - code-cleanup-for-loongarch-kvm.patch | 34 - fix-smbios-type4-info-for-numa-support.patch | 44 - fixup-can-t-find-cpu-type.patch | 34 - ...l-size-default-value-in-the-man-page.patch | 36 + ...e-bdrv_qiov_is_aligned-to-file-posix.patch | 104 + ...the-request-length-for-iov-alignment.patch | 48 + kvm-csr-save-and-restore-optimization.patch | 599 - ...iofsd-Adjust-limit-for-minor-version.patch | 41 - loongarch_bios.bin | Bin 4190208 -> 0 bytes loongarch_vars.bin | Bin 389120 -> 0 bytes pass-to-make-check.patch | 164 - qemu-kvm.spec | 251 +- rename-kvm_msr_buf-with-kvm_csr_buf.patch | 638 - 103 files changed, 212 insertions(+), 43969 deletions(-) delete mode 100644 0001-Add-Acpi-support.patch delete mode 100644 0001-anolis-csv-i386-add-CSV-context.patch delete mode 100644 0002-Support-rtc.patch delete mode 100644 0002-anolis-csv-i386-add-command-to-initialize-CSV-contex.patch delete mode 100644 0003-Add-loongarch-machine.patch delete mode 100644 0003-anolis-csv-i386-add-command-to-load-data-to-guest-me.patch delete mode 100644 0004-Add-target-loongarch64.patch delete mode 100644 0004-anolis-csv-i386-add-command-to-load-vmcb-to-guest-me.patch delete mode 100644 0005-Add-linux-headers-and-linux-user.patch delete mode 100644 0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch delete mode 100644 0006-Add-disas-gdb.patch delete mode 100644 0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch delete mode 100644 0007-Modify-kvm-cpu-vga-qapi.patch delete mode 100644 0007-anolis-target-i386-csv-load-initial-image-to-private.patch delete mode 100644 0008-Modify-compile-script.patch delete mode 100644 0008-anolis-vga-force-full-update-for-CSV-guest.patch delete mode 100644 0009-Add-loongarch64-rh-devices.mak.patch delete mode 100644 1038-doc-update-AMD-SEV-to-include-Live-migration-flow.patch delete mode 100644 1039-migration.json-add-AMD-SEV-specific-migration-parame.patch delete mode 100644 1040-confidential-guest-support-introduce-ConfidentialGue.patch delete mode 100644 1041-target-i386-sev-provide-callback-to-setup-outgoing-c.patch delete mode 100644 1042-target-i386-sev-do-not-create-launch-context-for-an-.patch delete mode 100644 1043-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch delete mode 100644 1044-target-i386-sev-add-support-to-load-incoming-encrypt.patch delete mode 100644 1045-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch delete mode 100644 1046-migration-add-support-to-migrate-shared-regions-list.patch delete mode 100644 1047-migration-ram-add-support-to-send-encrypted-pages.patch delete mode 100644 1048-migration-ram-Force-encrypted-status-for-flash0-flas.patch delete mode 100644 1049-migration-for-SEV-live-migration-bump-downtime-limit.patch delete mode 100644 1050-i386-kvm-Add-support-for-MSR-filtering.patch delete mode 100644 1051-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch delete mode 100644 1052-anolis-migration-ram-Force-encrypted-status-for-VGA-.patch delete mode 100644 1053-anolis-target-i386-sev-Clear-shared_regions_list-whe.patch delete mode 100644 1054-anolis-migration-ram-Fix-calculation-of-gfn-correpon.patch delete mode 100644 1055-anolis-target-i386-csv-Move-is_hygon_cpu-to-header-f.patch delete mode 100644 1056-anolis-target-i386-csv-Read-cert-chain-from-file-whe.patch delete mode 100644 1057-anolis-target-i386-csv-add-support-to-queue-the-outg.patch delete mode 100644 1058-anolis-target-i386-csv-add-support-to-encrypt-the-ou.patch delete mode 100644 1059-anolis-target-i386-csv-add-support-to-queue-the-inco.patch delete mode 100644 1060-anolis-target-i386-csv-add-support-to-load-incoming-.patch delete mode 100644 1061-anolis-migration-ram-Accelerate-the-transmission-of-.patch delete mode 100644 1062-anolis-migration-ram-Accelerate-the-loading-of-CSV-g.patch delete mode 100644 1063-anolis-target-i386-csv-Add-support-for-migrate-VMSA-.patch delete mode 100644 1064-anolis-target-i386-get-set-migrate-GHCB-state.patch delete mode 100644 1065-anolis-target-i386-kvm-Return-resettable-when-emulat.patch delete mode 100644 1066-anolis-kvm-Add-support-for-CSV2-reboot.patch delete mode 100644 1067-anolis-vfio-only-map-shared-region-for-CSV-virtual-m.patch delete mode 100644 1068-anolis-linux-headers-update-kernel-headers-to-includ.patch delete mode 100644 1069-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch delete mode 100644 1070-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch delete mode 100644 1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch delete mode 100644 1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch delete mode 100644 1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch delete mode 100644 1074-newfeature-support-vpsp.patch delete mode 100644 1075-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch delete mode 100644 1076-target-i386-Add-new-Hygon-Dharma-CPU-model.patch delete mode 100644 1077-target-i386-add-FSRM-to-TCG.patch delete mode 100644 1078-target-i386-add-FZRM-FSRS-FSRC.patch delete mode 100644 1079-i386-Add-new-CPU-model-SapphireRapids.patch delete mode 100644 1080-target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch delete mode 100644 1081-target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch delete mode 100644 1082-target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch delete mode 100644 1083-target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch delete mode 100644 1084-target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch delete mode 100644 1085-target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch delete mode 100644 1086-target-i386-Adjust-feature-level-according-to-FEAT_7.patch delete mode 100644 1087-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch delete mode 100644 1088-target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch delete mode 100644 1089-target-i386-Add-new-CPU-model-GraniteRapids.patch delete mode 100644 1090-target-i386-Add-support-for-AMX-COMPLEX-in-CPUID-enu.patch delete mode 100644 1091-target-i386-Add-new-CPU-model-SierraForest.patch delete mode 100644 1092-target-i386-Export-RFDS-bit-to-guests.patch delete mode 100644 1093-target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch delete mode 100644 1094-target-i386-Introduce-SapphireRapids-v3-to-add-missi.patch delete mode 100644 1095-ebpf-replace-deprecated-bpf_program__set_socket_filt.patch delete mode 100644 1096-target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch rename 81-kvm-anolis.rules => 81-kvm-rhel.rules (100%) delete mode 100644 Add-lbt-support-for-kvm.patch delete mode 100644 Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch delete mode 100644 Add-usb-storage-config-for-loongarch.patch delete mode 100644 Fix-LoongArch-KVM-header-macros.patch delete mode 100644 Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch delete mode 100644 Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch delete mode 100644 Fix-smp.cores-value.patch delete mode 100644 Fixed-the-issue-where-qemu-specifies-the-boot-order.patch delete mode 100644 Modify-smbios-option-lack-and-Modify-the-maximum-num.patch delete mode 100644 Modify-the-ioctl-command-of-kvm.patch delete mode 100644 Support-TPM.patch delete mode 100644 Support-vfio-config.patch delete mode 100644 address-space-code-cleanup-on-7A-virt-machine.patch delete mode 100644 code-cleanup-for-loongarch-kvm.patch delete mode 100644 fix-smbios-type4-info-for-numa-support.patch delete mode 100644 fixup-can-t-find-cpu-type.patch create mode 100644 kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch create mode 100644 kvm-block-move-bdrv_qiov_is_aligned-to-file-posix.patch create mode 100644 kvm-block-use-the-request-length-for-iov-alignment.patch delete mode 100644 kvm-csr-save-and-restore-optimization.patch delete mode 100644 kvm-virtiofsd-Adjust-limit-for-minor-version.patch delete mode 100644 loongarch_bios.bin delete mode 100644 loongarch_vars.bin delete mode 100644 pass-to-make-check.patch delete mode 100644 rename-kvm_msr_buf-with-kvm_csr_buf.patch diff --git a/0001-Add-Acpi-support.patch b/0001-Add-Acpi-support.patch deleted file mode 100644 index 101c3a4..0000000 --- a/0001-Add-Acpi-support.patch +++ /dev/null @@ -1,1348 +0,0 @@ -From 935f85c0025bbaaed976940ed0d57c23bfc68f94 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Fri, 19 Aug 2022 23:11:23 -0400 -Subject: [PATCH 01/28] Add Acpi support. - -Change-Id: I208228b2178cddf365e97c6faf6111ef40e795eb -Signed-off-by: lixianglai ---- - hw/acpi/Kconfig | 8 + - hw/acpi/larch_7a.c | 600 +++++++++++++++++++++++++++++++++++++++++ - hw/acpi/ls7a.c | 598 ++++++++++++++++++++++++++++++++++++++++ - hw/acpi/meson.build | 1 + - include/hw/acpi/ls7a.h | 80 ++++++ - 5 files changed, 1287 insertions(+) - create mode 100644 hw/acpi/larch_7a.c - create mode 100644 hw/acpi/ls7a.c - create mode 100644 include/hw/acpi/ls7a.h - -diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig -index 622b0b50b..2f2fb33a7 100644 ---- a/hw/acpi/Kconfig -+++ b/hw/acpi/Kconfig -@@ -15,6 +15,14 @@ config ACPI_X86_ICH - bool - select ACPI_X86 - -+config ACPI_LOONGARCH -+ bool -+ select ACPI -+ select ACPI_CPU_HOTPLUG -+ select ACPI_MEMORY_HOTPLUG -+ select ACPI_PIIX4 -+ select ACPI_PCIHP -+ - config ACPI_CPU_HOTPLUG - bool - -diff --git a/hw/acpi/larch_7a.c b/hw/acpi/larch_7a.c -new file mode 100644 -index 000000000..35d4a7526 ---- /dev/null -+++ b/hw/acpi/larch_7a.c -@@ -0,0 +1,600 @@ -+#include "qemu/osdep.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/runstate.h" -+#include "sysemu/reset.h" -+#include "hw/hw.h" -+#include "hw/irq.h" -+#include "hw/acpi/acpi.h" -+#include "hw/acpi/ls7a.h" -+#include "hw/nvram/fw_cfg.h" -+#include "qemu/config-file.h" -+#include "qapi/opts-visitor.h" -+#include "qapi/qapi-events-run-state.h" -+#include "qapi/error.h" -+#include "hw/loongarch/ls7a.h" -+#include "hw/mem/pc-dimm.h" -+#include "hw/mem/nvdimm.h" -+#include "migration/vmstate.h" -+ -+static void ls7a_pm_update_sci_fn(ACPIREGS *regs) -+{ -+ LS7APCIPMRegs *pm = container_of(regs, LS7APCIPMRegs, acpi_regs); -+ acpi_update_sci(&pm->acpi_regs, pm->irq); -+} -+ -+static uint64_t ls7a_gpe_readb(void *opaque, hwaddr addr, unsigned width) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ return acpi_gpe_ioport_readb(&pm->acpi_regs, addr); -+} -+ -+static void ls7a_gpe_writeb(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val); -+ acpi_update_sci(&pm->acpi_regs, pm->irq); -+} -+ -+static const MemoryRegionOps ls7a_gpe_ops = { -+ .read = ls7a_gpe_readb, -+ .write = ls7a_gpe_writeb, -+ .valid.min_access_size = 1, -+ .valid.max_access_size = 8, -+ .impl.min_access_size = 1, -+ .impl.max_access_size = 1, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+#define VMSTATE_GPE_ARRAY(_field, _state) \ -+ { \ -+ .name = (stringify(_field)), \ -+ .version_id = 0, \ -+ .num = ACPI_GPE0_LEN, \ -+ .info = &vmstate_info_uint8, \ -+ .size = sizeof(uint8_t), \ -+ .flags = VMS_ARRAY | VMS_POINTER, \ -+ .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ -+ } -+ -+static uint64_t ls7a_reset_readw(void *opaque, hwaddr addr, unsigned width) -+{ -+ return 0; -+} -+ -+static void ls7a_reset_writew(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ if (val & 1) { -+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); -+ return; -+ } -+} -+ -+static const MemoryRegionOps ls7a_reset_ops = { -+ .read = ls7a_reset_readw, -+ .write = ls7a_reset_writew, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static bool vmstate_test_use_memhp(void *opaque) -+{ -+ LS7APCIPMRegs *s = opaque; -+ return s->acpi_memory_hotplug.is_enabled; -+} -+ -+static const VMStateDescription vmstate_memhp_state = { -+ .name = "ls7a_pm/memhp", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .minimum_version_id_old = 1, -+ .needed = vmstate_test_use_memhp, -+ .fields = (VMStateField[]) { -+ VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, LS7APCIPMRegs), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+static const VMStateDescription vmstate_cpuhp_state = { -+ .name = "ls7a_pm/cpuhp", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .minimum_version_id_old = 1, -+ .fields = (VMStateField[]) { -+ VMSTATE_CPU_HOTPLUG(cpuhp_state, LS7APCIPMRegs), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+const VMStateDescription vmstate_ls7a_pm = { -+ .name = "ls7a_pm", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT16(acpi_regs.pm1.evt.sts, LS7APCIPMRegs), -+ VMSTATE_UINT16(acpi_regs.pm1.evt.en, LS7APCIPMRegs), -+ VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, LS7APCIPMRegs), -+ VMSTATE_TIMER_PTR(acpi_regs.tmr.timer, LS7APCIPMRegs), -+ VMSTATE_INT64(acpi_regs.tmr.overflow_time, LS7APCIPMRegs), -+ VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, LS7APCIPMRegs), -+ VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, LS7APCIPMRegs), -+ VMSTATE_END_OF_LIST() -+ }, -+ .subsections = (const VMStateDescription * []) { -+ &vmstate_memhp_state, -+ &vmstate_cpuhp_state, -+ NULL -+ } -+}; -+ -+static inline int64_t acpi_pm_tmr_get_clock(void) -+{ -+ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY, -+ NANOSECONDS_PER_SECOND); -+} -+ -+static uint32_t acpi_pm_tmr_get(ACPIREGS *ar) -+{ -+ uint32_t d = acpi_pm_tmr_get_clock(); -+ return d & 0xffffff; -+} -+ -+static void acpi_pm_tmr_timer(void *opaque) -+{ -+ ACPIREGS *ar = opaque; -+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_PMTIMER, NULL); -+ ar->tmr.update_sci(ar); -+} -+ -+static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width) -+{ -+ return acpi_pm_tmr_get(opaque); -+} -+ -+static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ /* nothing */ -+} -+ -+static const MemoryRegionOps acpi_pm_tmr_ops = { -+ .read = acpi_pm_tmr_read, -+ .write = acpi_pm_tmr_write, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static void ls7a_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, -+ MemoryRegion *parent, uint64_t offset) -+{ -+ ar->tmr.update_sci = update_sci; -+ ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar); -+ memory_region_init_io(&ar->tmr.io, memory_region_owner(parent), -+ &acpi_pm_tmr_ops, ar, "acpi-tmr", 4); -+ memory_region_add_subregion(parent, offset, &ar->tmr.io); -+} -+ -+static void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val) -+{ -+ uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar); -+ if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) { -+ /* if TMRSTS is reset, then compute the new overflow time */ -+ acpi_pm_tmr_calc_overflow_time(ar); -+ } -+ ar->pm1.evt.sts &= ~val; -+} -+ -+static uint64_t acpi_pm_evt_read(void *opaque, hwaddr addr, unsigned width) -+{ -+ ACPIREGS *ar = opaque; -+ switch (addr) { -+ case 0: -+ return acpi_pm1_evt_get_sts(ar); -+ case 4: -+ return ar->pm1.evt.en; -+ default: -+ return 0; -+ } -+} -+ -+static void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val) -+{ -+ ar->pm1.evt.en = val; -+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, -+ val & ACPI_BITMASK_RT_CLOCK_ENABLE); -+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, -+ val & ACPI_BITMASK_TIMER_ENABLE); -+} -+ -+static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ ACPIREGS *ar = opaque; -+ switch (addr) { -+ case 0: -+ acpi_pm1_evt_write_sts(ar, val); -+ ar->pm1.evt.update_sci(ar); -+ break; -+ case 4: -+ acpi_pm1_evt_write_en(ar, val); -+ ar->pm1.evt.update_sci(ar); -+ break; -+ } -+} -+ -+static const MemoryRegionOps acpi_pm_evt_ops = { -+ .read = acpi_pm_evt_read, -+ .write = acpi_pm_evt_write, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static void ls7a_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, -+ MemoryRegion *parent, uint64_t offset) -+{ -+ ar->pm1.evt.update_sci = update_sci; -+ memory_region_init_io(&ar->pm1.evt.io, memory_region_owner(parent), -+ &acpi_pm_evt_ops, ar, "acpi-evt", 8); -+ memory_region_add_subregion(parent, offset, &ar->pm1.evt.io); -+} -+ -+static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width) -+{ -+ ACPIREGS *ar = opaque; -+ return ar->pm1.cnt.cnt; -+} -+ -+/* ACPI PM1aCNT */ -+static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val) -+{ -+ ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE); -+ if (val & ACPI_BITMASK_SLEEP_ENABLE) { -+ /* change suspend type */ -+ uint16_t sus_typ = (val >> 10) & 7; -+ switch (sus_typ) { -+ /* s3,s4 not support */ -+ case 5: -+ case 6: -+ warn_report("acpi s3,s4 state not support"); -+ break; -+ /* s5: soft off */ -+ case 7: -+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); -+ break; -+ default: -+ break; -+ } -+ } -+} -+ -+static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ acpi_pm1_cnt_write(opaque, val); -+} -+ -+static const MemoryRegionOps acpi_pm_cnt_ops = { -+ .read = acpi_pm_cnt_read, -+ .write = acpi_pm_cnt_write, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static void acpi_notify_wakeup(Notifier *notifier, void *data) -+{ -+ ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup); -+ WakeupReason *reason = data; -+ -+ switch (*reason) { -+ case QEMU_WAKEUP_REASON_RTC: -+ ar->pm1.evt.sts |= -+ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS); -+ break; -+ case QEMU_WAKEUP_REASON_PMTIMER: -+ ar->pm1.evt.sts |= -+ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS); -+ break; -+ case QEMU_WAKEUP_REASON_OTHER: -+ /* ACPI_BITMASK_WAKE_STATUS should be set on resume. -+ * Pretend that resume was caused by power button */ -+ ar->pm1.evt.sts |= -+ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS); -+ break; -+ default: -+ break; -+ } -+} -+ -+static void ls7a_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, -+ bool disable_s3, bool disable_s4, uint8_t s4_val, uint64_t offset) -+{ -+ FWCfgState *fw_cfg; -+ -+ ar->pm1.cnt.s4_val = s4_val; -+ ar->wakeup.notify = acpi_notify_wakeup; -+ qemu_register_wakeup_notifier(&ar->wakeup); -+ memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent), -+ &acpi_pm_cnt_ops, ar, "acpi-cnt", 4); -+ memory_region_add_subregion(parent, offset, &ar->pm1.cnt.io); -+ -+ fw_cfg = fw_cfg_find(); -+ if (fw_cfg) { -+ uint8_t suspend[6] = {128, 0, 0, 129, 128, 128}; -+ suspend[3] = 1 | ((!disable_s3) << 7); -+ suspend[4] = s4_val | ((!disable_s4) << 7); -+ fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6); -+ } -+} -+ -+static void ls7a_pm_reset(void *opaque) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ -+ acpi_pm1_evt_reset(&pm->acpi_regs); -+ acpi_pm1_cnt_reset(&pm->acpi_regs); -+ acpi_pm_tmr_reset(&pm->acpi_regs); -+ acpi_gpe_reset(&pm->acpi_regs); -+ -+ acpi_update_sci(&pm->acpi_regs, pm->irq); -+} -+ -+static void pm_powerdown_req(Notifier *n, void *opaque) -+{ -+ LS7APCIPMRegs *pm = container_of(n, LS7APCIPMRegs, powerdown_notifier); -+ -+ acpi_pm1_evt_power_down(&pm->acpi_regs); -+} -+ -+void ls7a_pm_init(LS7APCIPMRegs *pm, qemu_irq *pic) -+{ -+ unsigned long base, gpe_len, acpi_aci_irq; -+ -+ /* ls7a board acpi hardware info, including -+ * acpi system io base address -+ * acpi gpe length -+ * acpi sci irq number -+ */ -+ base = ACPI_IO_BASE; -+ gpe_len = ACPI_GPE0_LEN; -+ acpi_aci_irq = ACPI_SCI_IRQ; -+ -+ pm->irq = pic[acpi_aci_irq - 64]; -+ memory_region_init(&pm->iomem, NULL, "ls7a_pm", ACPI_IO_SIZE); -+ memory_region_add_subregion(get_system_memory(), base, &pm->iomem); -+ -+ cpu_hotplug_hw_init(get_system_memory(), NULL, -+ &pm->cpuhp_state, CPU_HOTPLUG_BASE); -+ -+ ls7a_pm_tmr_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, LS7A_PM_TMR_BLK); -+ ls7a_pm1_evt_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, LS7A_PM_EVT_BLK); -+ ls7a_pm1_cnt_init(&pm->acpi_regs, &pm->iomem, false, false, 2, LS7A_PM_CNT_BLK); -+ -+ acpi_gpe_init(&pm->acpi_regs, gpe_len); -+ memory_region_init_io(&pm->iomem_gpe, NULL, &ls7a_gpe_ops, pm, -+ "acpi-gpe0", gpe_len); -+ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_STS_REG, &pm->iomem_gpe); -+ -+ memory_region_init_io(&pm->iomem_reset, NULL, &ls7a_reset_ops, pm, -+ "acpi-reset", 4); -+ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_RESET_REG, &pm->iomem_reset); -+ -+ qemu_register_reset(ls7a_pm_reset, pm); -+ -+ pm->powerdown_notifier.notify = pm_powerdown_req; -+ qemu_register_powerdown_notifier(&pm->powerdown_notifier); -+ -+ if (pm->acpi_memory_hotplug.is_enabled) { -+ acpi_memory_hotplug_init(get_system_memory(), NULL, -+ &pm->acpi_memory_hotplug, MEMORY_HOTPLUG_BASE); -+ } -+} -+ -+ -+static void ls7a_pm_get_gpe0_blk(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ uint64_t value = ACPI_IO_BASE + LS7A_GPE0_STS_REG; -+ -+ visit_type_uint64(v, name, &value, errp); -+} -+ -+static bool ls7a_pm_get_memory_hotplug_support(Object *obj, Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(obj); -+ -+ return ls7a->pm.acpi_memory_hotplug.is_enabled; -+} -+ -+static void ls7a_pm_set_memory_hotplug_support(Object *obj, bool value, -+ Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(obj); -+ -+ ls7a->pm.acpi_memory_hotplug.is_enabled = value; -+} -+ -+static void ls7a_pm_get_disable_s3(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ uint8_t value = pm->disable_s3; -+ -+ visit_type_uint8(v, name, &value, errp); -+} -+ -+static void ls7a_pm_set_disable_s3(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ Error *local_err = NULL; -+ uint8_t value; -+ -+ visit_type_uint8(v, name, &value, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ pm->disable_s3 = value; -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void ls7a_pm_get_disable_s4(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ uint8_t value = pm->disable_s4; -+ -+ visit_type_uint8(v, name, &value, errp); -+} -+ -+static void ls7a_pm_set_disable_s4(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ Error *local_err = NULL; -+ uint8_t value; -+ -+ visit_type_uint8(v, name, &value, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ pm->disable_s4 = value; -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void ls7a_pm_get_s4_val(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ uint8_t value = pm->s4_val; -+ -+ visit_type_uint8(v, name, &value, errp); -+} -+ -+static void ls7a_pm_set_s4_val(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ Error *local_err = NULL; -+ uint8_t value; -+ -+ visit_type_uint8(v, name, &value, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ pm->s4_val = value; -+out: -+ error_propagate(errp, local_err); -+} -+ -+void ls7a_pm_add_properties(Object *obj, LS7APCIPMRegs *pm, Error **errp) -+{ -+ static const uint32_t gpe0_len = ACPI_GPE0_LEN; -+ pm->acpi_memory_hotplug.is_enabled = true; -+ pm->disable_s3 = 0; -+ pm->disable_s4 = 0; -+ pm->s4_val = 2; -+ -+ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE, -+ &pm->pm_io_base, OBJ_PROP_FLAG_READ); -+ object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32", -+ ls7a_pm_get_gpe0_blk, -+ NULL, NULL, pm); -+ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN, -+ &gpe0_len, OBJ_PROP_FLAG_READ); -+ object_property_add_bool(obj, "memory-hotplug-support", -+ ls7a_pm_get_memory_hotplug_support, -+ ls7a_pm_set_memory_hotplug_support); -+ object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8", -+ ls7a_pm_get_disable_s3, -+ ls7a_pm_set_disable_s3, -+ NULL, pm); -+ object_property_add(obj, ACPI_PM_PROP_S4_DISABLED, "uint8", -+ ls7a_pm_get_disable_s4, -+ ls7a_pm_set_disable_s4, -+ NULL, pm); -+ object_property_add(obj, ACPI_PM_PROP_S4_VAL, "uint8", -+ ls7a_pm_get_s4_val, -+ ls7a_pm_set_s4_val, -+ NULL, pm); -+} -+ -+void ls7a_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); -+ -+ if (ls7a->pm.acpi_memory_hotplug.is_enabled && -+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { -+ nvdimm_acpi_plug_cb(hotplug_dev, dev); -+ } else { -+ acpi_memory_plug_cb(hotplug_dev, &ls7a->pm.acpi_memory_hotplug, -+ dev, errp); -+ } -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { -+ acpi_cpu_plug_cb(hotplug_dev, &ls7a->pm.cpuhp_state, dev, errp); -+ } else { -+ error_setg(errp, "acpi: device plug request for not supported device" -+ " type: %s", object_get_typename(OBJECT(dev))); -+ } -+} -+ -+void ls7a_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); -+ -+ if (ls7a->pm.acpi_memory_hotplug.is_enabled && -+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ acpi_memory_unplug_request_cb(hotplug_dev, -+ &ls7a->pm.acpi_memory_hotplug, dev, -+ errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { -+ acpi_cpu_unplug_request_cb(hotplug_dev, &ls7a->pm.cpuhp_state, -+ dev, errp); -+ } else { -+ error_setg(errp, "acpi: device unplug request for not supported device" -+ " type: %s", object_get_typename(OBJECT(dev))); -+ } -+} -+ -+void ls7a_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); -+ -+ if (ls7a->pm.acpi_memory_hotplug.is_enabled && -+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ acpi_memory_unplug_cb(&ls7a->pm.acpi_memory_hotplug, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { -+ acpi_cpu_unplug_cb(&ls7a->pm.cpuhp_state, dev, errp); -+ } else { -+ error_setg(errp, "acpi: device unplug for not supported device" -+ " type: %s", object_get_typename(OBJECT(dev))); -+ } -+} -+ -+void ls7a_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); -+ -+ acpi_memory_ospm_status(&ls7a->pm.acpi_memory_hotplug, list); -+ acpi_cpu_ospm_status(&ls7a->pm.cpuhp_state, list); -+} -+ -+void ls7a_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); -+ -+ acpi_send_gpe_event(&ls7a->pm.acpi_regs, ls7a->pm.irq, ev); -+} -+ -+ -+ -diff --git a/hw/acpi/ls7a.c b/hw/acpi/ls7a.c -new file mode 100644 -index 000000000..2de50ccb9 ---- /dev/null -+++ b/hw/acpi/ls7a.c -@@ -0,0 +1,598 @@ -+#include "qemu/osdep.h" -+#include "sysemu/sysemu.h" -+#include "hw/hw.h" -+#include "hw/irq.h" -+#include "hw/acpi/acpi.h" -+#include "hw/acpi/ls7a.h" -+#include "hw/nvram/fw_cfg.h" -+#include "qemu/config-file.h" -+#include "qapi/opts-visitor.h" -+#include "qapi/qapi-events-run-state.h" -+#include "qapi/error.h" -+#include "hw/mips/ls7a.h" -+#include "hw/mem/pc-dimm.h" -+#include "hw/mem/nvdimm.h" -+ -+static void ls7a_pm_update_sci_fn(ACPIREGS *regs) -+{ -+ LS7APCIPMRegs *pm = container_of(regs, LS7APCIPMRegs, acpi_regs); -+ acpi_update_sci(&pm->acpi_regs, pm->irq); -+} -+ -+static uint64_t ls7a_gpe_readb(void *opaque, hwaddr addr, unsigned width) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ return acpi_gpe_ioport_readb(&pm->acpi_regs, addr); -+} -+ -+static void ls7a_gpe_writeb(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val); -+ acpi_update_sci(&pm->acpi_regs, pm->irq); -+} -+ -+static const MemoryRegionOps ls7a_gpe_ops = { -+ .read = ls7a_gpe_readb, -+ .write = ls7a_gpe_writeb, -+ .valid.min_access_size = 1, -+ .valid.max_access_size = 8, -+ .impl.min_access_size = 1, -+ .impl.max_access_size = 1, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+#define VMSTATE_GPE_ARRAY(_field, _state) \ -+ { \ -+ .name = (stringify(_field)), \ -+ .version_id = 0, \ -+ .num = ACPI_GPE0_LEN, \ -+ .info = &vmstate_info_uint8, \ -+ .size = sizeof(uint8_t), \ -+ .flags = VMS_ARRAY | VMS_POINTER, \ -+ .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ -+ } -+ -+static uint64_t ls7a_reset_readw(void *opaque, hwaddr addr, unsigned width) -+{ -+ return 0; -+} -+ -+static void ls7a_reset_writew(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ if (val & 1) { -+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); -+ return; -+ } -+} -+ -+static const MemoryRegionOps ls7a_reset_ops = { -+ .read = ls7a_reset_readw, -+ .write = ls7a_reset_writew, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static bool vmstate_test_use_memhp(void *opaque) -+{ -+ LS7APCIPMRegs *s = opaque; -+ return s->acpi_memory_hotplug.is_enabled; -+} -+ -+static const VMStateDescription vmstate_memhp_state = { -+ .name = "ls7a_pm/memhp", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .minimum_version_id_old = 1, -+ .needed = vmstate_test_use_memhp, -+ .fields = (VMStateField[]) { -+ VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, LS7APCIPMRegs), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+static const VMStateDescription vmstate_cpuhp_state = { -+ .name = "ls7a_pm/cpuhp", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .minimum_version_id_old = 1, -+ .fields = (VMStateField[]) { -+ VMSTATE_CPU_HOTPLUG(cpuhp_state, LS7APCIPMRegs), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+const VMStateDescription vmstate_ls7a_pm = { -+ .name = "ls7a_pm", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT16(acpi_regs.pm1.evt.sts, LS7APCIPMRegs), -+ VMSTATE_UINT16(acpi_regs.pm1.evt.en, LS7APCIPMRegs), -+ VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, LS7APCIPMRegs), -+ VMSTATE_TIMER_PTR(acpi_regs.tmr.timer, LS7APCIPMRegs), -+ VMSTATE_INT64(acpi_regs.tmr.overflow_time, LS7APCIPMRegs), -+ VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, LS7APCIPMRegs), -+ VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, LS7APCIPMRegs), -+ VMSTATE_END_OF_LIST() -+ }, -+ .subsections = (const VMStateDescription * []) { -+ &vmstate_memhp_state, -+ &vmstate_cpuhp_state, -+ NULL -+ } -+}; -+ -+static inline int64_t acpi_pm_tmr_get_clock(void) -+{ -+ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY, -+ NANOSECONDS_PER_SECOND); -+} -+ -+static uint32_t acpi_pm_tmr_get(ACPIREGS *ar) -+{ -+ uint32_t d = acpi_pm_tmr_get_clock(); -+ return d & 0xffffff; -+} -+ -+static void acpi_pm_tmr_timer(void *opaque) -+{ -+ ACPIREGS *ar = opaque; -+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_PMTIMER, NULL); -+ ar->tmr.update_sci(ar); -+} -+ -+static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width) -+{ -+ return acpi_pm_tmr_get(opaque); -+} -+ -+static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ /* nothing */ -+} -+ -+static const MemoryRegionOps acpi_pm_tmr_ops = { -+ .read = acpi_pm_tmr_read, -+ .write = acpi_pm_tmr_write, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static void ls7a_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, -+ MemoryRegion *parent, uint64_t offset) -+{ -+ ar->tmr.update_sci = update_sci; -+ ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar); -+ memory_region_init_io(&ar->tmr.io, memory_region_owner(parent), -+ &acpi_pm_tmr_ops, ar, "acpi-tmr", 4); -+ memory_region_add_subregion(parent, offset, &ar->tmr.io); -+} -+ -+static void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val) -+{ -+ uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar); -+ if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) { -+ /* if TMRSTS is reset, then compute the new overflow time */ -+ acpi_pm_tmr_calc_overflow_time(ar); -+ } -+ ar->pm1.evt.sts &= ~val; -+} -+ -+static uint64_t acpi_pm_evt_read(void *opaque, hwaddr addr, unsigned width) -+{ -+ ACPIREGS *ar = opaque; -+ switch (addr) { -+ case 0: -+ return acpi_pm1_evt_get_sts(ar); -+ case 4: -+ return ar->pm1.evt.en; -+ default: -+ return 0; -+ } -+} -+ -+static void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val) -+{ -+ ar->pm1.evt.en = val; -+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, -+ val & ACPI_BITMASK_RT_CLOCK_ENABLE); -+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, -+ val & ACPI_BITMASK_TIMER_ENABLE); -+} -+ -+static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ ACPIREGS *ar = opaque; -+ switch (addr) { -+ case 0: -+ acpi_pm1_evt_write_sts(ar, val); -+ ar->pm1.evt.update_sci(ar); -+ break; -+ case 4: -+ acpi_pm1_evt_write_en(ar, val); -+ ar->pm1.evt.update_sci(ar); -+ break; -+ } -+} -+ -+static const MemoryRegionOps acpi_pm_evt_ops = { -+ .read = acpi_pm_evt_read, -+ .write = acpi_pm_evt_write, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static void ls7a_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, -+ MemoryRegion *parent, uint64_t offset) -+{ -+ ar->pm1.evt.update_sci = update_sci; -+ memory_region_init_io(&ar->pm1.evt.io, memory_region_owner(parent), -+ &acpi_pm_evt_ops, ar, "acpi-evt", 8); -+ memory_region_add_subregion(parent, offset, &ar->pm1.evt.io); -+} -+ -+static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width) -+{ -+ ACPIREGS *ar = opaque; -+ return ar->pm1.cnt.cnt; -+} -+ -+/* ACPI PM1aCNT */ -+static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val) -+{ -+ ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE); -+ -+ if (val & ACPI_BITMASK_SLEEP_ENABLE) { -+ /* change suspend type */ -+ uint16_t sus_typ = (val >> 10) & 7; -+ switch (sus_typ) { -+ case 0: /* soft power off */ -+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); -+ break; -+ case 1: -+ qemu_system_suspend_request(); -+ break; -+ default: -+ if (sus_typ == ar->pm1.cnt.s4_val) { /* S4 request */ -+ qapi_event_send_suspend_disk(); -+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); -+ } -+ break; -+ } -+ } -+} -+ -+static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ acpi_pm1_cnt_write(opaque, val); -+} -+ -+static const MemoryRegionOps acpi_pm_cnt_ops = { -+ .read = acpi_pm_cnt_read, -+ .write = acpi_pm_cnt_write, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static void acpi_notify_wakeup(Notifier *notifier, void *data) -+{ -+ ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup); -+ WakeupReason *reason = data; -+ -+ switch (*reason) { -+ case QEMU_WAKEUP_REASON_RTC: -+ ar->pm1.evt.sts |= -+ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS); -+ break; -+ case QEMU_WAKEUP_REASON_PMTIMER: -+ ar->pm1.evt.sts |= -+ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS); -+ break; -+ case QEMU_WAKEUP_REASON_OTHER: -+ /* ACPI_BITMASK_WAKE_STATUS should be set on resume. -+ * Pretend that resume was caused by power button */ -+ ar->pm1.evt.sts |= -+ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS); -+ break; -+ default: -+ break; -+ } -+} -+ -+static void ls7a_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, -+ bool disable_s3, bool disable_s4, uint8_t s4_val, uint64_t offset) -+{ -+ FWCfgState *fw_cfg; -+ -+ ar->pm1.cnt.s4_val = s4_val; -+ ar->wakeup.notify = acpi_notify_wakeup; -+ qemu_register_wakeup_notifier(&ar->wakeup); -+ memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent), -+ &acpi_pm_cnt_ops, ar, "acpi-cnt", 4); -+ memory_region_add_subregion(parent, offset, &ar->pm1.cnt.io); -+ -+ fw_cfg = fw_cfg_find(); -+ if (fw_cfg) { -+ uint8_t suspend[6] = {128, 0, 0, 129, 128, 128}; -+ suspend[3] = 1 | ((!disable_s3) << 7); -+ suspend[4] = s4_val | ((!disable_s4) << 7); -+ fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6); -+ } -+} -+ -+static void ls7a_pm_reset(void *opaque) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ -+ acpi_pm1_evt_reset(&pm->acpi_regs); -+ acpi_pm1_cnt_reset(&pm->acpi_regs); -+ acpi_pm_tmr_reset(&pm->acpi_regs); -+ acpi_gpe_reset(&pm->acpi_regs); -+ -+ acpi_update_sci(&pm->acpi_regs, pm->irq); -+} -+ -+static void pm_powerdown_req(Notifier *n, void *opaque) -+{ -+ LS7APCIPMRegs *pm = container_of(n, LS7APCIPMRegs, powerdown_notifier); -+ -+ acpi_pm1_evt_power_down(&pm->acpi_regs); -+} -+ -+void ls7a_pm_init(LS7APCIPMRegs *pm, qemu_irq *pic) -+{ -+ unsigned long base, gpe_len, acpi_aci_irq; -+ -+ /* ls7a board acpi hardware info, including -+ * acpi system io base address -+ * acpi gpe length -+ * acpi sci irq number -+ */ -+ base = ACPI_IO_BASE; -+ gpe_len = ACPI_GPE0_LEN; -+ acpi_aci_irq = ACPI_SCI_IRQ; -+ -+ pm->irq = pic[acpi_aci_irq - 64]; -+ memory_region_init(&pm->iomem, NULL, "ls7a_pm", ACPI_IO_SIZE); -+ memory_region_add_subregion(get_system_memory(), base, &pm->iomem); -+ -+ cpu_hotplug_hw_init(get_system_memory(), NULL, &pm->cpuhp_state, CPU_HOTPLUG_BASE); -+ -+ ls7a_pm_tmr_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, LS7A_PM_TMR_BLK); -+ ls7a_pm1_evt_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, LS7A_PM_EVT_BLK); -+ ls7a_pm1_cnt_init(&pm->acpi_regs, &pm->iomem, false, false, 2, LS7A_PM_CNT_BLK); -+ -+ acpi_gpe_init(&pm->acpi_regs, gpe_len); -+ memory_region_init_io(&pm->iomem_gpe, NULL, &ls7a_gpe_ops, pm, -+ "acpi-gpe0", gpe_len); -+ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_STS_REG, &pm->iomem_gpe); -+ -+ memory_region_init_io(&pm->iomem_reset, NULL, &ls7a_reset_ops, pm, -+ "acpi-reset", 4); -+ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_RESET_REG, &pm->iomem_reset); -+ -+ qemu_register_reset(ls7a_pm_reset, pm); -+ -+ pm->powerdown_notifier.notify = pm_powerdown_req; -+ qemu_register_powerdown_notifier(&pm->powerdown_notifier); -+ -+ if (pm->acpi_memory_hotplug.is_enabled) { -+ acpi_memory_hotplug_init(get_system_memory(), NULL, -+ &pm->acpi_memory_hotplug, MEMORY_HOTPLUG_BASE); -+ } -+} -+ -+ -+static void ls7a_pm_get_gpe0_blk(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ uint64_t value = ACPI_IO_BASE + LS7A_GPE0_STS_REG; -+ -+ visit_type_uint64(v, name, &value, errp); -+} -+ -+static bool ls7a_pm_get_memory_hotplug_support(Object *obj, Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(obj); -+ -+ return ls7a->pm.acpi_memory_hotplug.is_enabled; -+} -+ -+static void ls7a_pm_set_memory_hotplug_support(Object *obj, bool value, -+ Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(obj); -+ -+ ls7a->pm.acpi_memory_hotplug.is_enabled = value; -+} -+ -+static void ls7a_pm_get_disable_s3(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ uint8_t value = pm->disable_s3; -+ -+ visit_type_uint8(v, name, &value, errp); -+} -+ -+static void ls7a_pm_set_disable_s3(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ Error *local_err = NULL; -+ uint8_t value; -+ -+ visit_type_uint8(v, name, &value, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ pm->disable_s3 = value; -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void ls7a_pm_get_disable_s4(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ uint8_t value = pm->disable_s4; -+ -+ visit_type_uint8(v, name, &value, errp); -+} -+ -+static void ls7a_pm_set_disable_s4(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ Error *local_err = NULL; -+ uint8_t value; -+ -+ visit_type_uint8(v, name, &value, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ pm->disable_s4 = value; -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void ls7a_pm_get_s4_val(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ uint8_t value = pm->s4_val; -+ -+ visit_type_uint8(v, name, &value, errp); -+} -+ -+static void ls7a_pm_set_s4_val(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ Error *local_err = NULL; -+ uint8_t value; -+ -+ visit_type_uint8(v, name, &value, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ pm->s4_val = value; -+out: -+ error_propagate(errp, local_err); -+} -+ -+void ls7a_pm_add_properties(Object *obj, LS7APCIPMRegs *pm, Error **errp) -+{ -+ static const uint32_t gpe0_len = ACPI_GPE0_LEN; -+ pm->acpi_memory_hotplug.is_enabled = true; -+ pm->disable_s3 = 0; -+ pm->disable_s4 = 0; -+ pm->s4_val = 2; -+ -+ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE, -+ &pm->pm_io_base, OBJ_PROP_FLAG_READ); -+ object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32", -+ ls7a_pm_get_gpe0_blk, -+ NULL, NULL, pm); -+ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN, -+ &gpe0_len, OBJ_PROP_FLAG_READ); -+ object_property_add_bool(obj, "memory-hotplug-support", -+ ls7a_pm_get_memory_hotplug_support, -+ ls7a_pm_set_memory_hotplug_support); -+ object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8", -+ ls7a_pm_get_disable_s3, -+ ls7a_pm_set_disable_s3, -+ NULL, pm); -+ object_property_add(obj, ACPI_PM_PROP_S4_DISABLED, "uint8", -+ ls7a_pm_get_disable_s4, -+ ls7a_pm_set_disable_s4, -+ NULL, pm); -+ object_property_add(obj, ACPI_PM_PROP_S4_VAL, "uint8", -+ ls7a_pm_get_s4_val, -+ ls7a_pm_set_s4_val, -+ NULL, pm); -+} -+ -+void ls7a_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); -+ -+ if (ls7a->pm.acpi_memory_hotplug.is_enabled && -+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { -+ nvdimm_acpi_plug_cb(hotplug_dev, dev); -+ } else { -+ acpi_memory_plug_cb(hotplug_dev, &ls7a->pm.acpi_memory_hotplug, -+ dev, errp); -+ } -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { -+ acpi_cpu_plug_cb(hotplug_dev, &ls7a->pm.cpuhp_state, dev, errp); -+ } else { -+ error_setg(errp, "acpi: device plug request for not supported device" -+ " type: %s", object_get_typename(OBJECT(dev))); -+ } -+} -+ -+void ls7a_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); -+ -+ if (ls7a->pm.acpi_memory_hotplug.is_enabled && -+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ acpi_memory_unplug_request_cb(hotplug_dev, -+ &ls7a->pm.acpi_memory_hotplug, dev, -+ errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { -+ acpi_cpu_unplug_request_cb(hotplug_dev, &ls7a->pm.cpuhp_state, -+ dev, errp); -+ } else { -+ error_setg(errp, "acpi: device unplug request for not supported device" -+ " type: %s", object_get_typename(OBJECT(dev))); -+ } -+} -+ -+void ls7a_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); -+ -+ if (ls7a->pm.acpi_memory_hotplug.is_enabled && -+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ acpi_memory_unplug_cb(&ls7a->pm.acpi_memory_hotplug, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { -+ acpi_cpu_unplug_cb(&ls7a->pm.cpuhp_state, dev, errp); -+ } else { -+ error_setg(errp, "acpi: device unplug for not supported device" -+ " type: %s", object_get_typename(OBJECT(dev))); -+ } -+} -+ -+void ls7a_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); -+ -+ acpi_memory_ospm_status(&ls7a->pm.acpi_memory_hotplug, list); -+ acpi_cpu_ospm_status(&ls7a->pm.cpuhp_state, list); -+} -+ -+void ls7a_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); -+ -+ acpi_send_gpe_event(&ls7a->pm.acpi_regs, ls7a->pm.irq, ev); -+} -+ -+ -+ -diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build -index adf6347bc..5fe4cfa4f 100644 ---- a/hw/acpi/meson.build -+++ b/hw/acpi/meson.build -@@ -6,6 +6,7 @@ acpi_ss.add(files( - 'core.c', - 'utils.c', - )) -+acpi_ss.add(when: 'CONFIG_ACPI_LOONGARCH', if_true: files('larch_7a.c')) - acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_true: files('cpu.c', 'cpu_hotplug.c')) - acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_false: files('acpi-cpu-hotplug-stub.c')) - acpi_ss.add(when: 'CONFIG_ACPI_MEMORY_HOTPLUG', if_true: files('memory_hotplug.c')) -diff --git a/include/hw/acpi/ls7a.h b/include/hw/acpi/ls7a.h -new file mode 100644 -index 000000000..4401515c7 ---- /dev/null -+++ b/include/hw/acpi/ls7a.h -@@ -0,0 +1,80 @@ -+/* -+ * QEMU GMCH/LS7A PCI PM Emulation -+ * -+ * Copyright (c) 2009 Isaku Yamahata -+ * VA Linux Systems Japan K.K. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see -+ */ -+ -+#ifndef HW_ACPI_LS7A_H -+#define HW_ACPI_LS7A_H -+ -+#include "hw/acpi/acpi.h" -+#include "hw/acpi/cpu_hotplug.h" -+#include "hw/acpi/cpu.h" -+#include "hw/acpi/memory_hotplug.h" -+#include "hw/acpi/acpi_dev_interface.h" -+#include "hw/acpi/tco.h" -+ -+#define CPU_HOTPLUG_BASE 0x1e000000 -+#define MEMORY_HOTPLUG_BASE 0x1e00000c -+ -+typedef struct LS7APCIPMRegs { -+ /* -+ * In ls7a spec says that pm1_cnt register is 32bit width and -+ * that the upper 16bits are reserved and unused. -+ * PM1a_CNT_BLK = 2 in FADT so it is defined as uint16_t. -+ */ -+ ACPIREGS acpi_regs; -+ -+ MemoryRegion iomem; -+ MemoryRegion iomem_gpe; -+ MemoryRegion iomem_smi; -+ MemoryRegion iomem_reset; -+ -+ qemu_irq irq; /* SCI */ -+ -+ uint32_t pm_io_base; -+ Notifier powerdown_notifier; -+ -+ bool cpu_hotplug_legacy; -+ AcpiCpuHotplug gpe_cpu; -+ CPUHotplugState cpuhp_state; -+ -+ MemHotplugState acpi_memory_hotplug; -+ -+ uint8_t disable_s3; -+ uint8_t disable_s4; -+ uint8_t s4_val; -+} LS7APCIPMRegs; -+ -+void ls7a_pm_init(LS7APCIPMRegs *ls7a, qemu_irq *sci_irq); -+ -+void ls7a_pm_iospace_update(LS7APCIPMRegs *pm, uint32_t pm_io_base); -+extern const VMStateDescription vmstate_ls7a_pm; -+ -+void ls7a_pm_add_properties(Object *obj, LS7APCIPMRegs *pm, Error **errp); -+ -+void ls7a_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp); -+void ls7a_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp); -+void ls7a_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp); -+ -+void ls7a_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); -+ -+void ls7a_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev); -+#endif /* HW_ACPI_LS7A_H */ --- -2.43.5 - diff --git a/0001-anolis-csv-i386-add-CSV-context.patch b/0001-anolis-csv-i386-add-CSV-context.patch deleted file mode 100644 index 89e3d49..0000000 --- a/0001-anolis-csv-i386-add-CSV-context.patch +++ /dev/null @@ -1,205 +0,0 @@ -From fda324e163898d543e215cfec1aa3d26ba816426 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Tue, 24 Aug 2021 14:57:28 +0800 -Subject: [PATCH 1/8] anolis: csv/i386: add CSV context - -CSV is the secure virtualization feature on Hygon CPU. -It is compatible with the AMD SEV/SEV-ES and extends out -specific funtionality by setting bit 6 of guest policy. - -Add the context and the build option. - -Change-Id: I02b48c779dd25ddda4546fe3e28c1fe0c8c2e4c6 -Signed-off-by: Xin Jiang ---- - configs/devices/i386-softmmu/default.mak | 1 + - .../x86_64-softmmu/x86_64-rh-devices.mak | 1 + - hw/i386/Kconfig | 5 ++ - target/i386/csv-sysemu-stub.c | 16 ++++++ - target/i386/csv.c | 51 +++++++++++++++++++ - target/i386/csv.h | 35 +++++++++++++ - target/i386/meson.build | 1 + - 7 files changed, 110 insertions(+) - create mode 100644 target/i386/csv-sysemu-stub.c - create mode 100644 target/i386/csv.c - create mode 100644 target/i386/csv.h - -diff --git a/configs/devices/i386-softmmu/default.mak b/configs/devices/i386-softmmu/default.mak -index 598c6646df..db83ffcab9 100644 ---- a/configs/devices/i386-softmmu/default.mak -+++ b/configs/devices/i386-softmmu/default.mak -@@ -23,6 +23,7 @@ - #CONFIG_TPM_TIS_ISA=n - #CONFIG_VTD=n - #CONFIG_SGX=n -+#CONFIG_CSV=n - - # Boards: - # -diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak -index 31ce08edab..ee1df7aa52 100644 ---- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak -+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak -@@ -102,3 +102,4 @@ CONFIG_TPM_TIS_ISA=y - CONFIG_TPM_EMULATOR=y - CONFIG_TPM_PASSTHROUGH=y - CONFIG_SGX=y -+CONFIG_CSV=y -diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig -index d22ac4a4b9..ed35d762b3 100644 ---- a/hw/i386/Kconfig -+++ b/hw/i386/Kconfig -@@ -10,6 +10,10 @@ config SGX - bool - depends on KVM - -+config CSV -+ bool -+ depends on SEV -+ - config PC - bool - imply APPLESMC -@@ -26,6 +30,7 @@ config PC - imply QXL - imply SEV - imply SGX -+ imply CSV - imply SGA - imply TEST_DEVICES - imply TPM_CRB -diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c -new file mode 100644 -index 0000000000..a89b2600e7 ---- /dev/null -+++ b/target/i386/csv-sysemu-stub.c -@@ -0,0 +1,16 @@ -+/* -+ * QEMU CSV support -+ * -+ * Copyright: Hygon Info Technologies Ltd. 2022 -+ * -+ * Author: -+ * Jiang Xin -+ * -+ * 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 "sev.h" -+#include "csv.h" -diff --git a/target/i386/csv.c b/target/i386/csv.c -new file mode 100644 -index 0000000000..aac825d3f9 ---- /dev/null -+++ b/target/i386/csv.c -@@ -0,0 +1,51 @@ -+/* -+ * QEMU CSV support -+ * -+ * Copyright: Hygon Info Technologies Ltd. 2022 -+ * -+ * Author: -+ * Jiang Xin -+ * -+ * 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 "sev.h" -+#include "csv.h" -+ -+CsvGuestState csv_guest = { 0 }; -+ -+#define CPUID_VENDOR_HYGON_EBX 0x6f677948 /* "Hygo" */ -+#define CPUID_VENDOR_HYGON_ECX 0x656e6975 /* "uine" */ -+#define CPUID_VENDOR_HYGON_EDX 0x6e65476e /* "nGen" */ -+ -+#define GUEST_POLICY_CSV_BIT (1 << 6) -+ -+static bool is_hygon_cpu(void) -+{ -+ uint32_t ebx = 0; -+ uint32_t ecx = 0; -+ uint32_t edx = 0; -+ -+ host_cpuid(0, 0, NULL, &ebx, &ecx, &edx); -+ -+ if (ebx == CPUID_VENDOR_HYGON_EBX && -+ ecx == CPUID_VENDOR_HYGON_ECX && -+ edx == CPUID_VENDOR_HYGON_EDX) -+ return true; -+ else -+ return false; -+} -+ -+bool -+csv_enabled(void) -+{ -+ if (!is_hygon_cpu()) -+ return false; -+ -+ return sev_es_enabled() && (csv_guest.policy & GUEST_POLICY_CSV_BIT); -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -new file mode 100644 -index 0000000000..057d37d975 ---- /dev/null -+++ b/target/i386/csv.h -@@ -0,0 +1,35 @@ -+/* -+ * QEMU CSV support -+ * -+ * Copyright: Hygon Info Technologies Ltd. 2022 -+ * -+ * Author: -+ * Jiang Xin -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or later. -+ * See the COPYING file in the top-level directory. -+ * -+ */ -+ -+#ifndef QEMU_CSV_H -+#define QEMU_CSV_H -+ -+#include "qapi/qapi-commands-misc-target.h" -+ -+#ifdef CONFIG_CSV -+bool csv_enabled(void); -+#else -+#define csv_enabled() 0 -+#endif -+ -+struct CsvGuestState { -+ uint32_t policy; -+ int sev_fd; -+ void *state; -+}; -+ -+typedef struct CsvGuestState CsvGuestState; -+ -+extern struct CsvGuestState csv_guest; -+ -+#endif -diff --git a/target/i386/meson.build b/target/i386/meson.build -index ae38dc9563..361dea9290 100644 ---- a/target/i386/meson.build -+++ b/target/i386/meson.build -@@ -21,6 +21,7 @@ i386_softmmu_ss.add(files( - 'cpu-sysemu.c', - )) - i386_softmmu_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('sev-sysemu-stub.c')) -+i386_softmmu_ss.add(when: 'CONFIG_CSV', if_true: files('csv.c'), if_false: files('csv-sysemu-stub.c')) - - i386_user_ss = ss.source_set() - --- -2.17.1 - diff --git a/0002-Support-rtc.patch b/0002-Support-rtc.patch deleted file mode 100644 index 989778e..0000000 --- a/0002-Support-rtc.patch +++ /dev/null @@ -1,370 +0,0 @@ -From e0a8c8cb06e866bd334501d637e7219a14ae601b Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Fri, 19 Aug 2022 23:15:49 -0400 -Subject: [PATCH 02/28] Support rtc. - -Change-Id: Idd50274dd2a6c00b21ec0cd099f8d115ab4fa449 -Signed-off-by: lixianglai ---- - hw/timer/Kconfig | 2 + - hw/timer/ls7a_rtc.c | 325 +++++++++++++++++++++++++++++++++++++++++++ - hw/timer/meson.build | 1 + - 3 files changed, 328 insertions(+) - create mode 100644 hw/timer/ls7a_rtc.c - -diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig -index 010be7ed1..b395c72d7 100644 ---- a/hw/timer/Kconfig -+++ b/hw/timer/Kconfig -@@ -60,3 +60,5 @@ config STELLARIS_GPTM - - config AVR_TIMER16 - bool -+config LS7A_RTC -+ bool -diff --git a/hw/timer/ls7a_rtc.c b/hw/timer/ls7a_rtc.c -new file mode 100644 -index 000000000..756f2fc9c ---- /dev/null -+++ b/hw/timer/ls7a_rtc.c -@@ -0,0 +1,325 @@ -+#include "qemu/osdep.h" -+#include "hw/sysbus.h" -+#include "hw/irq.h" -+#include "include/hw/register.h" -+#include "qemu/timer.h" -+#include "sysemu/sysemu.h" -+#include "qemu/cutils.h" -+#include "qemu/log.h" -+#include "qemu-common.h" -+#include "migration/vmstate.h" -+ -+#ifdef DEBUG_LS7A_RTC -+#define DPRINTF (fmt, ...) \ -+do { printf("ls7a_rtc: " fmt , ## __VA_ARGS__); } while (0) -+#else -+#define DPRINTF (fmt, ...) do {} while (0) -+#endif -+ -+ -+#define SYS_TOYTRIM 0x20 -+#define SYS_TOYWRITE0 0x24 -+#define SYS_TOYWRITE1 0x28 -+#define SYS_TOYREAD0 0x2C -+#define SYS_TOYREAD1 0x30 -+#define SYS_TOYMATCH0 0x34 -+#define SYS_TOYMATCH1 0x38 -+#define SYS_TOYMATCH2 0x3C -+#define SYS_RTCCTRL 0x40 -+#define SYS_RTCTRIM 0x60 -+#define SYS_RTCWRTIE0 0x64 -+#define SYS_RTCREAD0 0x68 -+#define SYS_RTCMATCH0 0x6C -+#define SYS_RTCMATCH1 0x70 -+#define SYS_RTCMATCH2 0x74 -+ -+/** -+ ** shift bits and filed mask -+ **/ -+#define TOY_MON_MASK 0x3f -+#define TOY_DAY_MASK 0x1f -+#define TOY_HOUR_MASK 0x1f -+#define TOY_MIN_MASK 0x3f -+#define TOY_SEC_MASK 0x3f -+#define TOY_MSEC_MASK 0xf -+ -+#define TOY_MON_SHIFT 26 -+#define TOY_DAY_SHIFT 21 -+#define TOY_HOUR_SHIFT 16 -+#define TOY_MIN_SHIFT 10 -+#define TOY_SEC_SHIFT 4 -+#define TOY_MSEC_SHIFT 0 -+ -+#define TOY_MATCH_YEAR_MASK 0x3f -+#define TOY_MATCH_MON_MASK 0xf -+#define TOY_MATCH_DAY_MASK 0x1f -+#define TOY_MATCH_HOUR_MASK 0x1f -+#define TOY_MATCH_MIN_MASK 0x3f -+#define TOY_MATCH_SEC_MASK 0x3f -+ -+ -+#define TOY_MATCH_YEAR_SHIFT 26 -+#define TOY_MATCH_MON_SHIFT 22 -+#define TOY_MATCH_DAY_SHIFT 17 -+#define TOY_MATCH_HOUR_SHIFT 12 -+#define TOY_MATCH_MIN_SHIFT 6 -+#define TOY_MATCH_SEC_SHIFT 0 -+ -+#define TOY_ENABLE_BIT (1U << 11) -+ -+#define TYPE_LS7A_RTC "ls7a_rtc" -+#define LS7A_RTC(obj) OBJECT_CHECK(LS7A_RTCState, (obj), TYPE_LS7A_RTC) -+ -+typedef struct LS7A_RTCState { -+ SysBusDevice parent_obj; -+ -+ MemoryRegion iomem; -+ QEMUTimer *timer; -+ /* Needed to preserve the tick_count across migration, even if the -+ * absolute value of the rtc_clock is different on the source and -+ * destination. -+ */ -+ int64_t offset; -+ int64_t data; -+ int64_t save_alarm_offset; -+ int tidx; -+ uint32_t toymatch[3]; -+ uint32_t toytrim; -+ uint32_t cntrctl; -+ uint32_t rtctrim; -+ uint32_t rtccount; -+ uint32_t rtcmatch[3]; -+ qemu_irq toy_irq; -+} LS7A_RTCState; -+ -+enum { -+TOYEN = 1UL << 11, -+RTCEN = 1UL << 13, -+}; -+ -+static uint64_t ls7a_rtc_read(void *opaque, hwaddr addr, -+ unsigned size) -+{ -+ LS7A_RTCState *s = (LS7A_RTCState *)opaque; -+ struct tm tm; -+ unsigned int val; -+ -+ val = 0; -+ -+ switch (addr) { -+ case SYS_TOYREAD0: -+ qemu_get_timedate(&tm, s->offset); -+ val = (((tm.tm_mon + 1) & TOY_MON_MASK) << TOY_MON_SHIFT) -+ | (((tm.tm_mday) & TOY_DAY_MASK) << TOY_DAY_SHIFT) -+ | (((tm.tm_hour) & TOY_HOUR_MASK) << TOY_HOUR_SHIFT) -+ | (((tm.tm_min) & TOY_MIN_MASK) << TOY_MIN_SHIFT) -+ | (((tm.tm_sec) & TOY_SEC_MASK) << TOY_SEC_SHIFT) | 0x0; -+ break; -+ case SYS_TOYREAD1: -+ qemu_get_timedate(&tm, s->offset); -+ val = tm.tm_year; -+ break; -+ case SYS_TOYMATCH0: -+ val = s->toymatch[0]; -+ break; -+ case SYS_TOYMATCH1: -+ val = s->toymatch[1]; -+ break; -+ case SYS_TOYMATCH2: -+ val = s->toymatch[2]; -+ break; -+ case SYS_RTCCTRL: -+ val = s->cntrctl; -+ break; -+ case SYS_RTCREAD0: -+ val = s->rtccount; -+ break; -+ case SYS_RTCMATCH0: -+ val = s->rtcmatch[0]; -+ break; -+ case SYS_RTCMATCH1: -+ val = s->rtcmatch[1]; -+ break; -+ case SYS_RTCMATCH2: -+ val = s->rtcmatch[2]; -+ break; -+ default: -+ val = 0; -+ break; -+ } -+ return val; -+} -+ -+ -+static void ls7a_rtc_write(void *opaque, hwaddr addr, -+ uint64_t val, unsigned size) -+{ -+ LS7A_RTCState *s = (LS7A_RTCState *)opaque; -+ struct tm tm; -+ int64_t alarm_offset, year_diff, expire_time; -+ -+ switch (addr) { -+ case SYS_TOYWRITE0: -+ qemu_get_timedate(&tm, s->offset); -+ tm.tm_sec = (val >> TOY_SEC_SHIFT) & TOY_SEC_MASK; -+ tm.tm_min = (val >> TOY_MIN_SHIFT) & TOY_MIN_MASK; -+ tm.tm_hour = (val >> TOY_HOUR_SHIFT) & TOY_HOUR_MASK; -+ tm.tm_mday = ((val >> TOY_DAY_SHIFT) & TOY_DAY_MASK); -+ tm.tm_mon = ((val >> TOY_MON_SHIFT) & TOY_MON_MASK) - 1; -+ s->offset = qemu_timedate_diff(&tm); -+ break; -+ case SYS_TOYWRITE1: -+ qemu_get_timedate(&tm, s->offset); -+ tm.tm_year = val; -+ s->offset = qemu_timedate_diff(&tm); -+ break; -+ case SYS_TOYMATCH0: -+ s->toymatch[0] = val; -+ qemu_get_timedate(&tm, s->offset); -+ tm.tm_sec = (val >> TOY_MATCH_SEC_SHIFT) & TOY_MATCH_SEC_MASK; -+ tm.tm_min = (val >> TOY_MATCH_MIN_SHIFT) & TOY_MATCH_MIN_MASK; -+ tm.tm_hour = ((val >> TOY_MATCH_HOUR_SHIFT) & TOY_MATCH_HOUR_MASK); -+ tm.tm_mday = ((val >> TOY_MATCH_DAY_SHIFT) & TOY_MATCH_DAY_MASK); -+ tm.tm_mon = ((val >> TOY_MATCH_MON_SHIFT) & TOY_MATCH_MON_MASK) - 1; -+ year_diff = ((val >> TOY_MATCH_YEAR_SHIFT) & TOY_MATCH_YEAR_MASK); -+ year_diff = year_diff - (tm.tm_year & TOY_MATCH_YEAR_MASK); -+ tm.tm_year = tm.tm_year + year_diff; -+ alarm_offset = qemu_timedate_diff(&tm) - s->offset; -+ if ((alarm_offset < 0) && (alarm_offset > -5)) { -+ alarm_offset = 0; -+ } -+ expire_time = qemu_clock_get_ms(rtc_clock); -+ expire_time += ((alarm_offset * 1000) + 100); -+ timer_mod(s->timer, expire_time); -+ break; -+ case SYS_TOYMATCH1: -+ s->toymatch[1] = val; -+ break; -+ case SYS_TOYMATCH2: -+ s->toymatch[2] = val; -+ break; -+ case SYS_RTCCTRL: -+ s->cntrctl = val; -+ break; -+ case SYS_RTCWRTIE0: -+ s->rtccount = val; -+ break; -+ case SYS_RTCMATCH0: -+ s->rtcmatch[0] = val; -+ break; -+ case SYS_RTCMATCH1: -+ val = s->rtcmatch[1]; -+ break; -+ case SYS_RTCMATCH2: -+ val = s->rtcmatch[2]; -+ break; -+ default: -+ break; -+ } -+} -+ -+static const MemoryRegionOps ls7a_rtc_ops = { -+ .read = ls7a_rtc_read, -+ .write = ls7a_rtc_write, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+ .valid = { -+ .min_access_size = 4, -+ .max_access_size = 4, -+ }, -+ -+}; -+ -+static void toy_timer(void *opaque) -+{ -+ LS7A_RTCState *s = (LS7A_RTCState *) opaque; -+ -+ if (s->cntrctl & TOY_ENABLE_BIT) { -+ qemu_irq_pulse(s->toy_irq); -+ } -+} -+ -+static void ls7a_rtc_realize(DeviceState *dev, Error **errp) -+{ -+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev); -+ LS7A_RTCState *d = LS7A_RTC(sbd); -+ memory_region_init_io(&d->iomem, NULL, &ls7a_rtc_ops, -+ (void *)d, "ls7a_rtc", 0x100); -+ -+ sysbus_init_irq(sbd, &d->toy_irq); -+ -+ sysbus_init_mmio(sbd, &d->iomem); -+ d->timer = timer_new_ms(rtc_clock, toy_timer, d); -+ timer_mod(d->timer, qemu_clock_get_ms(rtc_clock) + 100); -+ d->offset = 0; -+} -+ -+static int ls7a_rtc_pre_save(void *opaque) -+{ -+ LS7A_RTCState *s = (LS7A_RTCState *)opaque; -+ struct tm tm; -+ int64_t year_diff, value; -+ -+ value = s->toymatch[0]; -+ qemu_get_timedate(&tm, s->offset); -+ tm.tm_sec = (value >> TOY_MATCH_SEC_SHIFT) & TOY_MATCH_SEC_MASK; -+ tm.tm_min = (value >> TOY_MATCH_MIN_SHIFT) & TOY_MATCH_MIN_MASK; -+ tm.tm_hour = ((value >> TOY_MATCH_HOUR_SHIFT) & TOY_MATCH_HOUR_MASK); -+ tm.tm_mday = ((value >> TOY_MATCH_DAY_SHIFT) & TOY_MATCH_DAY_MASK); -+ tm.tm_mon = ((value >> TOY_MATCH_MON_SHIFT) & TOY_MATCH_MON_MASK) - 1; -+ year_diff = ((value >> TOY_MATCH_YEAR_SHIFT) & TOY_MATCH_YEAR_MASK); -+ year_diff = year_diff - (tm.tm_year & TOY_MATCH_YEAR_MASK); -+ tm.tm_year = tm.tm_year + year_diff; -+ s->save_alarm_offset = qemu_timedate_diff(&tm) - s->offset; -+ -+ return 0; -+} -+ -+ -+static int ls7a_rtc_post_load(void *opaque, int version_id) -+{ -+ LS7A_RTCState *s = (LS7A_RTCState *)opaque; -+ int64_t expire_time; -+ -+ expire_time = qemu_clock_get_ms(rtc_clock) + (s->save_alarm_offset * 1000); -+ timer_mod(s->timer, expire_time); -+ -+ return 0; -+} -+ -+static const VMStateDescription vmstate_ls7a_rtc = { -+ .name = "ls7a_rtc", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .pre_save = ls7a_rtc_pre_save, -+ .post_load = ls7a_rtc_post_load, -+ .fields = (VMStateField[]) { -+ VMSTATE_INT64(offset, LS7A_RTCState), -+ VMSTATE_INT64(save_alarm_offset, LS7A_RTCState), -+ VMSTATE_UINT32(toymatch[0], LS7A_RTCState), -+ VMSTATE_UINT32(cntrctl, LS7A_RTCState), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+ -+static void ls7a_rtc_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ dc->vmsd = &vmstate_ls7a_rtc; -+ dc->realize = ls7a_rtc_realize; -+ dc->desc = "ls7a rtc"; -+} -+ -+static const TypeInfo ls7a_rtc_info = { -+ .name = TYPE_LS7A_RTC, -+ .parent = TYPE_SYS_BUS_DEVICE, -+ .instance_size = sizeof(LS7A_RTCState), -+ .class_init = ls7a_rtc_class_init, -+}; -+ -+static void ls7a_rtc_register_types(void) -+{ -+ type_register_static(&ls7a_rtc_info); -+} -+ -+type_init(ls7a_rtc_register_types) -diff --git a/hw/timer/meson.build b/hw/timer/meson.build -index 03092e2ce..e841a2f6e 100644 ---- a/hw/timer/meson.build -+++ b/hw/timer/meson.build -@@ -16,6 +16,7 @@ softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_mct.c')) - softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_pwm.c')) - softmmu_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_gptimer.c')) - softmmu_ss.add(when: 'CONFIG_HPET', if_true: files('hpet.c')) -+softmmu_ss.add(when: 'CONFIG_LS7A_RTC', if_true: files('ls7a_rtc.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')) --- -2.43.5 - diff --git a/0002-anolis-csv-i386-add-command-to-initialize-CSV-contex.patch b/0002-anolis-csv-i386-add-command-to-initialize-CSV-contex.patch deleted file mode 100644 index a62796a..0000000 --- a/0002-anolis-csv-i386-add-command-to-initialize-CSV-contex.patch +++ /dev/null @@ -1,204 +0,0 @@ -From 3239acc6c33806fac55fc08d7e5a81ef9ce85e23 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Wed, 25 Aug 2021 11:07:41 +0800 -Subject: [PATCH 2/8] anolis: csv/i386: add command to initialize CSV context - -When CSV is enabled, KVM_CSV_INIT command is used to initialize -the platform, which is implemented by reusing the SEV API -framework and extending the functionality. - -The KVM_CSV_INIT command should be performed earlier than -any other command. - -Signed-off-by: Xin Jiang -Change-Id: Ia4201dc90c250c23658e1cf5e19b528df9075330 ---- - linux-headers/linux/kvm.h | 11 +++++++++ - target/i386/csv-sysemu-stub.c | 5 ++++ - target/i386/csv.c | 44 +++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 3 +++ - target/i386/sev.c | 17 ++++++++++++++ - target/i386/sev.h | 5 ++++ - 6 files changed, 85 insertions(+) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index bcaf66cc4d..b15b8f5550 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1808,6 +1808,17 @@ struct kvm_sev_receive_update_data { - __u32 trans_len; - }; - -+/* CSV command */ -+enum csv_cmd_id { -+ KVM_CSV_NR_MIN = 0xc0, -+ -+ KVM_CSV_INIT = KVM_CSV_NR_MIN, -+}; -+ -+struct kvm_csv_init_data { -+ __u64 nodemask; -+}; -+ - #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) - #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) - #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) -diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c -index a89b2600e7..dbd710dc6f 100644 ---- a/target/i386/csv-sysemu-stub.c -+++ b/target/i386/csv-sysemu-stub.c -@@ -14,3 +14,8 @@ - #include "qemu/osdep.h" - #include "sev.h" - #include "csv.h" -+ -+int csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) -+{ -+ return 0; -+} -diff --git a/target/i386/csv.c b/target/i386/csv.c -index aac825d3f9..c11f59f30c 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -13,6 +13,12 @@ - - #include "qemu/osdep.h" - -+#include -+ -+#ifdef CONFIG_NUMA -+#include -+#endif -+ - #include "cpu.h" - #include "sev.h" - #include "csv.h" -@@ -41,6 +47,44 @@ static bool is_hygon_cpu(void) - return false; - } - -+int -+csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) -+{ -+ int fw_error; -+ int ret; -+ struct kvm_csv_init_data data = { 0 }; -+ -+#ifdef CONFIG_NUMA -+ int mode; -+ unsigned long nodemask; -+ -+ /* Set flags as 0 to retrieve the default NUMA policy. */ -+ ret = get_mempolicy(&mode, &nodemask, sizeof(nodemask) * 8, NULL, 0); -+ if (ret == 0 && (mode == MPOL_BIND)) -+ data.nodemask = nodemask; -+#endif -+ -+ if (!ops || !ops->sev_ioctl || !ops->fw_error_to_str) -+ return -1; -+ -+ csv_guest.policy = policy; -+ if (csv_enabled()) { -+ ret = ops->sev_ioctl(fd, KVM_CSV_INIT, &data, &fw_error); -+ if (ret) { -+ csv_guest.policy = 0; -+ error_report("%s: Fail to initialize ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, ops->fw_error_to_str(fw_error)); -+ return -1; -+ } -+ -+ csv_guest.sev_fd = fd; -+ csv_guest.state = state; -+ csv_guest.sev_ioctl = ops->sev_ioctl; -+ csv_guest.fw_error_to_str = ops->fw_error_to_str; -+ } -+ return 0; -+} -+ - bool - csv_enabled(void) - { -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 057d37d975..886dbb2613 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -26,10 +26,13 @@ struct CsvGuestState { - uint32_t policy; - int sev_fd; - void *state; -+ int (*sev_ioctl)(int fd, int cmd, void *data, int *error); -+ const char *(*fw_error_to_str)(int code); - }; - - typedef struct CsvGuestState CsvGuestState; - - extern struct CsvGuestState csv_guest; -+extern int csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops); - - #endif -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 025ff7a6f8..023532f4ec 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -26,6 +26,7 @@ - #include "crypto/hash.h" - #include "sysemu/kvm.h" - #include "sev.h" -+#include "csv.h" - #include "sysemu/sysemu.h" - #include "sysemu/runstate.h" - #include "trace.h" -@@ -43,6 +44,8 @@ - OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST) - - -+extern struct sev_ops sev_ops; -+ - /** - * SevGuestState: - * -@@ -952,6 +955,15 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - goto err; - } - -+ /* Support CSV */ -+ if (!ret && cmd == KVM_SEV_ES_INIT) { -+ ret = csv_init(sev_guest->policy, sev->sev_fd, &sev->state, &sev_ops); -+ if (ret) { -+ error_setg(errp, "%s: failed to init csv context", __func__); -+ goto err; -+ } -+ } -+ - ret = sev_launch_start(sev); - if (ret) { - error_setg(errp, "%s: failed to create encryption context", __func__); -@@ -1332,6 +1344,11 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) - return ret; - } - -+struct sev_ops sev_ops = { -+ .sev_ioctl = sev_ioctl, -+ .fw_error_to_str = fw_error_to_str, -+}; -+ - static void - sev_register_types(void) - { -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 83e82aa42c..1c97bff99e 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -59,4 +59,9 @@ void sev_es_set_reset_vector(CPUState *cpu); - - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - -+struct sev_ops { -+ int (*sev_ioctl)(int fd, int cmd, void *data, int *error); -+ const char *(*fw_error_to_str)(int code); -+}; -+ - #endif --- -2.17.1 - diff --git a/0003-Add-loongarch-machine.patch b/0003-Add-loongarch-machine.patch deleted file mode 100644 index 9052ba7..0000000 --- a/0003-Add-loongarch-machine.patch +++ /dev/null @@ -1,5752 +0,0 @@ -From 3cb18285115f8dd7f9135c65b39c93cb7eb3580c Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Fri, 19 Aug 2022 23:39:00 -0400 -Subject: [PATCH 03/28] Add loongarch machine. - -Change-Id: I7e31f874c676b740269945d5e19c6bc836de6a99 -Signed-off-by: lixianglai ---- - hw/loongarch/Kconfig | 17 + - hw/loongarch/acpi-build.c | 783 ++++++++++++ - hw/loongarch/acpi-build.h | 16 + - hw/loongarch/apic.c | 675 +++++++++++ - hw/loongarch/ioapic.c | 422 +++++++ - hw/loongarch/iocsr.c | 219 ++++ - hw/loongarch/ipi.c | 267 +++++ - hw/loongarch/larch_3a.c | 2026 ++++++++++++++++++++++++++++++++ - hw/loongarch/larch_hotplug.c | 355 ++++++ - hw/loongarch/larch_int.c | 91 ++ - hw/loongarch/ls7a_nb.c | 352 ++++++ - hw/loongarch/meson.build | 15 + - include/hw/loongarch/bios.h | 5 + - include/hw/loongarch/cpudevs.h | 53 + - include/hw/loongarch/larch.h | 163 +++ - include/hw/loongarch/ls7a.h | 152 +++ - 16 files changed, 5611 insertions(+) - create mode 100644 hw/loongarch/Kconfig - create mode 100644 hw/loongarch/acpi-build.c - create mode 100644 hw/loongarch/acpi-build.h - create mode 100644 hw/loongarch/apic.c - create mode 100644 hw/loongarch/ioapic.c - create mode 100644 hw/loongarch/iocsr.c - create mode 100644 hw/loongarch/ipi.c - create mode 100644 hw/loongarch/larch_3a.c - create mode 100644 hw/loongarch/larch_hotplug.c - create mode 100644 hw/loongarch/larch_int.c - create mode 100644 hw/loongarch/ls7a_nb.c - create mode 100644 hw/loongarch/meson.build - create mode 100644 include/hw/loongarch/bios.h - create mode 100644 include/hw/loongarch/cpudevs.h - create mode 100644 include/hw/loongarch/larch.h - create mode 100644 include/hw/loongarch/ls7a.h - -diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig -new file mode 100644 -index 000000000..3fe2677fd ---- /dev/null -+++ b/hw/loongarch/Kconfig -@@ -0,0 +1,17 @@ -+config LS7A_APIC -+ bool -+ -+config LS7A_RTC -+ bool -+ -+config LOONGSON3A -+ bool -+ -+config MEM_HOTPLUG -+ bool -+ -+config ACPI_LOONGARCH -+ bool -+ -+config E1000E_PCI -+ bool -diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c -new file mode 100644 -index 000000000..6ba637be5 ---- /dev/null -+++ b/hw/loongarch/acpi-build.c -@@ -0,0 +1,783 @@ -+/* Support for generating ACPI tables and passing them to Guests -+ * -+ * Copyright (C) 2008-2010 Kevin O'Connor -+ * Copyright (C) 2006 Fabrice Bellard -+ * Copyright (C) 2013 Red Hat Inc -+ * -+ * Author: Michael S. Tsirkin -+ * -+ * 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 . -+ */ -+ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include "qapi/qmp/qnum.h" -+#include "acpi-build.h" -+#include "qemu-common.h" -+#include "qemu/bitmap.h" -+#include "qemu/error-report.h" -+#include "hw/pci/pci.h" -+#include "hw/boards.h" -+#include "hw/core/cpu.h" -+#include "target/loongarch64/cpu.h" -+#include "hw/misc/pvpanic.h" -+#include "hw/timer/hpet.h" -+#include "hw/acpi/acpi-defs.h" -+#include "hw/acpi/acpi.h" -+#include "hw/acpi/cpu.h" -+#include "hw/nvram/fw_cfg.h" -+#include "hw/acpi/bios-linker-loader.h" -+#include "hw/loader.h" -+#include "hw/isa/isa.h" -+#include "hw/block/fdc.h" -+#include "hw/acpi/memory_hotplug.h" -+#include "sysemu/tpm.h" -+#include "hw/acpi/tpm.h" -+#include "hw/acpi/vmgenid.h" -+#include "sysemu/tpm_backend.h" -+#include "hw/rtc/mc146818rtc_regs.h" -+#include "sysemu/numa.h" -+#include "sysemu/runstate.h" -+#include "sysemu/reset.h" -+#include "migration/vmstate.h" -+#include "hw/mem/memory-device.h" -+#include "hw/acpi/utils.h" -+#include "hw/acpi/pci.h" -+/* Supported chipsets: */ -+#include "hw/acpi/aml-build.h" -+#include "hw/loongarch/larch.h" -+#include "hw/loongarch/ls7a.h" -+ -+#include "hw/acpi/ipmi.h" -+#include "hw/acpi/ls7a.h" -+ -+/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and -+ * -M pc-i440fx-2.0. Even if the actual amount of AML generated grows -+ * a little bit, there should be plenty of free space since the DSDT -+ * shrunk by ~1.5k between QEMU 2.0 and QEMU 2.1. -+ */ -+#define ACPI_BUILD_ALIGN_SIZE 0x1000 -+ -+#define ACPI_BUILD_TABLE_SIZE 0x20000 -+ -+/* #define DEBUG_ACPI_BUILD */ -+#ifdef DEBUG_ACPI_BUILD -+#define ACPI_BUILD_DPRINTF(fmt, ...) \ -+ do {printf("ACPI_BUILD: " fmt, ## __VA_ARGS__); } while (0) -+#else -+#define ACPI_BUILD_DPRINTF(fmt, ...) -+#endif -+ -+/* Default IOAPIC ID */ -+#define ACPI_BUILD_IOAPIC_ID 0x0 -+ -+/* PCI fw r3.0 MCFG table. */ -+/* Subtable */ -+ -+typedef struct AcpiMiscInfo { -+ bool is_piix4; -+ bool has_hpet; -+ TPMVersion tpm_version; -+ const unsigned char *dsdt_code; -+ unsigned dsdt_size; -+ uint16_t pvpanic_port; -+ uint16_t applesmc_io_base; -+} AcpiMiscInfo; -+ -+typedef struct AcpiBuildPciBusHotplugState { -+ GArray *device_table; -+ GArray *notify_table; -+ struct AcpiBuildPciBusHotplugState *parent; -+ bool pcihp_bridge_en; -+} AcpiBuildPciBusHotplugState; -+ -+static void init_common_fadt_data(AcpiFadtData *data) -+{ -+ AmlAddressSpace as = AML_AS_SYSTEM_MEMORY; -+ uint64_t base = LS7A_ACPI_REG_BASE; -+ AcpiFadtData fadt = { -+ .rev = 3, -+ .flags = -+ (1 << ACPI_FADT_F_WBINVD) | -+ (1 << ACPI_FADT_F_PROC_C1) | -+ (1 << ACPI_FADT_F_SLP_BUTTON) | -+ (1 << ACPI_FADT_F_TMR_VAL_EXT) | -+ (1 << ACPI_FADT_F_RESET_REG_SUP) , -+ .plvl2_lat = 0xfff /* C2 state not supported */, -+ .plvl3_lat = 0xfff /* C3 state not supported */, -+ .smi_cmd = 0x00, -+ .sci_int = ACPI_SCI_IRQ, -+ .acpi_enable_cmd = 0x00, -+ .acpi_disable_cmd = 0x00, -+ .pm1a_evt = { .space_id = as, .bit_width = 8 * 8, -+ .address = base + LS7A_PM_EVT_BLK }, -+ .pm1a_cnt = { .space_id = as, .bit_width = 4 * 8, -+ .address = base + LS7A_PM_CNT_BLK }, -+ .pm_tmr = { .space_id = as, .bit_width = 4 * 8, -+ .address = base + LS7A_PM_TMR_BLK }, -+ .gpe0_blk = { .space_id = as, .bit_width = 8 * 8, -+ .address = base + LS7A_GPE0_STS_REG}, -+ .reset_reg = { .space_id = as, .bit_width = 4 * 8, -+ .address = base + LS7A_GPE0_RESET_REG}, -+ .reset_val = 0x1, -+ }; -+ *data = fadt; -+} -+ -+static void acpi_align_size(GArray *blob, unsigned align) -+{ -+ /* Align size to multiple of given size. This reduces the chance -+ * we need to change size in the future (breaking cross version migration). -+ */ -+ g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align)); -+} -+ -+/* FACS */ -+static void -+build_facs(GArray *table_data) -+{ -+ const char *sig = "FACS"; -+ const uint8_t reserved[40] = {}; -+ -+ g_array_append_vals(table_data, sig, 4); /* Signature */ -+ build_append_int_noprefix(table_data, 64, 4); /* Length */ -+ build_append_int_noprefix(table_data, 0, 4); /* Hardware Signature */ -+ build_append_int_noprefix(table_data, 0, 4); /* Firmware Waking Vector */ -+ build_append_int_noprefix(table_data, 0, 4); /* Global Lock */ -+ build_append_int_noprefix(table_data, 0, 4); /* Flags */ -+ g_array_append_vals(table_data, reserved, 40); /* Reserved */ -+} -+ -+void ls7a_madt_cpu_entry(AcpiDeviceIf *adev, int uid, -+ const CPUArchIdList *apic_ids, GArray *entry, bool force_enabled) -+{ -+ uint32_t apic_id = apic_ids->cpus[uid].arch_id; -+ /* Flags – Local APIC Flags */ -+ uint32_t flags = apic_ids->cpus[uid].cpu != NULL || force_enabled ? -+ 1 /* Enabled */ : 0; -+ -+ /* Rev 1.0b, Table 5-13 Processor Local APIC Structure */ -+ build_append_int_noprefix(entry, 0, 1); /* Type */ -+ build_append_int_noprefix(entry, 8, 1); /* Length */ -+ build_append_int_noprefix(entry, uid, 1); /* ACPI Processor ID */ -+ build_append_int_noprefix(entry, apic_id, 1); /* APIC ID */ -+ build_append_int_noprefix(entry, flags, 4); /* Flags */ -+} -+static void build_ioapic(GArray *entry, uint8_t id, uint32_t addr, uint32_t irq) -+{ -+ /* Rev 1.0b, 5.2.8.2 IO APIC */ -+ build_append_int_noprefix(entry, 1, 1); /* Type */ -+ build_append_int_noprefix(entry, 12, 1); /* Length */ -+ build_append_int_noprefix(entry, id, 1); /* IO APIC ID */ -+ build_append_int_noprefix(entry, 0, 1); /* Reserved */ -+ build_append_int_noprefix(entry, addr, 4); /* IO APIC Address */ -+ build_append_int_noprefix(entry, irq, 4); /* System Vector Base */ -+} -+ -+static void -+build_madt(GArray *table_data, BIOSLinker *linker, LoongarchMachineState *lsms) -+{ -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ MachineClass *mc = MACHINE_GET_CLASS(lsms); -+ const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(lsms)); -+ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(lsms->acpi_dev); -+ AcpiDeviceIf *adev = ACPI_DEVICE_IF(lsms->acpi_dev); -+ int i; -+ AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lsms->oem_id, -+ .oem_table_id = lsms->oem_table_id}; -+ -+ acpi_table_begin(&table, table_data); -+ -+ /* Local APIC Address */ -+ build_append_int_noprefix(table_data, 0, 4); -+ build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */ -+ -+ -+ for (i = 0; i < apic_ids->len; i++) { -+ adevc->madt_cpu(adev, i, apic_ids, table_data, false); -+ } -+ -+ -+ build_ioapic(table_data, ACPI_BUILD_IOAPIC_ID, lsmc->ls7a_ioapic_reg_base, LOONGARCH_PCH_IRQ_BASE); -+ -+ /* Rev 1.0b, 5.2.8.3.3 Local APIC NMI */ -+ build_append_int_noprefix(table_data, 3, 1); /* Type */ -+ build_append_int_noprefix(table_data, 6, 1); /* Length */ -+ /* ACPI Processor ID */ -+ build_append_int_noprefix(table_data, 0xFF /* all processors */, 1); -+ build_append_int_noprefix(table_data, 0, 2); /* Flags */ -+ /* Local APIC INTI# */ -+ build_append_int_noprefix(table_data, 1 /* ACPI_LINT1 */, 1); -+ -+ /* Rev 1.0b, 5.2.8.3.3 Local APIC NMI */ -+ build_append_int_noprefix(table_data, 4, 1); /* Type */ -+ build_append_int_noprefix(table_data, 6, 1); /* Length */ -+ /* ACPI Processor ID */ -+ build_append_int_noprefix(table_data, 0xFF /* all processors */, 1); -+ build_append_int_noprefix(table_data, 0, 2); /* Flags */ -+ /* Local APIC INTI# */ -+ build_append_int_noprefix(table_data, 1 /* ACPI_LINT1 */, 1); -+ -+ -+ acpi_table_end(linker, &table); -+} -+ -+static void -+build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) -+{ -+ uint64_t i, mem_len, mem_base; -+ MachineClass *mc = MACHINE_GET_CLASS(machine); -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine); -+ int nb_numa_nodes = machine->numa_state->num_nodes; -+ NodeInfo *numa_info = machine->numa_state->nodes; -+ AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lsms->oem_id, -+ .oem_table_id = lsms->oem_table_id}; -+ -+ acpi_table_begin(&table, table_data); -+ build_append_int_noprefix(table_data, 1, 4); /* Reserved */ -+ build_append_int_noprefix(table_data, 0, 8); /* Reserved */ -+ -+ for (i = 0; i < apic_ids->len; ++i) { -+ /* 5.2.15.1 Processor Local APIC/SAPIC Affinity Structure */ -+ build_append_int_noprefix(table_data, 0, 1); /* Type */ -+ build_append_int_noprefix(table_data, 16, 1); /* Length */ -+ /* Proximity Domain [7:0] */ -+ build_append_int_noprefix(table_data, apic_ids->cpus[i].props.node_id, 1); -+ build_append_int_noprefix(table_data, apic_ids->cpus[i].arch_id, 1); /* APIC ID */ -+ /* Flags, Table 5-36 */ -+ build_append_int_noprefix(table_data, 1, 4); -+ build_append_int_noprefix(table_data, 0, 1); /* Local SAPIC EID */ -+ /* Proximity Domain [31:8] */ -+ build_append_int_noprefix(table_data, 0, 3); -+ build_append_int_noprefix(table_data, 0, 4); /* Reserved */ -+ } -+ -+ /* node0 */ -+ mem_base = (uint64_t)0; -+ mem_len = 0x10000000; -+ build_srat_memory(table_data, mem_base, mem_len, -+ 0, MEM_AFFINITY_ENABLED); -+ mem_base = 0x90000000; -+ if (!nb_numa_nodes) { -+ mem_len = machine->ram_size - 0x10000000; -+ } else { -+ mem_len = numa_info[0].node_mem - 0x10000000; -+ } -+ -+ build_srat_memory(table_data, mem_base, mem_len, -+ 0, MEM_AFFINITY_ENABLED); -+ mem_base += mem_len; -+ -+ /* node1 ~ nodemax */ -+ for (i = 1; i < nb_numa_nodes; ++i) { -+ mem_len = numa_info[i].node_mem; -+ build_srat_memory(table_data, mem_base, mem_len, -+ i, MEM_AFFINITY_ENABLED); -+ mem_base += mem_len; -+ } -+ -+ if (lsms->hotplug_memory_size) { -+ build_srat_memory(table_data, machine->device_memory->base, -+ lsms->hotplug_memory_size, 0, -+ MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); -+ } -+ -+ acpi_table_end(linker, &table); -+ -+} -+ -+typedef -+struct AcpiBuildState { -+ /* Copy of table in RAM (for patching). */ -+ MemoryRegion *table_mr; -+ /* Is table patched? */ -+ uint8_t patched; -+ void *rsdp; -+ MemoryRegion *rsdp_mr; -+ MemoryRegion *linker_mr; -+} AcpiBuildState; -+ -+static void build_ls7a_pci0_int(Aml *table) -+{ -+ Aml *sb_scope = aml_scope("_SB"); -+ Aml *pci0_scope = aml_scope("PCI0"); -+ Aml *prt_pkg = aml_varpackage(128); -+ int slot, pin; -+ -+ for (slot = 0; slot < PCI_SLOT_MAX; slot++) { -+ for (pin = 0; pin < PCI_NUM_PINS; pin++) { -+ Aml *pkg = aml_package(4); -+ aml_append(pkg, aml_int((slot << 16) | 0xFFFF)); -+ aml_append(pkg, aml_int(pin)); -+ aml_append(pkg, aml_int(0)); -+ aml_append(pkg, aml_int(LOONGARCH_PCH_IRQ_BASE + 16 + (slot * 4 + pin) % 16)); -+ aml_append(prt_pkg, pkg); -+ } -+ } -+ aml_append(pci0_scope, -+ aml_name_decl("_PRT", prt_pkg)); -+ -+ aml_append(sb_scope, pci0_scope); -+ -+ aml_append(table, sb_scope); -+} -+ -+static void build_dbg_aml(Aml *table) -+{ -+ Aml *field; -+ Aml *method; -+ Aml *while_ctx; -+ Aml *scope = aml_scope("\\"); -+ Aml *buf = aml_local(0); -+ Aml *len = aml_local(1); -+ Aml *idx = aml_local(2); -+ -+ aml_append(scope, -+ aml_operation_region("DBG", AML_SYSTEM_IO, aml_int(0x0402), 0x01)); -+ field = aml_field("DBG", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); -+ aml_append(field, aml_named_field("DBGB", 8)); -+ aml_append(scope, field); -+ -+ method = aml_method("DBUG", 1, AML_NOTSERIALIZED); -+ -+ aml_append(method, aml_to_hexstring(aml_arg(0), buf)); -+ aml_append(method, aml_to_buffer(buf, buf)); -+ aml_append(method, aml_subtract(aml_sizeof(buf), aml_int(1), len)); -+ aml_append(method, aml_store(aml_int(0), idx)); -+ -+ while_ctx = aml_while(aml_lless(idx, len)); -+ aml_append(while_ctx, -+ aml_store(aml_derefof(aml_index(buf, idx)), aml_name("DBGB"))); -+ aml_append(while_ctx, aml_increment(idx)); -+ aml_append(method, while_ctx); -+ -+ aml_append(method, aml_store(aml_int(0x0A), aml_name("DBGB"))); -+ aml_append(scope, method); -+ -+ aml_append(table, scope); -+} -+ -+static Aml *build_ls7a_osc_method(void) -+{ -+ Aml *if_ctx; -+ Aml *if_ctx2; -+ Aml *else_ctx; -+ Aml *method; -+ Aml *a_cwd1 = aml_name("CDW1"); -+ Aml *a_ctrl = aml_local(0); -+ -+ method = aml_method("_OSC", 4, AML_NOTSERIALIZED); -+ aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1")); -+ -+ if_ctx = aml_if(aml_equal( -+ aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766"))); -+ aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2")); -+ aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3")); -+ -+ aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl)); -+ -+ /* -+ * Always allow native PME, AER (no dependencies) -+ * Allow SHPC (PCI bridges can have SHPC controller) -+ */ -+ aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl)); -+ -+ if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1)))); -+ /* Unknown revision */ -+ aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1)); -+ aml_append(if_ctx, if_ctx2); -+ -+ if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl))); -+ /* Capabilities bits were masked */ -+ aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1)); -+ aml_append(if_ctx, if_ctx2); -+ -+ /* Update DWORD3 in the buffer */ -+ aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3"))); -+ aml_append(method, if_ctx); -+ -+ else_ctx = aml_else(); -+ /* Unrecognized UUID */ -+ aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1)); -+ aml_append(method, else_ctx); -+ -+ aml_append(method, aml_return(aml_arg(3))); -+ return method; -+} -+ -+static void build_ls7a_rtc_device_aml(Aml *table) -+{ -+ Aml *dev; -+ Aml *crs; -+ uint32_t rtc_irq = LS7A_RTC_IRQ; -+ -+ Aml *scope = aml_scope("_SB"); -+ dev = aml_device("RTC"); -+ aml_append(dev, aml_name_decl("_HID", aml_string("LOON0001"))); -+ crs = aml_resource_template(); -+ aml_append(crs, -+ aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, -+ AML_NON_CACHEABLE, AML_READ_WRITE, -+ 0, LS7A_RTC_REG_BASE, -+ LS7A_RTC_REG_BASE + LS7A_RTC_LEN - 1, 0, LS7A_RTC_LEN)); -+ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, -+ AML_EXCLUSIVE, &rtc_irq, 1)); -+ -+ aml_append(dev, aml_name_decl("_CRS", crs)); -+ aml_append(scope, dev); -+ aml_append(table, scope); -+} -+ -+static void build_ls7a_uart_device_aml(Aml *table) -+{ -+ Aml *dev; -+ Aml *crs; -+ Aml *pkg0, *pkg1, *pkg2; -+ uint32_t uart_irq = LS7A_UART_IRQ; -+ -+ Aml *scope = aml_scope("_SB"); -+ dev = aml_device("COMA"); -+ aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501"))); -+ aml_append(dev, aml_name_decl("_UID", aml_int(0))); -+ aml_append(dev, aml_name_decl("_CCA", aml_int(1))); -+ crs = aml_resource_template(); -+ aml_append(crs, -+ aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, -+ AML_NON_CACHEABLE, AML_READ_WRITE, -+ 0, LS7A_UART_BASE, LS7A_UART_BASE + LS7A_UART_LEN - 1, 0, 0x8)); -+ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, -+ AML_EXCLUSIVE, &uart_irq, 1)); -+ aml_append(dev, aml_name_decl("_CRS", crs)); -+ pkg0 = aml_package(0x2); -+ aml_append(pkg0, aml_int(0x01F78A40)); -+ aml_append(pkg0, aml_string("clock-frenquency")); -+ pkg1 = aml_package(0x1); -+ aml_append(pkg1, pkg0); -+ pkg2 = aml_package(0x2); -+ aml_append(pkg2, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301")); -+ aml_append(pkg2, pkg1); -+ -+ aml_append(dev, aml_name_decl("_DSD", pkg2)); -+ -+ aml_append(scope, dev); -+ aml_append(table, scope); -+} -+ -+static void -+build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) -+{ -+ Aml *dsdt, *sb_scope, *scope, *dev, *crs, *pkg; -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ uint32_t nr_mem = machine->ram_slots; -+ uint64_t base = LS7A_ACPI_REG_BASE; -+ int root_bus_limit = PCIE_MMCFG_BUS(LS_PCIECFG_SIZE - 1); -+ AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lsms->oem_id, -+ .oem_table_id = lsms->oem_table_id}; -+ -+ acpi_table_begin(&table, table_data); -+ dsdt = init_aml_allocator(); -+ -+ build_dbg_aml(dsdt); -+ -+ sb_scope = aml_scope("_SB"); -+ dev = aml_device("PCI0"); -+ aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); -+ aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); -+ aml_append(dev, aml_name_decl("_ADR", aml_int(0))); -+ aml_append(dev, aml_name_decl("_BBN", aml_int(0))); -+ aml_append(dev, aml_name_decl("_UID", aml_int(1))); -+ aml_append(dev, build_ls7a_osc_method()); -+ aml_append(sb_scope, dev); -+ aml_append(dsdt, sb_scope); -+ -+ build_ls7a_pci0_int(dsdt); -+ build_ls7a_rtc_device_aml(dsdt); -+ build_ls7a_uart_device_aml(dsdt); -+ -+ if (lsms->acpi_dev) { -+ CPUHotplugFeatures opts = { -+ .acpi_1_compatible = true, .has_legacy_cphp = false -+ }; -+ build_cpus_aml(dsdt, machine, opts, CPU_HOTPLUG_BASE, -+ "\\_SB.PCI0", "\\_GPE._E02"); -+ -+ build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0", -+ "\\_GPE._E03", AML_SYSTEM_MEMORY, -+ MEMORY_HOTPLUG_BASE); -+ } -+ -+ scope = aml_scope("_GPE"); -+ { -+ aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006"))); -+ } -+ aml_append(dsdt, scope); -+ -+ scope = aml_scope("\\_SB.PCI0"); -+ /* build PCI0._CRS */ -+ crs = aml_resource_template(); -+ aml_append(crs, -+ aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE, -+ 0x0000, 0x0, root_bus_limit, -+ 0x0000, root_bus_limit + 1)); -+ aml_append(crs, -+ aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED, -+ AML_POS_DECODE, AML_ENTIRE_RANGE, -+ 0x0000, 0x4000, 0xFFFF, 0x0000, 0xC000)); -+ aml_append(crs, -+ aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, -+ AML_CACHEABLE, AML_READ_WRITE, -+ 0, 0x40000000, 0x7FFFFFFF, 0, 0x40000000)); -+ aml_append(scope, aml_name_decl("_CRS", crs)); -+ -+ /* reserve GPE0 block resources */ -+ dev = aml_device("GPE0"); -+ aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06"))); -+ aml_append(dev, aml_name_decl("_UID", aml_string("GPE0 resources"))); -+ /* device present, functioning, decoding, not shown in UI */ -+ aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); -+ crs = aml_resource_template(); -+ aml_append(crs, -+ aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, -+ AML_CACHEABLE, AML_READ_WRITE, -+ 0, base + LS7A_GPE0_STS_REG, -+ base + LS7A_GPE0_STS_REG + 0x3, 0, 0x4)); -+ aml_append(dev, aml_name_decl("_CRS", crs)); -+ aml_append(scope, dev); -+ aml_append(dsdt, scope); -+ -+ scope = aml_scope("\\"); -+ pkg = aml_package(4); -+ aml_append(pkg, aml_int(7)); /* PM1a_CNT.SLP_TYP */ -+ aml_append(pkg, aml_int(7)); /* PM1b_CNT.SLP_TYP not impl. */ -+ aml_append(pkg, aml_int(0)); /* reserved */ -+ aml_append(pkg, aml_int(0)); /* reserved */ -+ aml_append(scope, aml_name_decl("_S5", pkg)); -+ aml_append(dsdt, scope); -+ -+ /* copy AML table into ACPI tables blob and patch header there */ -+ g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len); -+ acpi_table_end(linker, &table); -+ free_aml_allocator(); -+} -+ -+ -+static -+void acpi_build(AcpiBuildTables *tables, MachineState *machine) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ GArray *table_offsets; -+ AcpiFadtData fadt_data; -+ unsigned facs, rsdt, fadt, dsdt; -+ uint8_t *u; -+ size_t aml_len = 0; -+ GArray *tables_blob = tables->table_data; -+ -+ init_common_fadt_data(&fadt_data); -+ -+ table_offsets = g_array_new(false, true /* clear */, -+ sizeof(uint32_t)); -+ ACPI_BUILD_DPRINTF("init ACPI tables\n"); -+ -+ bios_linker_loader_alloc(tables->linker, -+ ACPI_BUILD_TABLE_FILE, tables_blob, -+ 64 /* Ensure FACS is aligned */, -+ false /* high memory */); -+ -+ /* -+ * FACS is pointed to by FADT. -+ * We place it first since it's the only table that has alignment -+ * requirements. -+ */ -+ facs = tables_blob->len; -+ build_facs(tables_blob); -+ -+ /* DSDT is pointed to by FADT */ -+ dsdt = tables_blob->len; -+ build_dsdt(tables_blob, tables->linker, MACHINE(qdev_get_machine())); -+ -+ /* Count the size of the DSDT and SSDT, we will need it for legacy -+ * sizing of ACPI tables. -+ */ -+ aml_len += tables_blob->len - dsdt; -+ -+ /* ACPI tables pointed to by RSDT */ -+ fadt = tables_blob->len; -+ acpi_add_table(table_offsets, tables_blob); -+ fadt_data.facs_tbl_offset = &facs; -+ fadt_data.dsdt_tbl_offset = &dsdt; -+ fadt_data.xdsdt_tbl_offset = &dsdt; -+ build_fadt(tables_blob, tables->linker, &fadt_data, -+ "LOONGS", "TP-R00"); -+ aml_len += tables_blob->len - fadt; -+ -+ acpi_add_table(table_offsets, tables_blob); -+ build_madt(tables_blob, tables->linker, lsms); -+ -+ acpi_add_table(table_offsets, tables_blob); -+ build_srat(tables_blob, tables->linker, machine); -+ if (machine->numa_state->have_numa_distance) { -+ acpi_add_table(table_offsets, tables_blob); -+ build_slit(tables_blob, tables->linker, machine, lsms->oem_id, -+ lsms->oem_table_id); -+ } -+ -+ /* Build mcfg */ -+ acpi_add_table(table_offsets, tables_blob); -+ { -+ AcpiMcfgInfo mcfg = { -+ .base = LS_PCIECFG_BASE, -+ .size = LS_PCIECFG_SIZE, -+ }; -+ build_mcfg(tables_blob, tables->linker, &mcfg, lsms->oem_id, -+ lsms->oem_table_id); -+ } -+ -+ /* Add tables supplied by user (if any) */ -+ for (u = acpi_table_first(); u; u = acpi_table_next(u)) { -+ unsigned len = acpi_table_len(u); -+ -+ acpi_add_table(table_offsets, tables_blob); -+ g_array_append_vals(tables_blob, u, len); -+ } -+ -+ /* RSDT is pointed to by RSDP */ -+ rsdt = tables_blob->len; -+ build_rsdt(tables_blob, tables->linker, table_offsets, -+ "LOONGS", "TP-R00"); -+ -+ /* RSDP is in FSEG memory, so allocate it separately */ -+ { -+ AcpiRsdpData rsdp_data = { -+ .revision = 0, -+ .oem_id = lsms->oem_id, -+ .xsdt_tbl_offset = NULL, -+ .rsdt_tbl_offset = &rsdt, -+ }; -+ build_rsdp(tables->rsdp, tables->linker, &rsdp_data); -+ } -+ acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE); -+ -+ /* Cleanup memory that's no longer used. */ -+ g_array_free(table_offsets, true); -+} -+ -+static void acpi_ram_update(MemoryRegion *mr, GArray *data) -+{ -+ uint32_t size = acpi_data_len(data); -+ -+ /* Make sure RAM size is correct - -+ in case it got changed e.g. by migration */ -+ memory_region_ram_resize(mr, size, &error_abort); -+ -+ memcpy(memory_region_get_ram_ptr(mr), data->data, size); -+ memory_region_set_dirty(mr, 0, size); -+} -+ -+static void acpi_build_update(void *build_opaque) -+{ -+ AcpiBuildState *build_state = build_opaque; -+ AcpiBuildTables tables; -+ -+ /* No state to update or already patched? Nothing to do. */ -+ if (!build_state || build_state->patched) { -+ return; -+ } -+ build_state->patched = 1; -+ -+ acpi_build_tables_init(&tables); -+ -+ acpi_build(&tables, MACHINE(qdev_get_machine())); -+ -+ acpi_ram_update(build_state->table_mr, tables.table_data); -+ -+ if (build_state->rsdp) { -+ memcpy(build_state->rsdp, tables.rsdp->data, -+ acpi_data_len(tables.rsdp)); -+ } else { -+ acpi_ram_update(build_state->rsdp_mr, tables.rsdp); -+ } -+ -+ acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob); -+ acpi_build_tables_cleanup(&tables, true); -+} -+ -+static void acpi_build_reset(void *build_opaque) -+{ -+ AcpiBuildState *build_state = build_opaque; -+ build_state->patched = 0; -+} -+ -+static const VMStateDescription vmstate_acpi_build = { -+ .name = "acpi_build", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT8(patched, AcpiBuildState), -+ VMSTATE_END_OF_LIST() -+ }, -+}; -+ -+void loongarch_acpi_setup(void) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); -+ AcpiBuildTables tables; -+ AcpiBuildState *build_state; -+ -+ if (!lsms->fw_cfg) { -+ ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n"); -+ return; -+ } -+ -+ if (!lsms->acpi_build_enabled) { -+ ACPI_BUILD_DPRINTF("ACPI build disabled. Bailing out.\n"); -+ return; -+ } -+ -+ if (!loongarch_is_acpi_enabled(lsms)) { -+ ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n"); -+ return; -+ } -+ -+ build_state = g_malloc0(sizeof *build_state); -+ -+ acpi_build_tables_init(&tables); -+ acpi_build(&tables, MACHINE(lsms)); -+ -+ /* Now expose it all to Guest */ -+ build_state->table_mr = acpi_add_rom_blob(acpi_build_update, build_state, -+ tables.table_data, -+ ACPI_BUILD_TABLE_FILE); -+ assert(build_state->table_mr != NULL); -+ -+ build_state->linker_mr = -+ acpi_add_rom_blob(acpi_build_update, build_state, tables.linker->cmd_blob, -+ "etc/table-loader"); -+ -+ fw_cfg_add_file(lsms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, -+ tables.tcpalog->data, acpi_data_len(tables.tcpalog)); -+ -+ build_state->rsdp = NULL; -+ build_state->rsdp_mr = acpi_add_rom_blob(acpi_build_update, build_state, tables.rsdp, -+ ACPI_BUILD_RSDP_FILE); -+ -+ qemu_register_reset(acpi_build_reset, build_state); -+ acpi_build_reset(build_state); -+ vmstate_register(NULL, 0, &vmstate_acpi_build, build_state); -+ -+ /* Cleanup tables but don't free the memory: we track it -+ * in build_state. -+ */ -+ acpi_build_tables_cleanup(&tables, false); -+} -diff --git a/hw/loongarch/acpi-build.h b/hw/loongarch/acpi-build.h -new file mode 100644 -index 000000000..a914268bb ---- /dev/null -+++ b/hw/loongarch/acpi-build.h -@@ -0,0 +1,16 @@ -+ -+#ifndef HW_LARCH_ACPI_BUILD_H -+#define HW_LARCH_ACPI_BUILD_H -+ -+#define EFI_ACPI_OEM_ID "LARCH" -+#define EFI_ACPI_OEM_TABLE_ID "LARCH" /* OEM table id 8 bytes long */ -+#define EFI_ACPI_OEM_REVISION 0x00000002 -+#define EFI_ACPI_CREATOR_ID "LINUX" -+#define EFI_ACPI_CREATOR_REVISION 0x01000013 -+ -+#define ACPI_COMPATIBLE_1_0 0 -+#define ACPI_COMPATIBLE_2_0 1 -+ -+void loongarch_acpi_setup(void); -+ -+#endif -diff --git a/hw/loongarch/apic.c b/hw/loongarch/apic.c -new file mode 100644 -index 000000000..d6ba2a2ce ---- /dev/null -+++ b/hw/loongarch/apic.c -@@ -0,0 +1,675 @@ -+/* -+ * Loongarch 3A5000 interrupt controller emulation -+ * -+ * Copyright (C) 2020 Lu Zeng -+ * -+ * 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/boards.h" -+#include "hw/irq.h" -+#include "hw/loongarch/cpudevs.h" -+#include "hw/sysbus.h" -+#include "qemu/host-utils.h" -+#include "qemu/error-report.h" -+#include "sysemu/kvm.h" -+#include "hw/hw.h" -+#include "hw/irq.h" -+#include "target/loongarch64/cpu.h" -+#include "exec/address-spaces.h" -+#include "hw/loongarch/larch.h" -+#include "migration/vmstate.h" -+ -+#define DEBUG_APIC 0 -+ -+#define DPRINTF(fmt, ...) \ -+do { \ -+ if (DEBUG_APIC) { \ -+ fprintf(stderr, "APIC: " fmt , ## __VA_ARGS__); \ -+ } \ -+} while (0) -+ -+#define APIC_OFFSET 0x400 -+#define APIC_BASE (0x1f010000ULL) -+#define EXTIOI_NODETYPE_START (0x4a0 - APIC_OFFSET) -+#define EXTIOI_NODETYPE_END (0x4c0 - APIC_OFFSET) -+#define EXTIOI_IPMAP_START (0x4c0 - APIC_OFFSET) -+#define EXTIOI_IPMAP_END (0x4c8 - APIC_OFFSET) -+#define EXTIOI_ENABLE_START (0x600 - APIC_OFFSET) -+#define EXTIOI_ENABLE_END (0x620 - APIC_OFFSET) -+#define EXTIOI_BOUNCE_START (0x680 - APIC_OFFSET) -+#define EXTIOI_BOUNCE_END (0x6a0 - APIC_OFFSET) -+#define EXTIOI_ISR_START (0x700 - APIC_OFFSET) -+#define EXTIOI_ISR_END (0x720 - APIC_OFFSET) -+#define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET) -+#define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET) -+#define EXTIOI_COREISR_START (0x10000) -+#define EXTIOI_COREISR_END (EXTIOI_COREISR_START + 0x10000) -+ -+static int ext_irq_pre_save(void *opaque) -+{ -+#ifdef CONFIG_KVM -+ apicState *apic = opaque; -+ struct loongarch_kvm_irqchip *chip; -+ struct kvm_loongarch_ls3a_extirq_state *kstate; -+ int ret, length, i, vcpuid; -+#endif -+ if (!kvm_irqchip_in_kernel()) { -+ return 0; -+ } -+#ifdef CONFIG_KVM -+ length = sizeof(struct loongarch_kvm_irqchip) + -+ sizeof(struct kvm_loongarch_ls3a_extirq_state); -+ chip = g_malloc0(length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS3A_EXTIRQ; -+ chip->len = length; -+ -+ ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); -+ if (ret < 0) { -+ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); -+ abort(); -+ } -+ -+ kstate = (struct kvm_loongarch_ls3a_extirq_state *)chip->data; -+ for (i = 0; i < EXTIOI_IRQS_BITMAP_SIZE; i++) { -+ apic->ext_en[i] = kstate->ext_en_r.reg_u8[i]; -+ apic->ext_bounce[i] = kstate->bounce_r.reg_u8[i]; -+ apic->ext_isr[i] = kstate->ext_isr_r.reg_u8[i]; -+ for (vcpuid = 0; vcpuid < MAX_CORES; vcpuid++) { -+ apic->ext_coreisr[vcpuid][i] = kstate->ext_core_isr_r.reg_u8[vcpuid][i]; -+ } -+ } -+ for (i = 0; i < EXTIOI_IRQS_IPMAP_SIZE; i++) { -+ apic->ext_ipmap[i] = kstate->ip_map_r.reg_u8[i]; -+ } -+ for (i = 0; i < EXTIOI_IRQS; i++) { -+ apic->ext_coremap[i] = kstate->core_map_r.reg_u8[i];; -+ } -+ for (i = 0; i < 16; i++) { -+ apic->ext_nodetype[i] = kstate->node_type_r.reg_u16[i]; -+ } -+ g_free(chip); -+#endif -+ return 0; -+} -+ -+static int ext_irq_post_load(void *opaque, int version) -+{ -+#ifdef CONFIG_KVM -+ apicState *apic = opaque; -+ struct loongarch_kvm_irqchip *chip; -+ struct kvm_loongarch_ls3a_extirq_state *kstate; -+ int ret, length, i, vcpuid; -+#endif -+ if (!kvm_irqchip_in_kernel()) { -+ return 0; -+ } -+#ifdef CONFIG_KVM -+ length = sizeof(struct loongarch_kvm_irqchip) + -+ sizeof(struct kvm_loongarch_ls3a_extirq_state); -+ chip = g_malloc0(length); -+ -+ chip->chip_id = KVM_IRQCHIP_LS3A_EXTIRQ; -+ chip->len = length; -+ -+ kstate = (struct kvm_loongarch_ls3a_extirq_state *)chip->data; -+ for (i = 0; i < EXTIOI_IRQS_BITMAP_SIZE; i++) { -+ kstate->ext_en_r.reg_u8[i] = apic->ext_en[i]; -+ kstate->bounce_r.reg_u8[i] = apic->ext_bounce[i]; -+ kstate->ext_isr_r.reg_u8[i] = apic->ext_isr[i]; -+ for (vcpuid = 0; vcpuid < MAX_CORES; vcpuid++) { -+ kstate->ext_core_isr_r.reg_u8[vcpuid][i] = apic->ext_coreisr[vcpuid][i]; -+ } -+ } -+ for (i = 0; i < EXTIOI_IRQS_IPMAP_SIZE; i++) { -+ kstate->ip_map_r.reg_u8[i] = apic->ext_ipmap[i]; -+ } -+ for (i = 0; i < EXTIOI_IRQS; i++) { -+ kstate->core_map_r.reg_u8[i] = apic->ext_coremap[i]; -+ } -+ for (i = 0; i < 16; i++) { -+ kstate->node_type_r.reg_u16[i] = apic->ext_nodetype[i]; -+ } -+ -+ ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); -+ if (ret < 0) { -+ fprintf(stderr, "KVM_SET_IRQCHIP failed: %s\n", strerror(ret)); -+ abort(); -+ } -+ g_free(chip); -+#endif -+ return 0; -+} -+typedef struct nodeApicState { -+ unsigned long addr; -+ int nodeid; -+ apicState *apic; -+} nodeApicState; -+ -+static void ioapic_update_irq(void *opaque, int irq, int level) -+{ -+ apicState *s = opaque; -+ uint8_t ipnum, cpu, cpu_ipnum; -+ unsigned long found1, found2; -+ uint8_t reg_count, reg_bit; -+ -+ reg_count = irq / 32; -+ reg_bit = irq % 32; -+ -+ ipnum = s->ext_sw_ipmap[irq]; -+ cpu = s->ext_sw_coremap[irq]; -+ cpu_ipnum = cpu * LS3A_INTC_IP + ipnum; -+ if (level == 1) { -+ if (test_bit(reg_bit, ((void *)s->ext_en + 0x4 * reg_count)) == false) { -+ return; -+ } -+ -+ if (test_bit(reg_bit, ((void *)s->ext_isr + 0x4 * reg_count)) == false) { -+ return; -+ } -+ bitmap_set(((void *)s->ext_coreisr[cpu] + 0x4 * reg_count), reg_bit, 1); -+ found1 = find_next_bit(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), -+ EXTIOI_IRQS, 0); -+ bitmap_set(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), reg_bit, 1); -+ if (found1 >= EXTIOI_IRQS) { -+ qemu_set_irq(s->parent_irq[cpu][ipnum], level); -+ } -+ } else { -+ bitmap_clear(((void *)s->ext_isr + 0x4 * reg_count), reg_bit, 1); -+ bitmap_clear(((void *)s->ext_coreisr[cpu] + 0x4 * reg_count), reg_bit, 1); -+ found1 = find_next_bit(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), -+ EXTIOI_IRQS, 0); -+ found1 += reg_count * 32; -+ bitmap_clear(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), reg_bit, 1); -+ found2 = find_next_bit(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), -+ EXTIOI_IRQS, 0); -+ if ((found1 < EXTIOI_IRQS) && (found2 >= EXTIOI_IRQS)) { -+ qemu_set_irq(s->parent_irq[cpu][ipnum], level); -+ } -+ } -+} -+ -+static void ioapic_setirq(void *opaque, int irq, int level) -+{ -+ apicState *s = opaque; -+ uint8_t reg_count, reg_bit; -+ -+ reg_count = irq / 32; -+ reg_bit = irq % 32; -+ -+ if (level) { -+ bitmap_set(((void *)s->ext_isr + 0x4 * reg_count), reg_bit, 1); -+ } else { -+ bitmap_clear(((void *)s->ext_isr + 0x4 * reg_count), reg_bit, 1); -+ } -+ -+ ioapic_update_irq(s, irq, level); -+} -+ -+static uint32_t apic_readb(void *opaque, hwaddr addr) -+{ -+ nodeApicState *node; -+ apicState *state; -+ unsigned long off; -+ uint8_t ret; -+ int cpu; -+ -+ node = (nodeApicState *)opaque; -+ state = node->apic; -+ off = addr & 0xfffff; -+ ret = 0; -+ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { -+ off -= EXTIOI_ENABLE_START; -+ ret = *(uint8_t *)((void *)state->ext_en + off); -+ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { -+ off -= EXTIOI_BOUNCE_START; -+ ret = *(uint8_t *)((void *)state->ext_bounce + off); -+ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { -+ off -= EXTIOI_ISR_START; -+ ret = *(uint8_t *)((void *)state->ext_isr + off); -+ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { -+ off -= EXTIOI_COREISR_START; -+ cpu = (off >> 8) & 0xff; -+ ret = *(uint8_t *)((void *)state->ext_coreisr[cpu] + (off & 0x1f)); -+ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { -+ off -= EXTIOI_IPMAP_START; -+ ret = *(uint8_t *)((void *)state->ext_ipmap + off); -+ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { -+ off -= EXTIOI_COREMAP_START; -+ ret = *(uint8_t *)((void *)state->ext_coremap + off); -+ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { -+ off -= EXTIOI_NODETYPE_START; -+ ret = *(uint8_t *)((void *)state->ext_nodetype + off); -+ } -+ -+ DPRINTF("readb reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, ret); -+ return ret; -+} -+ -+static uint32_t apic_readw(void *opaque, hwaddr addr) -+{ -+ nodeApicState *node; -+ apicState *state; -+ unsigned long off; -+ uint16_t ret; -+ int cpu; -+ -+ node = (nodeApicState *)opaque; -+ state = node->apic; -+ off = addr & 0xfffff; -+ ret = 0; -+ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { -+ off -= EXTIOI_ENABLE_START; -+ ret = *(uint16_t *)((void *)state->ext_en + off); -+ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { -+ off -= EXTIOI_BOUNCE_START; -+ ret = *(uint16_t *)((void *)state->ext_bounce + off); -+ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { -+ off -= EXTIOI_ISR_START; -+ ret = *(uint16_t *)((void *)state->ext_isr + off); -+ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { -+ off -= EXTIOI_COREISR_START; -+ cpu = (off >> 8) & 0xff; -+ ret = *(uint16_t *)((void *)state->ext_coreisr[cpu] + (off & 0x1f)); -+ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { -+ off -= EXTIOI_IPMAP_START; -+ ret = *(uint16_t *)((void *)state->ext_ipmap + off); -+ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { -+ off -= EXTIOI_COREMAP_START; -+ ret = *(uint16_t *)((void *)state->ext_coremap + off); -+ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { -+ off -= EXTIOI_NODETYPE_START; -+ ret = *(uint16_t *)((void *)state->ext_nodetype + off); -+ } -+ -+ DPRINTF("readw reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, ret); -+ return ret; -+} -+ -+static uint32_t apic_readl(void *opaque, hwaddr addr) -+{ -+ nodeApicState *node; -+ apicState *state; -+ unsigned long off; -+ uint32_t ret; -+ int cpu; -+ -+ node = (nodeApicState *)opaque; -+ state = node->apic; -+ off = addr & 0xfffff; -+ ret = 0; -+ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { -+ off -= EXTIOI_ENABLE_START; -+ ret = *(uint32_t *)((void *)state->ext_en + off); -+ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { -+ off -= EXTIOI_BOUNCE_START; -+ ret = *(uint32_t *)((void *)state->ext_bounce + off); -+ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { -+ off -= EXTIOI_ISR_START; -+ ret = *(uint32_t *)((void *)state->ext_isr + off); -+ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { -+ off -= EXTIOI_COREISR_START; -+ cpu = (off >> 8) & 0xff; -+ ret = *(uint32_t *)((void *)state->ext_coreisr[cpu] + (off & 0x1f)); -+ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { -+ off -= EXTIOI_IPMAP_START; -+ ret = *(uint32_t *)((void *)state->ext_ipmap + off); -+ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { -+ off -= EXTIOI_COREMAP_START; -+ ret = *(uint32_t *)((void *)state->ext_coremap + off); -+ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { -+ off -= EXTIOI_NODETYPE_START; -+ ret = *(uint32_t *)((void *)state->ext_nodetype + off); -+ } -+ -+ DPRINTF("readl reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, ret); -+ return ret; -+ -+} -+ -+static void apic_writeb(void *opaque, hwaddr addr, uint32_t val) -+{ -+ nodeApicState *node; -+ apicState *state; -+ unsigned long off; -+ uint8_t old; -+ int cpu, i, ipnum, level, mask; -+ -+ node = (nodeApicState *)opaque; -+ state = node->apic; -+ off = addr & 0xfffff; -+ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { -+ off -= EXTIOI_ENABLE_START; -+ old = *(uint8_t *)((void *)state->ext_en + off); -+ if (old != val) { -+ *(uint8_t *)((void *)state->ext_en + off) = val; -+ old = old ^ val; -+ mask = 0x1; -+ for (i = 0; i < 8; i++) { -+ if (old & mask) { -+ level = !!(val & (0x1 << i)); -+ ioapic_update_irq(state, i + off * 8, level); -+ } -+ mask = mask << 1; -+ } -+ } -+ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { -+ off -= EXTIOI_BOUNCE_START; -+ *(uint8_t *)((void *)state->ext_bounce + off) = val; -+ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { -+ off -= EXTIOI_ISR_START; -+ old = *(uint8_t *)((void *)state->ext_isr + off); -+ *(uint8_t *)((void *)state->ext_isr + off) = old & ~val; -+ mask = 0x1; -+ for (i = 0; i < 8; i++) { -+ if ((old & mask) && (val & mask)) { -+ ioapic_update_irq(state, i + off * 8, 0); -+ } -+ mask = mask << 1; -+ } -+ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { -+ off -= EXTIOI_COREISR_START; -+ cpu = (off >> 8) & 0xff; -+ off = off & 0x1f; -+ old = *(uint8_t *)((void *)state->ext_coreisr[cpu] + off); -+ *(uint8_t *)((void *)state->ext_coreisr[cpu] + off) = old & ~val; -+ mask = 0x1; -+ for (i = 0; i < 8; i++) { -+ if ((old & mask) && (val & mask)) { -+ ioapic_update_irq(state, i + off * 8, 0); -+ } -+ mask = mask << 1; -+ } -+ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { -+ off -= EXTIOI_IPMAP_START; -+ val = val & 0xf; -+ *(uint8_t *)((void *)state->ext_ipmap + off) = val; -+ ipnum = 0; -+ for (i = 0; i < 4; i++) { -+ if (val & (0x1 << i)) { -+ ipnum = i; -+ break; -+ } -+ } -+ if (val) { -+ for (i = 0; i < 32; i++) { -+ cpu = off * 32 + i; -+ state->ext_sw_ipmap[cpu] = ipnum; -+ } -+ } -+ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { -+ off -= EXTIOI_COREMAP_START; -+ val = val & 0xff; -+ *(uint8_t *)((void *)state->ext_coremap + off) = val; -+ state->ext_sw_coremap[off] = val; -+ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { -+ off -= EXTIOI_NODETYPE_START; -+ *(uint8_t *)((void *)state->ext_nodetype + off) = val; -+ } -+ -+ DPRINTF("writeb reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, val); -+} -+ -+static void apic_writew(void *opaque, hwaddr addr, uint32_t val) -+{ -+ nodeApicState *node; -+ apicState *state; -+ unsigned long off; -+ uint16_t old; -+ int cpu, i, level, mask; -+ -+ node = (nodeApicState *)opaque; -+ state = node->apic; -+ off = addr & 0xfffff; -+ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { -+ off -= EXTIOI_ENABLE_START; -+ old = *(uint16_t *)((void *)state->ext_en + off); -+ if (old != val) { -+ *(uint16_t *)((void *)state->ext_en + off) = val; -+ old = old ^ val; -+ mask = 0x1; -+ for (i = 0; i < 16; i++) { -+ if (old & mask) { -+ level = !!(val & (0x1 << i)); -+ ioapic_update_irq(state, i + off * 8, level); -+ } -+ mask = mask << 1; -+ } -+ } -+ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { -+ off -= EXTIOI_BOUNCE_START; -+ *(uint16_t *)((void *)state->ext_bounce + off) = val; -+ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { -+ off -= EXTIOI_ISR_START; -+ old = *(uint16_t *)((void *)state->ext_isr + off); -+ *(uint16_t *)((void *)state->ext_isr + off) = old & ~val; -+ mask = 0x1; -+ for (i = 0; i < 16; i++) { -+ if ((old & mask) && (val & mask)) { -+ ioapic_update_irq(state, i + off * 8, 0); -+ } -+ mask = mask << 1; -+ } -+ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { -+ off -= EXTIOI_COREISR_START; -+ cpu = (off >> 8) & 0xff; -+ off = off & 0x1f; -+ old = *(uint16_t *)((void *)state->ext_coreisr[cpu] + off); -+ *(uint16_t *)((void *)state->ext_coreisr[cpu] + off) = old & ~val; -+ mask = 0x1; -+ for (i = 0; i < 16; i++) { -+ if ((old & mask) && (val & mask)) { -+ ioapic_update_irq(state, i + off * 8, 0); -+ } -+ mask = mask << 1; -+ } -+ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { -+ apic_writeb(opaque, addr, val & 0xff); -+ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); -+ -+ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { -+ apic_writeb(opaque, addr, val & 0xff); -+ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); -+ -+ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { -+ off -= EXTIOI_NODETYPE_START; -+ *(uint16_t *)((void *)state->ext_nodetype + off) = val; -+ } -+ -+ DPRINTF("writew reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, val); -+} -+ -+static void apic_writel(void *opaque, hwaddr addr, uint32_t val) -+{ -+ nodeApicState *node; -+ apicState *state; -+ unsigned long off; -+ uint32_t old; -+ int cpu, i, level, mask; -+ -+ node = (nodeApicState *)opaque; -+ state = node->apic; -+ off = addr & 0xfffff; -+ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { -+ off -= EXTIOI_ENABLE_START; -+ old = *(uint32_t *)((void *)state->ext_en + off); -+ if (old != val) { -+ *(uint32_t *)((void *)state->ext_en + off) = val; -+ old = old ^ val; -+ mask = 0x1; -+ for (i = 0; i < 32; i++) { -+ if (old & mask) { -+ level = !!(val & (0x1 << i)); -+ ioapic_update_irq(state, i + off * 8, level); -+ } -+ mask = mask << 1; -+ } -+ } -+ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { -+ off -= EXTIOI_BOUNCE_START; -+ *(uint32_t *)((void *)state->ext_bounce + off) = val; -+ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { -+ off -= EXTIOI_ISR_START; -+ old = *(uint32_t *)((void *)state->ext_isr + off); -+ *(uint32_t *)((void *)state->ext_isr + off) = old & ~val; -+ mask = 0x1; -+ for (i = 0; i < 32; i++) { -+ if ((old & mask) && (val & mask)) { -+ ioapic_update_irq(state, i + off * 8, 0); -+ } -+ mask = mask << 1; -+ } -+ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { -+ off -= EXTIOI_COREISR_START; -+ cpu = (off >> 8) & 0xff; -+ off = off & 0x1f; -+ old = *(uint32_t *)((void *)state->ext_coreisr[cpu] + off); -+ *(uint32_t *)((void *)state->ext_coreisr[cpu] + off) = old & ~val; -+ mask = 0x1; -+ for (i = 0; i < 32; i++) { -+ if ((old & mask) && (val & mask)) { -+ ioapic_update_irq(state, i + off * 8, 0); -+ } -+ mask = mask << 1; -+ } -+ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { -+ apic_writeb(opaque, addr, val & 0xff); -+ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); -+ apic_writeb(opaque, addr + 2, (val >> 16) & 0xff); -+ apic_writeb(opaque, addr + 3, (val >> 24) & 0xff); -+ -+ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { -+ apic_writeb(opaque, addr, val & 0xff); -+ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); -+ apic_writeb(opaque, addr + 2, (val >> 16) & 0xff); -+ apic_writeb(opaque, addr + 3, (val >> 24) & 0xff); -+ -+ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { -+ off -= EXTIOI_NODETYPE_START; -+ *(uint32_t *)((void *)state->ext_nodetype + off) = val; -+ } -+ -+ DPRINTF("writel reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, val); -+} -+ -+static uint64_t apic_readfn(void *opaque, hwaddr addr, -+ unsigned size) -+{ -+ switch (size) { -+ case 1: -+ return apic_readb(opaque, addr); -+ case 2: -+ return apic_readw(opaque, addr); -+ case 4: -+ return apic_readl(opaque, addr); -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static void apic_writefn(void *opaque, hwaddr addr, -+ uint64_t value, unsigned size) -+{ -+ switch (size) { -+ case 1: -+ apic_writeb(opaque, addr, value); -+ break; -+ case 2: -+ apic_writew(opaque, addr, value); -+ break; -+ case 4: -+ apic_writel(opaque, addr, value); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static const VMStateDescription vmstate_apic = { -+ .name = "apic", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .pre_save = ext_irq_pre_save, -+ .post_load = ext_irq_post_load, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT8_ARRAY(ext_en, apicState, EXTIOI_IRQS_BITMAP_SIZE), -+ VMSTATE_UINT8_ARRAY(ext_bounce, apicState, EXTIOI_IRQS_BITMAP_SIZE), -+ VMSTATE_UINT8_ARRAY(ext_isr, apicState, EXTIOI_IRQS_BITMAP_SIZE), -+ VMSTATE_UINT8_2DARRAY(ext_coreisr, apicState, MAX_CORES, -+ EXTIOI_IRQS_BITMAP_SIZE), -+ VMSTATE_UINT8_ARRAY(ext_ipmap, apicState, EXTIOI_IRQS_IPMAP_SIZE), -+ VMSTATE_UINT8_ARRAY(ext_coremap, apicState, EXTIOI_IRQS), -+ VMSTATE_UINT16_ARRAY(ext_nodetype, apicState, 16), -+ VMSTATE_UINT64(ext_control, apicState), -+ VMSTATE_UINT8_ARRAY(ext_sw_ipmap, apicState, EXTIOI_IRQS), -+ VMSTATE_UINT8_ARRAY(ext_sw_coremap, apicState, EXTIOI_IRQS), -+ VMSTATE_UINT8_2DARRAY(ext_ipisr, apicState, MAX_CORES * LS3A_INTC_IP, -+ EXTIOI_IRQS_BITMAP_SIZE), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+static const MemoryRegionOps apic_ops = { -+ .read = apic_readfn, -+ .write = apic_writefn, -+ .impl.min_access_size = 1, -+ .impl.max_access_size = 4, -+ .valid.min_access_size = 1, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+}; -+ -+int cpu_init_apic(LoongarchMachineState *ms, CPULOONGARCHState *env, int cpu) -+{ -+ apicState *apic; -+ nodeApicState *node; -+ MemoryRegion *iomem; -+ unsigned long base; -+ int pin; -+ char str[32]; -+ -+ if (ms->apic == NULL) { -+ apic = g_malloc0(sizeof(apicState)); -+ vmstate_register(NULL, 0, &vmstate_apic, apic); -+ apic->irq = qemu_allocate_irqs(ioapic_setirq, apic, EXTIOI_IRQS); -+ -+ for (pin = 0; pin < LS3A_INTC_IP; pin++) { -+ /* cpu_pin[9:2] <= intc_pin[7:0] */ -+ apic->parent_irq[cpu][pin] = env->irq[pin + 2]; -+ } -+ ms->apic = apic; -+ -+ if (cpu == 0) { -+ base = APIC_BASE; -+ node = g_malloc0(sizeof(nodeApicState)); -+ node->apic = ms->apic; -+ node->addr = base; -+ -+ iomem = g_new(MemoryRegion, 1); -+ sprintf(str, "apic%d", cpu); -+ /* extioi addr 0x1f010000~0x1f02ffff */ -+ memory_region_init_io(iomem, NULL, &apic_ops, node, str, 0x20000); -+ memory_region_add_subregion(get_system_memory(), base, iomem); -+ } -+ -+ } else { -+ if (cpu != 0) { -+ for (pin = 0; pin < LS3A_INTC_IP; pin++) { -+ ms->apic->parent_irq[cpu][pin] = env->irq[pin + 2]; -+ } -+ } -+ } -+ return 0; -+} -+ -diff --git a/hw/loongarch/ioapic.c b/hw/loongarch/ioapic.c -new file mode 100644 -index 000000000..3de0ed88d ---- /dev/null -+++ b/hw/loongarch/ioapic.c -@@ -0,0 +1,422 @@ -+/* -+ * LS7A1000 Northbridge IOAPIC support -+ * -+ * Copyright (c) 2019 Loongarch Technology -+ * Authors: -+ * Zhu Chen -+ * -+ * 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 "hw/sysbus.h" -+#include "hw/irq.h" -+#include "qemu/log.h" -+#include "sysemu/kvm.h" -+#include "linux/kvm.h" -+#include "migration/vmstate.h" -+ -+#define DEBUG_LS7A_APIC 0 -+ -+#define DPRINTF(fmt, ...) \ -+do { \ -+ if (DEBUG_LS7A_APIC) { \ -+ fprintf(stderr, "IOAPIC: " fmt , ## __VA_ARGS__); \ -+ } \ -+} while (0) -+ -+#define TYPE_LS7A_APIC "ioapic" -+#define LS7A_APIC(obj) OBJECT_CHECK(LS7AApicState, (obj), TYPE_LS7A_APIC) -+ -+#define LS7A_IOAPIC_ROUTE_ENTRY_OFFSET 0x100 -+#define LS7A_IOAPIC_INT_ID_OFFSET 0x00 -+#define LS7A_INT_ID_VAL 0x7000000UL -+#define LS7A_INT_ID_VER 0x1f0001UL -+#define LS7A_IOAPIC_INT_MASK_OFFSET 0x20 -+#define LS7A_IOAPIC_INT_EDGE_OFFSET 0x60 -+#define LS7A_IOAPIC_INT_CLEAR_OFFSET 0x80 -+#define LS7A_IOAPIC_INT_STATUS_OFFSET 0x3a0 -+#define LS7A_IOAPIC_INT_POL_OFFSET 0x3e0 -+#define LS7A_IOAPIC_HTMSI_EN_OFFSET 0x40 -+#define LS7A_IOAPIC_HTMSI_VEC_OFFSET 0x200 -+#define LS7A_AUTO_CTRL0_OFFSET 0xc0 -+#define LS7A_AUTO_CTRL1_OFFSET 0xe0 -+ -+typedef struct LS7AApicState { -+ SysBusDevice parent_obj; -+ qemu_irq parent_irq[257]; -+ uint64_t int_id; -+ uint64_t int_mask; /*0x020 interrupt mask register*/ -+ uint64_t htmsi_en;/*0x040 1=msi*/ -+ uint64_t intedge; /*0x060 edge=1 level =0*/ -+ uint64_t intclr; /*0x080 for clean edge int,set 1 clean,set 0 is noused*/ -+ uint64_t auto_crtl0; /*0x0c0*/ -+ uint64_t auto_crtl1; /*0x0e0*/ -+ uint8_t route_entry[64]; /*0x100 - 0x140*/ -+ uint8_t htmsi_vector[64]; /*0x200 - 0x240*/ -+ uint64_t intisr_chip0; /*0x300*/ -+ uint64_t intisr_chip1;/*0x320*/ -+ uint64_t last_intirr; /* edge detection */ -+ uint64_t intirr; /* 0x380 interrupt request register */ -+ uint64_t intisr; /* 0x3a0 interrupt service register */ -+ uint64_t int_polarity; /*0x3e0 interrupt level polarity -+ selection register 0 for high level tirgger*/ -+ MemoryRegion iomem; -+} LS7AApicState; -+ -+static void update_irq(LS7AApicState *s) -+{ -+ int i; -+ if ((s->intirr & (~s->int_mask)) & (~s->htmsi_en)) { -+ DPRINTF("7a update irqline up\n"); -+ s->intisr = (s->intirr & (~s->int_mask) & (~s->htmsi_en)); -+ qemu_set_irq(s->parent_irq[256], 1); -+ } else { -+ DPRINTF("7a update irqline down\n"); -+ s->intisr &= (~s->htmsi_en); -+ qemu_set_irq(s->parent_irq[256], 0); -+ } -+ if (s->htmsi_en) { -+ for (i = 0; i < 64; i++) { -+ if ((((~s->intisr) & s->intirr) & s->htmsi_en) & (1ULL << i)) { -+ s->intisr |= 1ULL << i; -+ qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], 1); -+ } else if (((~(s->intisr | s->intirr)) & s->htmsi_en) & -+ (1ULL << i)) { -+ qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], 0); -+ } -+ } -+ } -+} -+ -+static void irq_handler(void *opaque, int irq, int level) -+{ -+ LS7AApicState *s = opaque; -+ -+ assert(irq < 64); -+ uint64_t mask = 1ULL << irq; -+ DPRINTF("------ %s irq %d %d\n", __func__, irq, level); -+ -+ if (s->intedge & mask) { -+ /* edge triggered */ -+ /*TODO*/ -+ } else { -+ /* level triggered */ -+ if (level) { -+ s->intirr |= mask; -+ } else { -+ s->intirr &= ~mask; -+ } -+ -+ } -+ update_irq(s); -+ -+} -+ -+static uint64_t ls7a_apic_reg_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ LS7AApicState *a = opaque; -+ uint64_t val = 0; -+ uint64_t offset; -+ int64_t offset_tmp; -+ offset = addr & 0xfff; -+ if (8 == size) { -+ switch (offset) { -+ case LS7A_IOAPIC_INT_ID_OFFSET: -+ val = LS7A_INT_ID_VER; -+ val = (val << 32) + LS7A_INT_ID_VAL; -+ break; -+ case LS7A_IOAPIC_INT_MASK_OFFSET: -+ val = a->int_mask; -+ break; -+ case LS7A_IOAPIC_INT_STATUS_OFFSET: -+ val = a->intisr & (~a->int_mask); -+ break; -+ case LS7A_IOAPIC_INT_EDGE_OFFSET: -+ val = a->intedge; -+ break; -+ case LS7A_IOAPIC_INT_POL_OFFSET: -+ val = a->int_polarity; -+ break; -+ case LS7A_IOAPIC_HTMSI_EN_OFFSET: -+ val = a->htmsi_en; -+ break; -+ case LS7A_AUTO_CTRL0_OFFSET: -+ case LS7A_AUTO_CTRL1_OFFSET: -+ break; -+ default: -+ break; -+ } -+ } else if (1 == size) { -+ if (offset >= LS7A_IOAPIC_HTMSI_VEC_OFFSET) { -+ offset_tmp = offset - LS7A_IOAPIC_HTMSI_VEC_OFFSET; -+ if (offset_tmp >= 0 && offset_tmp < 64) { -+ val = a->htmsi_vector[offset_tmp]; -+ } -+ } else if (offset >= LS7A_IOAPIC_ROUTE_ENTRY_OFFSET) { -+ offset_tmp = offset - LS7A_IOAPIC_ROUTE_ENTRY_OFFSET; -+ if (offset_tmp >= 0 && offset_tmp < 64) { -+ val = a->route_entry[offset_tmp]; -+ DPRINTF("addr %lx val %lx\n", addr, val); -+ } -+ } -+ } -+ DPRINTF(TARGET_FMT_plx" val %lx\n", addr, val); -+ return val; -+} -+ -+static void ls7a_apic_reg_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) -+{ -+ LS7AApicState *a = opaque; -+ int64_t offset_tmp; -+ uint64_t offset; -+ offset = addr & 0xfff; -+ DPRINTF(TARGET_FMT_plx" size %d val %lx\n", addr, size, data); -+ if (8 == size) { -+ switch (offset) { -+ case LS7A_IOAPIC_INT_MASK_OFFSET: -+ a->int_mask = data; -+ update_irq(a); -+ break; -+ case LS7A_IOAPIC_INT_STATUS_OFFSET: -+ a->intisr = data; -+ break; -+ case LS7A_IOAPIC_INT_EDGE_OFFSET: -+ a->intedge = data; -+ break; -+ case LS7A_IOAPIC_INT_CLEAR_OFFSET: -+ a->intisr &= (~data); -+ update_irq(a); -+ break; -+ case LS7A_IOAPIC_INT_POL_OFFSET: -+ a->int_polarity = data; -+ break; -+ case LS7A_IOAPIC_HTMSI_EN_OFFSET: -+ a->htmsi_en = data; -+ break; -+ case LS7A_AUTO_CTRL0_OFFSET: -+ case LS7A_AUTO_CTRL1_OFFSET: -+ break; -+ default: -+ break; -+ } -+ } else if (1 == size) { -+ if (offset >= LS7A_IOAPIC_HTMSI_VEC_OFFSET) { -+ offset_tmp = offset - LS7A_IOAPIC_HTMSI_VEC_OFFSET; -+ if (offset_tmp >= 0 && offset_tmp < 64) { -+ a->htmsi_vector[offset_tmp] = (uint8_t)(data & 0xff); -+ } -+ } else if (offset >= LS7A_IOAPIC_ROUTE_ENTRY_OFFSET) { -+ offset_tmp = offset - LS7A_IOAPIC_ROUTE_ENTRY_OFFSET; -+ if (offset_tmp >= 0 && offset_tmp < 64) { -+ a->route_entry[offset_tmp] = (uint8_t)(data & 0xff); -+ } -+ } -+ } -+} -+ -+static const MemoryRegionOps ls7a_apic_ops = { -+ .read = ls7a_apic_reg_read, -+ .write = ls7a_apic_reg_write, -+ .valid = { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+ .impl = { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+}; -+ -+static int kvm_ls7a_pre_save(void *opaque) -+{ -+#ifdef CONFIG_KVM -+ LS7AApicState *s = opaque; -+ struct loongarch_kvm_irqchip *chip; -+ struct ls7a_ioapic_state *state; -+ int ret, i, length; -+ -+ if (!kvm_irqchip_in_kernel()) { -+ return 0; -+ } -+ -+ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct ls7a_ioapic_state); -+ chip = g_malloc0(length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS7A_IOAPIC; -+ chip->len = length; -+ ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); -+ if (ret < 0) { -+ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); -+ abort(); -+ } -+ state = (struct ls7a_ioapic_state *)chip->data; -+ s->int_id = state->int_id; -+ s->int_mask = state->int_mask; -+ s->htmsi_en = state->htmsi_en; -+ s->intedge = state->intedge; -+ s->intclr = state->intclr; -+ s->auto_crtl0 = state->auto_crtl0; -+ s->auto_crtl1 = state->auto_crtl1; -+ for (i = 0; i < 64; i++) { -+ s->route_entry[i] = state->route_entry[i]; -+ s->htmsi_vector[i] = state->htmsi_vector[i]; -+ } -+ s->intisr_chip0 = state->intisr_chip0; -+ s->intisr_chip1 = state->intisr_chip1; -+ s->intirr = state->intirr; -+ s->intisr = state->intisr; -+ s->int_polarity = state->int_polarity; -+ g_free(chip); -+#endif -+ return 0; -+} -+ -+static int kvm_ls7a_post_load(void *opaque, int version) -+{ -+#ifdef CONFIG_KVM -+ LS7AApicState *s = opaque; -+ struct loongarch_kvm_irqchip *chip; -+ struct ls7a_ioapic_state *state; -+ int ret, i, length; -+ -+ if (!kvm_irqchip_in_kernel()) { -+ return 0; -+ } -+ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct ls7a_ioapic_state); -+ chip = g_malloc0(length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS7A_IOAPIC; -+ chip->len = length; -+ -+ state = (struct ls7a_ioapic_state *)chip->data; -+ state->int_id = s->int_id; -+ state->int_mask = s->int_mask; -+ state->htmsi_en = s->htmsi_en; -+ state->intedge = s->intedge; -+ state->intclr = s->intclr; -+ state->auto_crtl0 = s->auto_crtl0; -+ state->auto_crtl1 = s->auto_crtl1; -+ for (i = 0; i < 64; i++) { -+ state->route_entry[i] = s->route_entry[i]; -+ state->htmsi_vector[i] = s->htmsi_vector[i]; -+ } -+ state->intisr_chip0 = s->intisr_chip0; -+ state->intisr_chip1 = s->intisr_chip1; -+ state->last_intirr = 0; -+ state->intirr = s->intirr; -+ state->intisr = s->intisr; -+ state->int_polarity = s->int_polarity; -+ -+ ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); -+ if (ret < 0) { -+ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); -+ abort(); -+ } -+ g_free(chip); -+#endif -+ return 0; -+} -+ -+static void ls7a_apic_reset(DeviceState *d) -+{ -+ LS7AApicState *s = LS7A_APIC(d); -+ int i; -+ -+ s->int_id = 0x001f000107000000; -+ s->int_mask = 0xffffffffffffffff; -+ s->htmsi_en = 0x0; -+ s->intedge = 0x0; -+ s->intclr = 0x0; -+ s->auto_crtl0 = 0x0; -+ s->auto_crtl1 = 0x0; -+ for (i = 0; i < 64; i++) { -+ s->route_entry[i] = 0x1; -+ s->htmsi_vector[i] = 0x0; -+ } -+ s->intisr_chip0 = 0x0; -+ s->intisr_chip1 = 0x0; -+ s->intirr = 0x0; -+ s->intisr = 0x0; -+ s->int_polarity = 0x0; -+ kvm_ls7a_post_load(s, 0); -+} -+ -+static void ls7a_apic_init(Object *obj) -+{ -+ DeviceState *dev = DEVICE(obj); -+ LS7AApicState *s = LS7A_APIC(obj); -+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj); -+ int tmp; -+ memory_region_init_io(&s->iomem, obj, &ls7a_apic_ops, s, TYPE_LS7A_APIC, 0x1000); -+ sysbus_init_mmio(sbd, &s->iomem); -+ for (tmp = 0; tmp < 257; tmp++) { -+ sysbus_init_irq(sbd, &s->parent_irq[tmp]); -+ } -+ qdev_init_gpio_in(dev, irq_handler, 64); -+} -+ -+static const VMStateDescription vmstate_ls7a_apic = { -+ .name = TYPE_LS7A_APIC, -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .pre_save = kvm_ls7a_pre_save, -+ .post_load = kvm_ls7a_post_load, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT64(int_mask, LS7AApicState), -+ VMSTATE_UINT64(htmsi_en, LS7AApicState), -+ VMSTATE_UINT64(intedge, LS7AApicState), -+ VMSTATE_UINT64(intclr, LS7AApicState), -+ VMSTATE_UINT64(auto_crtl0, LS7AApicState), -+ VMSTATE_UINT64(auto_crtl1, LS7AApicState), -+ VMSTATE_UINT8_ARRAY(route_entry, LS7AApicState, 64), -+ VMSTATE_UINT8_ARRAY(htmsi_vector, LS7AApicState, 64), -+ VMSTATE_UINT64(intisr_chip0, LS7AApicState), -+ VMSTATE_UINT64(intisr_chip1, LS7AApicState), -+ VMSTATE_UINT64(last_intirr, LS7AApicState), -+ VMSTATE_UINT64(intirr, LS7AApicState), -+ VMSTATE_UINT64(intisr, LS7AApicState), -+ VMSTATE_UINT64(int_polarity, LS7AApicState), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+static void ls7a_apic_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ -+ dc->reset = ls7a_apic_reset; -+ dc->vmsd = &vmstate_ls7a_apic; -+} -+ -+static const TypeInfo ls7a_apic_info = { -+ .name = TYPE_LS7A_APIC, -+ .parent = TYPE_SYS_BUS_DEVICE, -+ .instance_size = sizeof(LS7AApicState), -+ .instance_init = ls7a_apic_init, -+ .class_init = ls7a_apic_class_init, -+}; -+ -+static void ls7a_apic_register_types(void) -+{ -+ type_register_static(&ls7a_apic_info); -+} -+ -+type_init(ls7a_apic_register_types) -diff --git a/hw/loongarch/iocsr.c b/hw/loongarch/iocsr.c -new file mode 100644 -index 000000000..14521c2d5 ---- /dev/null -+++ b/hw/loongarch/iocsr.c -@@ -0,0 +1,219 @@ -+/* -+ * LOONGARCH IOCSR support -+ * -+ * Copyright (c) 2021 Loongarch Technology -+ * -+ * 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 "hw/sysbus.h" -+#include "qemu/log.h" -+#include "sysemu/kvm.h" -+#include "linux/kvm.h" -+#include "migration/vmstate.h" -+#include "hw/boards.h" -+#include "hw/loongarch/larch.h" -+ -+#define BIT_ULL(nr) (1ULL << (nr)) -+#define LOONGARCH_IOCSR_FEATURES 0x8 -+#define IOCSRF_TEMP BIT_ULL(0) -+#define IOCSRF_NODECNT BIT_ULL(1) -+#define IOCSRF_MSI BIT_ULL(2) -+#define IOCSRF_EXTIOI BIT_ULL(3) -+#define IOCSRF_CSRIPI BIT_ULL(4) -+#define IOCSRF_FREQCSR BIT_ULL(5) -+#define IOCSRF_FREQSCALE BIT_ULL(6) -+#define IOCSRF_DVFSV1 BIT_ULL(7) -+#define IOCSRF_GMOD BIT_ULL(9) -+#define IOCSRF_VM BIT_ULL(11) -+#define LOONGARCH_IOCSR_VENDOR 0x10 -+#define LOONGARCH_IOCSR_CPUNAME 0x20 -+#define LOONGARCH_IOCSR_NODECNT 0x408 -+#define LOONGARCH_IOCSR_MISC_FUNC 0x420 -+#define IOCSR_MISC_FUNC_TIMER_RESET BIT_ULL(21) -+#define IOCSR_MISC_FUNC_EXT_IOI_EN BIT_ULL(48) -+ -+enum { -+ IOCSR_FEATURES, -+ IOCSR_VENDOR, -+ IOCSR_CPUNAME, -+ IOCSR_NODECNT, -+ IOCSR_MISC_FUNC, -+ IOCSR_MAX -+}; -+ -+static uint32_t iocsr_array[IOCSR_MAX] = { -+ [IOCSR_FEATURES] = LOONGARCH_IOCSR_FEATURES, -+ [IOCSR_VENDOR] = LOONGARCH_IOCSR_VENDOR, -+ [IOCSR_CPUNAME] = LOONGARCH_IOCSR_CPUNAME, -+ [IOCSR_NODECNT] = LOONGARCH_IOCSR_NODECNT, -+ [IOCSR_MISC_FUNC] = LOONGARCH_IOCSR_MISC_FUNC, -+}; -+ -+ -+#define TYPE_IOCSR "iocsr" -+#define IOCSR(obj) OBJECT_CHECK(IOCSRState, (obj), TYPE_IOCSR) -+ -+typedef struct IOCSRState { -+ SysBusDevice parent_obj; -+ uint64_t iocsr_val[IOCSR_MAX]; -+} IOCSRState; -+ -+IOCSRState iocsr_init = { -+ .iocsr_val = { -+ IOCSRF_NODECNT | IOCSRF_MSI | IOCSRF_EXTIOI -+ | IOCSRF_CSRIPI | IOCSRF_GMOD | IOCSRF_VM, -+ 0x6e6f73676e6f6f4c, /* Loongson */ -+ 0x303030354133, /*3A5000*/ -+ 0x4, -+ 0x0, -+ } -+}; -+ -+static int kvm_iocsr_pre_save(void *opaque) -+{ -+#ifdef CONFIG_KVM -+ IOCSRState *s = opaque; -+ struct kvm_iocsr_entry entry; -+ int i = 0; -+ for (i = 0; i < IOCSR_MAX; i++) { -+ entry.addr = iocsr_array[i]; -+ kvm_vm_ioctl(kvm_state, KVM_LOONGARCH_GET_IOCSR, &entry); -+ s->iocsr_val[i] = entry.data; -+ } -+#endif -+ return 0; -+} -+ -+static int kvm_iocsr_post_load(void *opaque, int version) -+{ -+#ifdef CONFIG_KVM -+ IOCSRState *s = opaque; -+ struct kvm_iocsr_entry entry; -+ int i = 0; -+ -+ if (!kvm_enabled()) { -+ return 0; -+ } -+ -+ for (i = 0; i < IOCSR_MAX; i++) { -+ entry.addr = iocsr_array[i]; -+ entry.data = s->iocsr_val[i]; -+ kvm_vm_ioctl(kvm_state, KVM_LOONGARCH_SET_IOCSR, &entry); -+ } -+#endif -+ return 0; -+} -+ -+static void iocsr_reset(DeviceState *d) -+{ -+ IOCSRState *s = IOCSR(d); -+ int i; -+ -+ for (i = 0; i < IOCSR_MAX; i++) { -+ s->iocsr_val[i] = iocsr_init.iocsr_val[i]; -+ } -+ kvm_iocsr_post_load(s, 0); -+} -+static void init_vendor_cpuname(uint64_t *vendor, -+ uint64_t *cpu_name, char *cpuname) -+{ -+ int i = 0, len = 0; -+ char *index = NULL, *index_end = NULL; -+ char *vendor_c = (char *)vendor; -+ char *cpu_name_c = (char *)cpu_name; -+ -+ index = strstr(cpuname, "-"); -+ len = strlen(cpuname); -+ if ((index == NULL) || (len <= 0)) { -+ return ; -+ } -+ -+ *vendor = 0; -+ *cpu_name = 0; -+ index_end = cpuname + len; -+ -+ while (((cpuname + i) < index) && (i < sizeof(uint64_t))) { -+ vendor_c[i] = cpuname[i]; -+ i++; -+ } -+ -+ index += 1; -+ i = 0; -+ -+ while (((index + i) < index_end) && (i < sizeof(uint64_t))) { -+ cpu_name_c[i] = index[i]; -+ i++; -+ } -+ -+ return ; -+} -+ -+static void iocsr_instance_init(Object *obj) -+{ -+ IOCSRState *s = IOCSR(obj); -+ int i; -+ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ -+ init_vendor_cpuname((uint64_t *)&iocsr_init.iocsr_val[IOCSR_VENDOR], -+ (uint64_t *)&iocsr_init.iocsr_val[IOCSR_CPUNAME], -+ lsmc->cpu_name); -+ -+ for (i = 0; i < IOCSR_MAX; i++) { -+ s->iocsr_val[i] = iocsr_init.iocsr_val[i]; -+ } -+} -+ -+static const VMStateDescription vmstate_iocsr = { -+ .name = TYPE_IOCSR, -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .pre_save = kvm_iocsr_pre_save, -+ .post_load = kvm_iocsr_post_load, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT64_ARRAY(iocsr_val, IOCSRState, IOCSR_MAX), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+static void iocsr_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ -+ dc->reset = iocsr_reset; -+ dc->vmsd = &vmstate_iocsr; -+ -+} -+ -+static const TypeInfo iocsr_info = { -+ .name = TYPE_IOCSR, -+ .parent = TYPE_SYS_BUS_DEVICE, -+ .instance_size = sizeof(IOCSRState), -+ .instance_init = iocsr_instance_init, -+ .class_init = iocsr_class_init, -+}; -+ -+static void iocsr_register_types(void) -+{ -+ type_register_static(&iocsr_info); -+} -+ -+type_init(iocsr_register_types) -diff --git a/hw/loongarch/ipi.c b/hw/loongarch/ipi.c -new file mode 100644 -index 000000000..ade182abc ---- /dev/null -+++ b/hw/loongarch/ipi.c -@@ -0,0 +1,267 @@ -+#include "qemu/osdep.h" -+#include "qemu/units.h" -+#include "qapi/error.h" -+#include "hw/hw.h" -+#include "hw/irq.h" -+#include "hw/loongarch/cpudevs.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/cpus.h" -+#include "sysemu/kvm.h" -+#include "hw/core/cpu.h" -+#include "qemu/log.h" -+#include "hw/loongarch/bios.h" -+#include "elf.h" -+#include "linux/kvm.h" -+#include "hw/loongarch/larch.h" -+#include "hw/loongarch/ls7a.h" -+#include "migration/vmstate.h" -+ -+static int gipi_pre_save(void *opaque) -+{ -+#ifdef CONFIG_KVM -+ gipiState *state = opaque; -+ struct loongarch_gipiState *kstate; -+ struct loongarch_kvm_irqchip *chip; -+ int ret, i, j, length; -+#endif -+ -+ if (!kvm_irqchip_in_kernel()) { -+ return 0; -+ } -+ -+#ifdef CONFIG_KVM -+ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct loongarch_gipiState); -+ chip = g_malloc0(length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS3A_GIPI; -+ chip->len = length; -+ ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); -+ if (ret < 0) { -+ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); -+ abort(); -+ } -+ -+ kstate = (struct loongarch_gipiState *)chip->data; -+ -+ for (i = 0; i < MAX_GIPI_CORE_NUM; i++) { -+ state->core[i].status = kstate->core[i].status; -+ state->core[i].en = kstate->core[i].en; -+ state->core[i].set = kstate->core[i].set; -+ state->core[i].clear = kstate->core[i].clear; -+ for (j = 0; j < MAX_GIPI_MBX_NUM; j++) { -+ state->core[i].buf[j] = kstate->core[i].buf[j]; -+ } -+ } -+ g_free(chip); -+#endif -+ -+ return 0; -+} -+ -+static int gipi_post_load(void *opaque, int version) -+{ -+#ifdef CONFIG_KVM -+ gipiState *state = opaque; -+ struct loongarch_gipiState *kstate; -+ struct loongarch_kvm_irqchip *chip; -+ int ret, i, j, length; -+#endif -+ -+ if (!kvm_irqchip_in_kernel()) { -+ return 0; -+ } -+ -+#ifdef CONFIG_KVM -+ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct loongarch_gipiState); -+ chip = g_malloc0(length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS3A_GIPI; -+ chip->len = length; -+ kstate = (struct loongarch_gipiState *)chip->data; -+ -+ for (i = 0; i < MAX_GIPI_CORE_NUM; i++) { -+ kstate->core[i].status = state->core[i].status; -+ kstate->core[i].en = state->core[i].en; -+ kstate->core[i].set = state->core[i].set; -+ kstate->core[i].clear = state->core[i].clear; -+ for (j = 0; j < MAX_GIPI_MBX_NUM; j++) { -+ kstate->core[i].buf[j] = state->core[i].buf[j]; -+ } -+ } -+ -+ ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); -+ if (ret < 0) { -+ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); -+ abort(); -+ } -+ g_free(chip); -+#endif -+ -+ return 0; -+} -+ -+static const VMStateDescription vmstate_gipi_core = { -+ .name = "gipi-single", -+ .version_id = 0, -+ .minimum_version_id = 0, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT32(status, gipi_core), -+ VMSTATE_UINT32(en, gipi_core), -+ VMSTATE_UINT32(set, gipi_core), -+ VMSTATE_UINT32(clear, gipi_core), -+ VMSTATE_UINT64_ARRAY(buf, gipi_core, MAX_GIPI_MBX_NUM), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+static const VMStateDescription vmstate_gipi = { -+ .name = "gipi", -+ .pre_save = gipi_pre_save, -+ .post_load = gipi_post_load, -+ .version_id = 0, -+ .minimum_version_id = 0, -+ .fields = (VMStateField[]) { -+ VMSTATE_STRUCT_ARRAY(core, gipiState, MAX_GIPI_CORE_NUM, 0, -+ vmstate_gipi_core, gipi_core), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+ -+static void gipi_writel(void *opaque, hwaddr addr, uint64_t val, unsigned size) -+{ -+ gipi_core *s = opaque; -+ gipi_core *ss; -+ void *pbuf; -+ uint32_t cpu, action_data, mailaddr; -+ LoongarchMachineState *ms = LoongarchMACHINE(qdev_get_machine()); -+ -+ if ((size != 4) && (size != 8)) { -+ hw_error("size not 4 and not 8"); -+ } -+ addr &= 0xff; -+ switch (addr) { -+ case CORE0_STATUS_OFF: -+ hw_error("CORE0_STATUS_OFF Can't be write\n"); -+ break; -+ case CORE0_EN_OFF: -+ s->en = val; -+ break; -+ case CORE0_IPI_SEND: -+ cpu = (val >> 16) & 0x3ff; -+ action_data = 1UL << (val & 0x1f); -+ ss = &ms->gipi->core[cpu]; -+ ss->status |= action_data; -+ if (ss->status != 0) { -+ qemu_irq_raise(ss->irq); -+ } -+ break; -+ case CORE0_MAIL_SEND: -+ cpu = (val >> 16) & 0x3ff; -+ mailaddr = (val >> 2) & 0x7; -+ ss = &ms->gipi->core[cpu]; -+ pbuf = (void *)ss->buf + mailaddr * 4; -+ *(unsigned int *)pbuf = (val >> 32); -+ break; -+ case CORE0_SET_OFF: -+ hw_error("CORE0_SET_OFF Can't be write\n"); -+ break; -+ case CORE0_CLEAR_OFF: -+ s->status ^= val; -+ if (s->status == 0) { -+ qemu_irq_lower(s->irq); -+ } -+ break; -+ case 0x20 ... 0x3c: -+ pbuf = (void *)s->buf + (addr - 0x20); -+ if (size == 1) { -+ *(unsigned char *)pbuf = (unsigned char)val; -+ } else if (size == 2) { -+ *(unsigned short *)pbuf = (unsigned short)val; -+ } else if (size == 4) { -+ *(unsigned int *)pbuf = (unsigned int)val; -+ } else if (size == 8) { -+ *(unsigned long *)pbuf = (unsigned long)val; -+ } -+ break; -+ default: -+ break; -+ } -+} -+ -+static uint64_t gipi_readl(void *opaque, hwaddr addr, unsigned size) -+{ -+ gipi_core *s = opaque; -+ uint64_t ret = 0; -+ void *pbuf; -+ -+ addr &= 0xff; -+ if ((size != 4) && (size != 8)) { -+ hw_error("size not 4 and not 8 size:%d\n", size); -+ } -+ switch (addr) { -+ case CORE0_STATUS_OFF: -+ ret = s->status; -+ break; -+ case CORE0_EN_OFF: -+ ret = s->en; -+ break; -+ case CORE0_SET_OFF: -+ ret = 0; -+ break; -+ case CORE0_CLEAR_OFF: -+ ret = 0; -+ break; -+ case 0x20 ... 0x3c: -+ pbuf = (void *)s->buf + (addr - 0x20); -+ if (size == 1) { -+ ret = *(unsigned char *)pbuf; -+ } else if (size == 2) { -+ ret = *(unsigned short *)pbuf; -+ } else if (size == 4) { -+ ret = *(unsigned int *)pbuf; -+ } else if (size == 8) { -+ ret = *(unsigned long *)pbuf; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ return ret; -+} -+ -+static const MemoryRegionOps gipi_ops = { -+ .read = gipi_readl, -+ .write = gipi_writel, -+ .valid = { -+ .min_access_size = 4, -+ .max_access_size = 8, -+ }, -+ .impl = { -+ .min_access_size = 4, -+ .max_access_size = 8, -+ }, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+}; -+ -+int cpu_init_ipi(LoongarchMachineState *ms, qemu_irq parent, int cpu) -+{ -+ hwaddr addr; -+ MemoryRegion *region; -+ char str[32]; -+ -+ if (ms->gipi == NULL) { -+ ms->gipi = g_malloc0(sizeof(gipiState)); -+ vmstate_register(NULL, 0, &vmstate_gipi, ms->gipi); -+ } -+ -+ ms->gipi->core[cpu].irq = parent; -+ -+ addr = SMP_GIPI_MAILBOX | (cpu << 8); -+ region = g_new(MemoryRegion, 1); -+ sprintf(str, "gipi%d", cpu); -+ memory_region_init_io(region, NULL, &gipi_ops, &ms->gipi->core[cpu], str, 0x100); -+ memory_region_add_subregion(get_system_memory(), addr, region); -+ return 0; -+} -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -new file mode 100644 -index 000000000..3db269274 ---- /dev/null -+++ b/hw/loongarch/larch_3a.c -@@ -0,0 +1,2026 @@ -+/* -+ * QEMU loongarch 3a develop board emulation -+ * -+ * Copyright (C) 2013-2014 qiaochong -+ * Copyright (C) 2016-2017 zhangshuangshuang -+ * -+ * 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/units.h" -+#include "qapi/error.h" -+#include "qemu/datadir.h" -+#include "hw/hw.h" -+#include "hw/loongarch/cpudevs.h" -+#include "hw/i386/pc.h" -+#include "hw/char/serial.h" -+#include "hw/isa/isa.h" -+#include "hw/qdev-core.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/runstate.h" -+#include "sysemu/reset.h" -+#include "migration/vmstate.h" -+#include "sysemu/cpus.h" -+#include "hw/boards.h" -+#include "qemu/log.h" -+#include "hw/loongarch/bios.h" -+#include "hw/loader.h" -+#include "elf.h" -+#include "exec/address-spaces.h" -+#include "hw/ide.h" -+#include "hw/pci/pci_host.h" -+#include "hw/pci/msi.h" -+#include "linux/kvm.h" -+#include "sysemu/kvm.h" -+#include "sysemu/numa.h" -+#include "hw/rtc/mc146818rtc.h" -+#include "hw/irq.h" -+#include "net/net.h" -+#include "hw/timer/i8254.h" -+#include "hw/loongarch/larch.h" -+#include "hw/loongarch/ls7a.h" -+#include "hw/nvram/fw_cfg.h" -+#include "hw/firmware/smbios.h" -+#include "acpi-build.h" -+#include -+#include -+#include "sysemu/block-backend.h" -+#include "hw/block/flash.h" -+#include "sysemu/device_tree.h" -+#include "qapi/visitor.h" -+#include "qapi/qapi-visit-common.h" -+ -+#include -+ -+#define DMA64_SUPPORTED 0x2 -+#define MAX_IDE_BUS 2 -+ -+#define BOOTPARAM_PHYADDR 0x0ff00000ULL -+#define BOOTPARAM_ADDR (0x9000000000000000ULL + BOOTPARAM_PHYADDR) -+#define SMBIOS_PHYSICAL_ADDRESS 0x0fe00000 -+#define SMBIOS_SIZE_LIMIT 0x200000 -+#define RESERVED_SIZE_LIMIT 0x1100000 -+#define COMMAND_LINE_SIZE 4096 -+#define FW_CONF_ADDR 0x0fff0000 -+ -+#define PHYS_TO_VIRT(x) ((x) | 0x9000000000000000ULL) -+ -+#define TARGET_REALPAGE_MASK (TARGET_PAGE_MASK << 2) -+ -+#ifdef CONFIG_KVM -+#define LS_ISA_IO_SIZE 0x02000000 -+#define LS_ISA_MEM_SIZE 0x40000000 -+#else -+#define LS_ISA_IO_SIZE 0x00010000 -+#define LS_ISA_MEM_SIZE 0x01000000 -+#endif -+ -+#ifdef CONFIG_KVM -+#define align(x) (((x) + 63) & ~63) -+#else -+#define align(x) (((x) + 15) & ~15) -+#endif -+ -+#define DEBUG_LOONGARCH3A 0 -+#define FLASH_SECTOR_SIZE 4096 -+ -+#define DPRINTF(fmt, ...) \ -+ do { if (DEBUG_LOONGARCH3A) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0) -+ -+#define DEFINE_LS3A5K_MACHINE(suffix, name, optionfn) \ -+ static void ls3a5k_init_##suffix(MachineState *machine) \ -+ { \ -+ ls3a5k_init(machine); \ -+ } \ -+ DEFINE_LOONGARCH_MACHINE(suffix, name, ls3a5k_init_##suffix, optionfn) -+ -+struct efi_memory_map_loongarch { -+ uint16_t vers; /* version of efi_memory_map */ -+ uint32_t nr_map; /* number of memory_maps */ -+ uint32_t mem_freq; /* memory frequence */ -+ struct mem_map { -+ uint32_t node_id; /* node_id which memory attached to */ -+ uint32_t mem_type; /* system memory, pci memory, pci io, etc. */ -+ uint64_t mem_start; /* memory map start address */ -+ uint32_t mem_size; /* each memory_map size, not the total size */ -+ } map[128]; -+} __attribute__((packed)); -+ -+enum loongarch_cpu_type { -+ Loongson3 = 0x1, -+ Loongson3_comp = 0x2 -+}; -+ -+struct GlobalProperty loongarch_compat[] = { -+ { -+ .driver = "rtl8139", -+ .property = "romfile", -+ .value = "", -+ },{ -+ .driver = "e1000", -+ .property = "romfile", -+ .value = "", -+ },{ -+ .driver = "virtio-net-pci", -+ .property = "romfile", -+ .value = "", -+ },{ -+ .driver = "qxl-vga", -+ .property = "romfile", -+ .value = "", -+ },{ -+ .driver = "VGA", -+ .property = "romfile", -+ .value = "", -+ },{ -+ .driver = "cirrus-vga", -+ .property = "romfile", -+ .value = "", -+ },{ -+ .driver = "virtio-vga", -+ .property = "romfile", -+ .value = "", -+ },{ -+ .driver = "vmware-svga", -+ .property = "romfile", -+ .value = "", -+ }, -+}; -+const size_t loongarch_compat_len = G_N_ELEMENTS(loongarch_compat); -+ -+/* -+ * Capability and feature descriptor structure for LOONGARCH CPU -+ */ -+struct efi_cpuinfo_loongarch { -+ uint16_t vers; /* version of efi_cpuinfo_loongarch */ -+ uint32_t processor_id; /* PRID, e.g. 6305, 6306 */ -+ enum loongarch_cpu_type cputype; /* 3A, 3B, etc. */ -+ uint32_t total_node; /* num of total numa nodes */ -+ uint16_t cpu_startup_core_id; /* Core id */ -+ uint16_t reserved_cores_mask; -+ uint32_t cpu_clock_freq; /* cpu_clock */ -+ uint32_t nr_cpus; -+} __attribute__((packed)); -+ -+#define MAX_UARTS 64 -+struct uart_device { -+ uint32_t iotype; /* see include/linux/serial_core.h */ -+ uint32_t uartclk; -+ uint32_t int_offset; -+ uint64_t uart_base; -+} __attribute__((packed)); -+ -+#define MAX_SENSORS 64 -+#define SENSOR_TEMPER 0x00000001 -+#define SENSOR_VOLTAGE 0x00000002 -+#define SENSOR_FAN 0x00000004 -+struct sensor_device { -+ char name[32]; /* a formal name */ -+ char label[64]; /* a flexible description */ -+ uint32_t type; /* SENSOR_* */ -+ uint32_t id; /* instance id of a sensor-class */ -+ uint32_t fan_policy; /* see arch/loongarch/include/ -+ asm/mach-loongarch/loongarch_hwmon.h */ -+ uint32_t fan_percent;/* only for constant speed policy */ -+ uint64_t base_addr; /* base address of device registers */ -+} __attribute__((packed)); -+ -+struct system_loongarch { -+ uint16_t vers; /* version of system_loongarch */ -+ uint32_t ccnuma_smp; /* 0: no numa; 1: has numa */ -+ uint32_t sing_double_channel;/* 1:single; 2:double */ -+ uint32_t nr_uarts; -+ struct uart_device uarts[MAX_UARTS]; -+ uint32_t nr_sensors; -+ struct sensor_device sensors[MAX_SENSORS]; -+ char has_ec; -+ char ec_name[32]; -+ uint64_t ec_base_addr; -+ char has_tcm; -+ char tcm_name[32]; -+ uint64_t tcm_base_addr; -+ uint64_t workarounds; /* see workarounds.h */ -+} __attribute__((packed)); -+ -+struct irq_source_routing_table { -+ uint16_t vers; -+ uint16_t size; -+ uint16_t rtr_bus; -+ uint16_t rtr_devfn; -+ uint32_t vendor; -+ uint32_t device; -+ uint32_t PIC_type; /* conform use HT or PCI to route to CPU-PIC */ -+ uint64_t ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ -+ uint64_t ht_enable; /* irqs used in this PIC */ -+ uint32_t node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */ -+ uint64_t pci_mem_start_addr; -+ uint64_t pci_mem_end_addr; -+ uint64_t pci_io_start_addr; -+ uint64_t pci_io_end_addr; -+ uint64_t pci_config_addr; -+ uint32_t dma_mask_bits; -+ uint16_t dma_noncoherent; -+} __attribute__((packed)); -+ -+struct interface_info { -+ uint16_t vers; /* version of the specificition */ -+ uint16_t size; -+ uint8_t flag; -+ char description[64]; -+} __attribute__((packed)); -+ -+#define MAX_RESOURCE_NUMBER 128 -+struct resource_loongarch { -+ uint64_t start; /* resource start address */ -+ uint64_t end; /* resource end address */ -+ char name[64]; -+ uint32_t flags; -+}; -+ -+struct archdev_data {}; /* arch specific additions */ -+ -+struct board_devices { -+ char name[64]; /* hold the device name */ -+ uint32_t num_resources; /* number of device_resource */ -+ /* for each device's resource */ -+ struct resource_loongarch resource[MAX_RESOURCE_NUMBER]; -+ /* arch specific additions */ -+ struct archdev_data archdata; -+}; -+ -+struct loongarch_special_attribute { -+ uint16_t vers; /* version of this special */ -+ char special_name[64]; /* special_atribute_name */ -+ uint32_t loongarch_special_type; /* type of special device */ -+ /* for each device's resource */ -+ struct resource_loongarch resource[MAX_RESOURCE_NUMBER]; -+}; -+ -+struct loongarch_params { -+ uint64_t memory_offset; /* efi_memory_map_loongarch struct offset */ -+ uint64_t cpu_offset; /* efi_cpuinfo_loongarch struct offset */ -+ uint64_t system_offset; /* system_loongarch struct offset */ -+ uint64_t irq_offset; /* irq_source_routing_table struct offset */ -+ uint64_t interface_offset; /* interface_info struct offset */ -+ uint64_t special_offset; /* loongarch_special_attribute struct offset */ -+ uint64_t boarddev_table_offset; /* board_devices offset */ -+}; -+ -+struct smbios_tables { -+ uint16_t vers; /* version of smbios */ -+ uint64_t vga_bios; /* vga_bios address */ -+ struct loongarch_params lp; -+}; -+ -+struct efi_reset_system_t { -+ uint64_t ResetCold; -+ uint64_t ResetWarm; -+ uint64_t ResetType; -+ uint64_t Shutdown; -+ uint64_t DoSuspend; /* NULL if not support */ -+}; -+ -+struct efi_loongarch { -+ uint64_t mps; /* MPS table */ -+ uint64_t acpi; /* ACPI table (IA64 ext 0.71) */ -+ uint64_t acpi20; /* ACPI table (ACPI 2.0) */ -+ struct smbios_tables smbios; /* SM BIOS table */ -+ uint64_t sal_systab; /* SAL system table */ -+ uint64_t boot_info; /* boot info table */ -+}; -+ -+struct boot_params { -+ struct efi_loongarch efi; -+ struct efi_reset_system_t reset_system; -+}; -+ -+static struct _loaderparams { -+ unsigned long ram_size; -+ const char *kernel_filename; -+ const char *kernel_cmdline; -+ const char *initrd_filename; -+ unsigned long a0, a1, a2; -+} loaderparams; -+ -+static struct _firmware_config { -+ unsigned long ram_size; -+ unsigned int mem_freq; -+ unsigned int cpu_nr; -+ unsigned int cpu_clock_freq; -+} fw_config; -+ -+struct la_memmap_entry { -+ uint64_t address; -+ uint64_t length; -+ uint32_t type; -+ uint32_t reserved; -+} ; -+ -+static void *boot_params_buf; -+static void *boot_params_p; -+static struct la_memmap_entry *la_memmap_table; -+static unsigned la_memmap_entries; -+ -+CPULOONGARCHState *cpu_states[LOONGARCH_MAX_VCPUS]; -+ -+struct kvm_cpucfg ls3a5k_cpucfgs = { -+ .cpucfg[LOONGARCH_CPUCFG0] = CPUCFG0_3A5000_PRID, -+ .cpucfg[LOONGARCH_CPUCFG1] = CPUCFG1_ISGR64 | CPUCFG1_PAGING | -+ CPUCFG1_IOCSR | CPUCFG1_PABITS | CPUCFG1_VABITS | CPUCFG1_UAL | -+ CPUCFG1_RI | CPUCFG1_XI | CPUCFG1_RPLV | CPUCFG1_HUGEPG | -+ CPUCFG1_IOCSRBRD, -+ .cpucfg[LOONGARCH_CPUCFG2] = CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP | -+ CPUCFG2_FPVERS | CPUCFG2_LSX | CPUCFG2_LASX | CPUCFG2_COMPLEX | -+ CPUCFG2_CRYPTO | CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | CPUCFG2_LSPW | -+ CPUCFG2_LAM, -+ .cpucfg[LOONGARCH_CPUCFG3] = CPUCFG3_CCDMA | CPUCFG3_SFB | CPUCFG3_UCACC | -+ CPUCFG3_LLEXC | CPUCFG3_SCDLY | CPUCFG3_LLDBAR | CPUCFG3_ITLBT | -+ CPUCFG3_ICACHET | CPUCFG3_SPW_LVL | CPUCFG3_SPW_HG_HF | CPUCFG3_RVA | -+ CPUCFG3_RVAMAX, -+ .cpucfg[LOONGARCH_CPUCFG4] = CCFREQ_100M, -+ .cpucfg[LOONGARCH_CPUCFG5] = CPUCFG5_CCMUL | CPUCFG5_CCDIV, -+ .cpucfg[LOONGARCH_CPUCFG6] = CPUCFG6_PMP | CPUCFG6_PAMVER | CPUCFG6_PMNUM | -+ CPUCFG6_PMBITS | CPUCFG6_UPM, -+ .cpucfg[LOONGARCH_CPUCFG16] = CPUCFG16_L1_IUPRE | CPUCFG16_L1_DPRE | -+ CPUCFG16_L2_IUPRE | CPUCFG16_L2_IUUNIFY | CPUCFG16_L2_IUPRIV | -+ CPUCFG16_L3_IUPRE | CPUCFG16_L3_IUUNIFY | CPUCFG16_L3_IUINCL, -+ .cpucfg[LOONGARCH_CPUCFG17] = CPUCFG17_L1I_WAYS_M | CPUCFG17_L1I_SETS_M | -+ CPUCFG17_L1I_SIZE_M, -+ .cpucfg[LOONGARCH_CPUCFG18] = CPUCFG18_L1D_WAYS_M | CPUCFG18_L1D_SETS_M | -+ CPUCFG18_L1D_SIZE_M, -+ .cpucfg[LOONGARCH_CPUCFG19] = CPUCFG19_L2_WAYS_M | CPUCFG19_L2_SETS_M | -+ CPUCFG19_L2_SIZE_M, -+ .cpucfg[LOONGARCH_CPUCFG20] = CPUCFG20_L3_WAYS_M | CPUCFG20_L3_SETS_M | -+ CPUCFG20_L3_SIZE_M, -+}; -+ -+bool loongarch_is_acpi_enabled(LoongarchMachineState *vms) -+{ -+ if (vms->acpi == ON_OFF_AUTO_OFF) { -+ return false; -+ } -+ return true; -+} -+static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(obj); -+ OnOffAuto acpi = lsms->acpi; -+ -+ visit_type_OnOffAuto(v, name, &acpi, errp); -+} -+ -+static void loongarch_set_acpi(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(obj); -+ -+ visit_type_OnOffAuto(v, name, &lsms->acpi, errp); -+} -+int la_memmap_add_entry(uint64_t address, uint64_t length, uint32_t type) -+{ -+ int i; -+ -+ for (i = 0; i < la_memmap_entries; i++) { -+ if (la_memmap_table[i].address == address) { -+ fprintf(stderr, "%s address:0x%lx length:0x%lx already exists\n", -+ __func__, address, length); -+ return 0; -+ } -+ } -+ -+ la_memmap_table = g_renew(struct la_memmap_entry, la_memmap_table, -+ la_memmap_entries + 1); -+ la_memmap_table[la_memmap_entries].address = cpu_to_le64(address); -+ la_memmap_table[la_memmap_entries].length = cpu_to_le64(length); -+ la_memmap_table[la_memmap_entries].type = cpu_to_le32(type); -+ la_memmap_entries++; -+ -+ return la_memmap_entries; -+} -+ -+static ram_addr_t get_hotplug_membase(ram_addr_t ram_size) -+{ -+ ram_addr_t sstart; -+ -+ if (ram_size <= 0x10000000) { -+ sstart = 0x90000000; -+ } else { -+ sstart = 0x90000000 + ROUND_UP((ram_size - 0x10000000), -+ LOONGARCH_HOTPLUG_MEM_ALIGN); -+ } -+ return sstart; -+} -+ -+static struct efi_memory_map_loongarch *init_memory_map(void *g_map) -+{ -+ struct efi_memory_map_loongarch *emap = g_map; -+ -+ emap->nr_map = 4; -+ emap->mem_freq = 266000000; -+ -+ emap->map[0].node_id = 0; -+ emap->map[0].mem_type = 1; -+ emap->map[0].mem_start = 0x0; -+#ifdef CONFIG_KVM -+ emap->map[0].mem_size = (loaderparams.ram_size > 0x10000000 -+ ? 256 : (loaderparams.ram_size >> 20)) - 18; -+#else -+ emap->map[0].mem_size = atoi(getenv("memsize")); -+#endif -+ -+ emap->map[1].node_id = 0; -+ emap->map[1].mem_type = 2; -+ emap->map[1].mem_start = 0x90000000; -+#ifdef CONFIG_KVM -+ emap->map[1].mem_size = (loaderparams.ram_size > 0x10000000 -+ ? (loaderparams.ram_size >> 20) - 256 : 0); -+#else -+ emap->map[1].mem_size = atoi(getenv("highmemsize")); -+#endif -+ -+ /* support for smbios */ -+ emap->map[2].node_id = 0; -+ emap->map[2].mem_type = 10; -+ emap->map[2].mem_start = SMBIOS_PHYSICAL_ADDRESS; -+ emap->map[2].mem_size = SMBIOS_SIZE_LIMIT >> 20; -+ -+ emap->map[3].node_id = 0; -+ emap->map[3].mem_type = 3; -+ emap->map[3].mem_start = 0xee00000; -+ emap->map[3].mem_size = RESERVED_SIZE_LIMIT >> 20; -+ -+ return emap; -+} -+ -+static uint64_t get_host_cpu_freq(void) -+{ -+ int fd = 0; -+ char buf[1024]; -+ uint64_t freq = 0, size = 0; -+ char *buf_p; -+ -+ fd = open("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", O_RDONLY); -+ if (fd == -1) { -+ fprintf(stderr, "/sys/devices/system/cpu/cpu0/cpufreq/ \ -+ cpuinfo_max_freq not exist!\n"); -+ fprintf(stderr, "Trying /proc/cpuinfo...\n"); -+ } else { -+ size = read(fd, buf, 16); -+ if (size == -1) { -+ fprintf(stderr, "read err...\n"); -+ } -+ close(fd); -+ freq = (uint64_t)atoi(buf); -+ return freq * 1000; -+ } -+ -+ fd = open("/proc/cpuinfo", O_RDONLY); -+ if (fd == -1) { -+ fprintf(stderr, "Failed to open /proc/cpuinfo!\n"); -+ return 0; -+ } -+ -+ size = read(fd, buf, 1024); -+ if (size == -1) { -+ fprintf(stderr, "read err...\n"); -+ } -+ close(fd); -+ -+ buf_p = strstr(buf, "MHz"); -+ if (buf_p) { -+ while (*buf_p != ':') { -+ buf_p++; -+ } -+ buf_p += 2; -+ } else { -+ buf_p = strstr(buf, "name"); -+ while (*buf_p != '@') { -+ buf_p++; -+ } -+ buf_p += 2; -+ } -+ -+ memcpy(buf, buf_p, 12); -+ buf_p = buf; -+ while ((*buf_p >= '0') && (*buf_p <= '9')) { -+ buf_p++; -+ } -+ *buf_p = '\0'; -+ -+ freq = (uint64_t)atoi(buf); -+ return freq * 1000 * 1000; -+} -+ -+static char *get_host_cpu_model_name(void) -+{ -+ int fd = 0; -+ int size = 0; -+ static char buf[1024]; -+ char *buf_p; -+ -+ fd = open("/proc/cpuinfo", O_RDONLY); -+ if (fd == -1) { -+ fprintf(stderr, "Failed to open /proc/cpuinfo!\n"); -+ return 0; -+ } -+ -+ size = read(fd, buf, 1024); -+ if (size == -1) { -+ fprintf(stderr, "read err...\n"); -+ } -+ close(fd); -+ buf_p = strstr(buf, "name"); -+ -+ while (*buf_p != ':') { -+ buf_p++; -+ } -+ buf_p = buf_p + 2; -+ memcpy(buf, buf_p, 40); -+ buf_p = buf; -+ while (*buf_p != '\n') { -+ buf_p++; -+ } -+ -+ *(buf_p) = '\0'; -+ -+ return buf; -+} -+ -+static void fw_conf_init(unsigned long ramsize) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ int smp_cpus = ms->smp.cpus; -+ fw_config.ram_size = ramsize; -+ fw_config.mem_freq = 266000000; -+ fw_config.cpu_nr = smp_cpus ; -+ fw_config.cpu_clock_freq = get_host_cpu_freq(); -+} -+ -+static struct efi_cpuinfo_loongarch *init_cpu_info(void *g_cpuinfo_loongarch) -+{ -+ struct efi_cpuinfo_loongarch *c = g_cpuinfo_loongarch; -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ int smp_cpus = ms->smp.cpus; -+ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ -+ if (strstr(lsmc->cpu_name, "5000")) { -+ c->processor_id = 0x14c010; -+ } -+ c->cputype = Loongson3_comp; -+ c->cpu_clock_freq = get_host_cpu_freq(); -+ if (!c->cpu_clock_freq) { -+ c->cpu_clock_freq = 200000000; -+ } -+ c->total_node = 1; -+ c->nr_cpus = smp_cpus; -+ c->cpu_startup_core_id = 0; -+ c->reserved_cores_mask = 0xffff & (0xffff << smp_cpus); -+ -+ return c; -+} -+ -+static struct system_loongarch *init_system_loongarch(void *g_sysitem) -+{ -+ struct system_loongarch *s = g_sysitem; -+ -+ s->ccnuma_smp = 1; -+ s->ccnuma_smp = 0; -+ s->sing_double_channel = 1; -+ -+ return s; -+} -+ -+enum loongarch_irq_source_enum { -+ HT, I8259, UNKNOWN -+}; -+ -+static struct irq_source_routing_table *init_irq_source(void *g_irq_source) -+{ -+ struct irq_source_routing_table *irq_info = g_irq_source; -+ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ -+ irq_info->PIC_type = HT; -+ irq_info->ht_int_bit = 1 << 24; -+ irq_info->ht_enable = 0x0000d17b; -+ irq_info->node_id = 0; -+ -+ irq_info->pci_mem_start_addr = LS_ISA_MEM_BASE; -+ irq_info->pci_mem_end_addr = irq_info->pci_mem_start_addr + LS_ISA_MEM_SIZE - 1; -+ -+ if (strstr(lsmc->cpu_name, "5000")) { -+ irq_info->pci_io_start_addr = LS3A5K_ISA_IO_BASE; -+ } -+ irq_info->dma_noncoherent = 1; -+ return irq_info; -+} -+ -+static struct interface_info *init_interface_info(void *g_interface) -+{ -+ struct interface_info *inter = g_interface; -+ int flashsize = 0x80000; -+ -+ inter->vers = 0x0001; -+ inter->size = flashsize / 0x400; -+ inter->flag = 1; -+ -+ strcpy(inter->description, "PMON_Version_v2.1"); -+ -+ return inter; -+} -+ -+static struct board_devices *board_devices_info(void *g_board) -+{ -+ struct board_devices *bd = g_board; -+ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ -+ if (!strcmp(lsmc->bridge_name, "ls7a")) { -+ strcpy(bd->name, "Loongarch-3A-7A-1w-V1.03-demo"); -+ } -+ bd->num_resources = 10; -+ -+ return bd; -+} -+ -+static struct loongarch_special_attribute *init_special_info(void *g_special) -+{ -+ struct loongarch_special_attribute *special = g_special; -+ char update[11] = "2013-01-01"; -+ int VRAM_SIZE = 0x20000; -+ -+ strcpy(special->special_name, update); -+ special->resource[0].flags = 0; -+ special->resource[0].start = 0; -+ special->resource[0].end = VRAM_SIZE; -+ strcpy(special->resource[0].name, "SPMODULE"); -+ special->resource[0].flags |= DMA64_SUPPORTED; -+ -+ return special; -+} -+ -+static void init_loongarch_params(struct loongarch_params *lp) -+{ -+ void *p = boot_params_p; -+ -+ lp->memory_offset = (unsigned long long)init_memory_map(p) -+ - (unsigned long long)lp; -+ p += align(sizeof(struct efi_memory_map_loongarch)); -+ -+ lp->cpu_offset = (unsigned long long)init_cpu_info(p) -+ - (unsigned long long)lp; -+ p += align(sizeof(struct efi_cpuinfo_loongarch)); -+ -+ lp->system_offset = (unsigned long long)init_system_loongarch(p) -+ - (unsigned long long)lp; -+ p += align(sizeof(struct system_loongarch)); -+ -+ lp->irq_offset = (unsigned long long)init_irq_source(p) -+ - (unsigned long long)lp; -+ p += align(sizeof(struct irq_source_routing_table)); -+ -+ lp->interface_offset = (unsigned long long)init_interface_info(p) -+ - (unsigned long long)lp; -+ p += align(sizeof(struct interface_info)); -+ -+ lp->boarddev_table_offset = (unsigned long long)board_devices_info(p) -+ - (unsigned long long)lp; -+ p += align(sizeof(struct board_devices)); -+ -+ lp->special_offset = (unsigned long long)init_special_info(p) -+ - (unsigned long long)lp; -+ p += align(sizeof(struct loongarch_special_attribute)); -+ -+ boot_params_p = p; -+} -+ -+static void init_smbios(struct smbios_tables *smbios) -+{ -+ smbios->vers = 1; -+ smbios->vga_bios = 1; -+ init_loongarch_params(&(smbios->lp)); -+} -+ -+static void init_efi(struct efi_loongarch *efi) -+{ -+ init_smbios(&(efi->smbios)); -+} -+ -+static int init_boot_param(struct boot_params *bp) -+{ -+ init_efi(&(bp->efi)); -+ -+ return 0; -+} -+ -+static unsigned int ls3a5k_aui_boot_code[] = { -+ 0x0380200d, /* ori $r13,$r0,0x8 */ -+ 0x0400002d, /* csrwr $r13,0x0 */ -+ 0x0401000e, /* csrrd $r14,0x40 */ -+ 0x0343fdce, /* andi $r14,$r14,0xff */ -+ 0x143fc02c, /* lu12i.w $r12,261889(0x1fe01) */ -+ 0x1600000c, /* lu32i.d $r12,0 */ -+ 0x0320018c, /* lu52i.d $r12,$r12,-1792(0x800) */ -+ 0x03400dcf, /* andi $r15,$r14,0x3 */ -+ 0x004121ef, /* slli.d $r15,$r15,0x8 */ -+ 0x00153d8c, /* or $r12,$r12,$r15 */ -+ 0x034031d0, /* andi $r16,$r14,0xc */ -+ 0x0041aa10, /* slli.d $r16,$r16,0x2a */ -+ 0x0015418c, /* or $r12,$r12,$r16 */ -+ 0x28808184, /* ld.w $r4,$r12,32(0x20) */ -+ 0x43fffc9f, /* beqz $r4,0 -4 */ -+ 0x28c08184, /* ld.d $r4,$r12,32(0x20) */ -+ 0x28c0a183, /* ld.d $r3,$r12,40(0x28) */ -+ 0x28c0c182, /* ld.d $r2,$r12,48(0x30) */ -+ 0x28c0e185, /* ld.d $r5,$r12,56(0x38) */ -+ 0x4c000080, /* jirl $r0,$r4,0 */ -+}; -+ -+static int set_bootparam_uefi(ram_addr_t initrd_offset, long initrd_size) -+{ -+ long params_size; -+ char memenv[32]; -+ char highmemenv[32]; -+ void *params_buf; -+ unsigned long *parg_env; -+ int ret = 0; -+ -+ /* Allocate params_buf for command line. */ -+ params_size = 0x100000; -+ params_buf = g_malloc0(params_size); -+ -+ /* -+ * Layout of params_buf looks like this: -+ * argv[0], argv[1], 0, env[0], env[1], ...env[i], 0, -+ * argv[0]'s data, argv[1]'s data, env[0]'data, ..., env[i]'s data, 0 -+ */ -+ parg_env = (void *)params_buf; -+ -+ ret = (3 + 1) * sizeof(target_ulong); -+ *parg_env++ = (BOOTPARAM_ADDR + ret); -+ ret += (1 + snprintf(params_buf + ret, COMMAND_LINE_SIZE - ret, "g")); -+ -+ /* argv1 */ -+ *parg_env++ = BOOTPARAM_ADDR + ret; -+ if (initrd_size > 0) -+ ret += (1 + snprintf(params_buf + ret, COMMAND_LINE_SIZE - ret, -+ "rd_start=0x%llx rd_size=%li %s", -+ PHYS_TO_VIRT((uint32_t)initrd_offset), -+ initrd_size, loaderparams.kernel_cmdline)); -+ else -+ ret += (1 + snprintf(params_buf + ret, COMMAND_LINE_SIZE - ret, "%s", -+ loaderparams.kernel_cmdline)); -+ -+ /* argv2 */ -+ *parg_env++ = 0; -+ -+ /* env */ -+ sprintf(memenv, "%lu", loaderparams.ram_size > 0x10000000 -+ ? 256 : (loaderparams.ram_size >> 20)); -+ sprintf(highmemenv, "%lu", loaderparams.ram_size > 0x10000000 -+ ? (loaderparams.ram_size >> 20) - 256 : 0); -+ -+ setenv("memsize", memenv, 1); -+ setenv("highmemsize", highmemenv, 1); -+ -+ ret = ((ret + 32) & ~31); -+ -+ boot_params_buf = (void *)(params_buf + ret); -+ boot_params_p = boot_params_buf + align(sizeof(struct boot_params)); -+ init_boot_param(boot_params_buf); -+ rom_add_blob_fixed("params", params_buf, params_size, -+ BOOTPARAM_PHYADDR); -+ loaderparams.a0 = 2; -+ loaderparams.a1 = BOOTPARAM_ADDR; -+ loaderparams.a2 = BOOTPARAM_ADDR + ret; -+ -+ return 0; -+} -+ -+static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) -+{ -+ return addr & 0x1fffffffll; -+} -+ -+static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg, -+ uint64_t highram_size, -+ uint64_t phyAddr_initrd) -+{ -+ int64_t entry, kernel_low, kernel_high; -+ long initrd_size = 0; -+ uint64_t initrd_offset = 0; -+ void *cmdline_buf; -+ int ret = 0; -+ -+ ret = load_elf(loaderparams.kernel_filename, NULL, cpu_loongarch_virt_to_phys, NULL, -+ (uint64_t *)&entry, (uint64_t *)&kernel_low, -+ (uint64_t *)&kernel_high, NULL, 0, EM_LOONGARCH, 1, 0); -+ -+ if(0 > ret) { -+ error_report("kernel image load error"); -+ exit(1); -+ } -+ -+ fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ENTRY, entry); -+ -+ if (loaderparams.initrd_filename) { -+ initrd_size = get_image_size(loaderparams.initrd_filename); -+ if (0 < initrd_size) { -+ if (initrd_size > highram_size) { -+ error_report("initrd size is too big, should below %ld MB", -+ highram_size / S_1MiB); -+ /*prevent write io memory address space*/ -+ exit(1); -+ } -+ initrd_offset = (phyAddr_initrd - initrd_size) & TARGET_REALPAGE_MASK; -+ initrd_size = load_image_targphys(loaderparams.initrd_filename, -+ initrd_offset, -+ loaderparams.ram_size - initrd_offset); -+ fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_offset); -+ fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); -+ } else { -+ error_report("initrd image size is error"); -+ } -+ } -+ -+ cmdline_buf = g_malloc0(COMMAND_LINE_SIZE); -+ if (initrd_size > 0) -+ ret = (1 + snprintf(cmdline_buf, COMMAND_LINE_SIZE, -+ "rd_start=0x%llx rd_size=%li %s", -+ PHYS_TO_VIRT(initrd_offset), -+ initrd_size, loaderparams.kernel_cmdline)); -+ else -+ ret = (1 + snprintf(cmdline_buf, COMMAND_LINE_SIZE, "%s", -+ loaderparams.kernel_cmdline)); -+ -+ fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, ret); -+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, (const char *)cmdline_buf); -+ -+ return ; -+} -+ -+static int64_t load_kernel(void) -+{ -+ int64_t entry, kernel_low, kernel_high; -+ long initrd_size = 0; -+ ram_addr_t initrd_offset = 0; -+ -+ load_elf(loaderparams.kernel_filename, NULL, cpu_loongarch_virt_to_phys, NULL, -+ (uint64_t *)&entry, (uint64_t *)&kernel_low, -+ (uint64_t *)&kernel_high, NULL, 0, EM_LOONGARCH, 1, 0); -+ -+ if (loaderparams.initrd_filename) { -+ initrd_size = get_image_size(loaderparams.initrd_filename); -+ -+ if (initrd_size > 0) { -+ initrd_offset = (kernel_high * 4 + ~TARGET_REALPAGE_MASK) -+ & TARGET_REALPAGE_MASK; -+ initrd_size = load_image_targphys(loaderparams.initrd_filename, -+ initrd_offset, -+ loaderparams.ram_size - initrd_offset); -+ } -+ } -+ set_bootparam_uefi(initrd_offset, initrd_size); -+ -+ return entry; -+} -+ -+static void main_cpu_reset(void *opaque) -+{ -+ ResetData *s = (ResetData *)opaque; -+ CPULOONGARCHState *env = &s->cpu->env; -+ -+ cpu_reset(CPU(s->cpu)); -+ env->active_tc.PC = s->vector; -+ env->active_tc.gpr[4] = loaderparams.a0; -+ env->active_tc.gpr[5] = loaderparams.a1; -+ env->active_tc.gpr[6] = loaderparams.a2; -+} -+ -+void slave_cpu_reset(void *opaque) -+{ -+ ResetData *s = (ResetData *)opaque; -+ -+ cpu_reset(CPU(s->cpu)); -+} -+ -+ -+/* KVM_IRQ_LINE irq field index values */ -+#define KVM_LOONGARCH_IRQ_TYPE_SHIFT 24 -+#define KVM_LOONGARCH_IRQ_TYPE_MASK 0xff -+#define KVM_LOONGARCH_IRQ_VCPU_SHIFT 16 -+#define KVM_LOONGARCH_IRQ_VCPU_MASK 0xff -+#define KVM_LOONGARCH_IRQ_NUM_SHIFT 0 -+#define KVM_LOONGARCH_IRQ_NUM_MASK 0xffff -+ -+/* irq_type field */ -+#define KVM_LOONGARCH_IRQ_TYPE_CPU_IP 0 -+#define KVM_LOONGARCH_IRQ_TYPE_CPU_IO 1 -+#define KVM_LOONGARCH_IRQ_TYPE_HT 2 -+#define KVM_LOONGARCH_IRQ_TYPE_MSI 3 -+#define KVM_LOONGARCH_IRQ_TYPE_IOAPIC 4 -+ -+static void legacy_set_irq(void *opaque, int irq, int level) -+{ -+ qemu_irq *pic = opaque; -+ -+ qemu_set_irq(pic[irq], level); -+} -+ -+typedef struct ls3a_intctlstate { -+ uint8_t nodecounter_reg[0x100]; -+ uint8_t pm_reg[0x100]; -+ uint8_t msi_reg[0x8]; -+ CPULOONGARCHState **env; -+ DeviceState *apicdev; -+ qemu_irq *ioapic_irq; -+#ifdef CONFIG_KVM -+ struct loongarch_kvm_irqchip chip; -+#endif -+} ls3a_intctlstate; -+ -+typedef struct ls3a_func_args { -+ ls3a_intctlstate *state; -+ uint64_t base; -+ uint32_t mask; -+ uint8_t *mem; -+} ls3a_func_args; -+ -+static uint64_t ls3a_msi_mem_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ return 0; -+} -+ -+static void ls3a_msi_mem_write(void *opaque, hwaddr addr, -+ uint64_t val, unsigned size) -+{ -+ struct kvm_msi msi; -+ apicState *apic; -+ -+ apic = (apicState *)opaque; -+ msi.address_lo = 0; -+ msi.address_hi = 0; -+ msi.data = val & 0xff; -+ msi.flags = 0; -+ memset(msi.pad, 0, sizeof(msi.pad)); -+ -+ if (kvm_irqchip_in_kernel()) { -+ kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi); -+ } else { -+ qemu_set_irq(apic->irq[msi.data], 1); -+ } -+} -+ -+ -+static const MemoryRegionOps ls3a_msi_ops = { -+ .read = ls3a_msi_mem_read, -+ .write = ls3a_msi_mem_write, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+}; -+ -+ -+static const VMStateDescription vmstate_ls3a_msi = { -+ .name = "ls3a-msi", -+ .version_id = 0, -+ .minimum_version_id = 0, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT8_ARRAY(msi_reg, ls3a_intctlstate, 0x8), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+static void ioapic_handler(void *opaque, int irq, int level) -+{ -+ apicState *apic; -+ int kvm_irq; -+ -+ apic = (apicState *)opaque; -+ -+ if (kvm_irqchip_in_kernel()) { -+ kvm_irq = (KVM_LOONGARCH_IRQ_TYPE_IOAPIC << KVM_LOONGARCH_IRQ_TYPE_SHIFT) -+ | (0 << KVM_LOONGARCH_IRQ_VCPU_SHIFT) | irq; -+ kvm_set_irq(kvm_state, kvm_irq, !!level); -+ } else { -+ qemu_set_irq(apic->irq[irq], level); -+ } -+} -+ -+static void *ls3a_intctl_init(MachineState *machine, CPULOONGARCHState *env[]) -+{ -+ qemu_irq *irqhandler; -+ ls3a_intctlstate *s; -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ LoongarchMachineClass *mc = LoongarchMACHINE_GET_CLASS(lsms); -+ DeviceState *dev; -+ SysBusDevice *busdev; -+ MemoryRegion *address_space_mem = get_system_memory(); -+ MemoryRegion *iomem = NULL; -+ int i; -+ -+ s = g_malloc0(sizeof(ls3a_intctlstate)); -+ -+ if (!s) { -+ return NULL; -+ } -+ -+ /*Add MSI mmio memory*/ -+ iomem = g_new(MemoryRegion, 1); -+ memory_region_init_io(iomem, NULL, &ls3a_msi_ops, lsms->apic, -+ "ls3a_msi", 0x8); -+ memory_region_add_subregion(address_space_mem, -+ MSI_ADDR_LOW, iomem); -+ vmstate_register(NULL, 0, &vmstate_ls3a_msi, s); -+ -+ s->env = env; -+ -+ if (!strcmp(mc->bridge_name, "ls7a")) { -+ if (lsms->apic_xrupt_override) { -+ DPRINTF("irqchip in kernel %d\n", kvm_irqchip_in_kernel()); -+#ifdef CONFIG_KVM -+ if (kvm_has_gsi_routing()) { -+ for (i = 0; i < 32; ++i) { -+ kvm_irqchip_add_irq_route(kvm_state, i, 0, i); -+ } -+ kvm_gsi_routing_allowed = true; -+ } -+ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled(); -+#endif -+ } -+ -+ irqhandler = qemu_allocate_irqs(ioapic_handler, lsms->apic, 64); -+ dev = qdev_new("ioapic"); -+ busdev = SYS_BUS_DEVICE(dev); -+ sysbus_realize_and_unref(busdev, &error_fatal); -+ sysbus_mmio_map(busdev, 0, mc->ls7a_ioapic_reg_base); -+ s->ioapic_irq = irqhandler; -+ s->apicdev = dev; -+ return s->ioapic_irq; -+ } -+ return NULL; -+} -+ -+/* Network support */ -+static void network_init(PCIBus *pci_bus) -+{ -+ int i; -+ -+ for (i = 0; i < nb_nics; i++) { -+ NICInfo *nd = &nd_table[i]; -+ -+ if (!nd->model) { -+ nd->model = g_strdup("virtio-net-pci"); -+ } -+ -+ pci_nic_init_nofail(nd, pci_bus, nd->model, NULL); -+ } -+} -+ -+void loongarch_cpu_destroy(MachineState *machine, LOONGARCHCPU *cpu) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ unsigned int id; -+ int smp_cpus = machine->smp.cpus; -+ id = cpu->id; -+ qemu_unregister_reset(slave_cpu_reset, lsms->reset_info[id]); -+ g_free(lsms->reset_info[id]); -+ lsms->reset_info[id] = NULL; -+ -+ smp_cpus -= 1; -+ if (lsms->fw_cfg) { -+ fw_cfg_modify_i16(lsms->fw_cfg, FW_CFG_NB_CPUS, -+ (uint16_t)smp_cpus); -+ } -+ -+ qemu_del_vm_change_state_handler(cpu->cpuStateEntry); -+} -+ -+LOONGARCHCPU *loongarch_cpu_create(MachineState *machine, -+ LOONGARCHCPU *cpu, Error **errp) -+{ -+ CPULOONGARCHState *env; -+ unsigned int id; -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ int smp_cpus = machine->smp.cpus; -+ id = cpu->id; -+ env = &cpu->env; -+ cpu_states[id] = env; -+ env->CSR_TMID |= id; -+ -+ lsms = LoongarchMACHINE(machine); -+ lsms->reset_info[id] = g_malloc0(sizeof(ResetData)); -+ lsms->reset_info[id]->cpu = cpu; -+ lsms->reset_info[id]->vector = env->active_tc.PC; -+ qemu_register_reset(slave_cpu_reset, lsms->reset_info[id]); -+ -+ /* Init CPU internal devices */ -+ cpu_init_irq(cpu); -+ cpu_loongarch_clock_init(cpu); -+ -+ smp_cpus += 1; -+ if (lsms->fw_cfg) { -+ fw_cfg_modify_i16(lsms->fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); -+ } -+ cpu_init_ipi(lsms, env->irq[12], id); -+ cpu_init_apic(lsms, env, id); -+ -+ return cpu; -+} -+ -+static void fw_cfg_boot_set(void *opaque, const char *boot_device, -+ Error **errp) -+{ -+ fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); -+} -+ -+static FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, -+ LoongarchMachineState *lsms) -+{ -+ FWCfgState *fw_cfg; -+ uint64_t *numa_fw_cfg; -+ int i; -+ const CPUArchIdList *cpus; -+ MachineClass *mc = MACHINE_GET_CLASS(lsms); -+ MachineState *ms = MACHINE(OBJECT(lsms)); -+ int max_cpus = ms->smp.max_cpus; -+ int smp_cpus = ms->smp.cpus; -+ int nb_numa_nodes = ms->numa_state->num_nodes; -+ NodeInfo *numa_info = ms->numa_state->nodes; -+ -+ fw_cfg = fw_cfg_init_mem_wide(FW_CFG_ADDR + 8, FW_CFG_ADDR, 8, 0, NULL); -+ fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); -+ fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); -+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); -+ -+ /* allocate memory for the NUMA channel: one (64bit) word for the number -+ * of nodes, one word for each VCPU->node and one word for each node to -+ * hold the amount of memory. -+ */ -+ numa_fw_cfg = g_new0(uint64_t, 1 + max_cpus + nb_numa_nodes); -+ numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes); -+ cpus = mc->possible_cpu_arch_ids(MACHINE(lsms)); -+ for (i = 0; i < cpus->len; i++) { -+ unsigned int apic_id = cpus->cpus[i].arch_id; -+ assert(apic_id < max_cpus); -+ numa_fw_cfg[apic_id + 1] = cpu_to_le64(cpus->cpus[i].props.node_id); -+ } -+ for (i = 0; i < nb_numa_nodes; i++) { -+ numa_fw_cfg[max_cpus + 1 + i] = -+ cpu_to_le64(numa_info[i].node_mem); -+ } -+ fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg, -+ (1 + max_cpus + nb_numa_nodes) * -+ sizeof(*numa_fw_cfg)); -+ -+ qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); -+ return fw_cfg; -+} -+ -+static void loongarch_build_smbios(LoongarchMachineState *lsms) -+{ -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ MachineState *ms = MACHINE(OBJECT(lsms)); -+ uint8_t *smbios_tables, *smbios_anchor; -+ size_t smbios_tables_len, smbios_anchor_len; -+ const char *product = "QEMU Virtual Machine"; -+ ms->smp.cores = 4; -+ -+ if (!lsms->fw_cfg) { -+ return; -+ } -+ -+ if (kvm_enabled()) { -+ if (strstr(lsmc->cpu_name, "5000")) { -+ product = "KVM"; -+ } -+ } else { -+ product = "Loongarch-3A5K-7A1000-TCG"; -+ } -+ -+ host_cpufreq = get_host_cpu_freq(); -+ -+ smbios_set_defaults("Loongson", product, lsmc->cpu_name, false, -+ true, NULL, NULL, SMBIOS_ENTRY_POINT_30); -+ -+ smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len, -+ &smbios_anchor, &smbios_anchor_len, &error_fatal); -+ -+ if (smbios_anchor) { -+ fw_cfg_add_file(lsms->fw_cfg, "etc/smbios/smbios-tables", -+ smbios_tables, smbios_tables_len); -+ fw_cfg_add_file(lsms->fw_cfg, "etc/smbios/smbios-anchor", -+ smbios_anchor, smbios_anchor_len); -+ } -+} -+ -+static -+void loongarch_machine_done(Notifier *notifier, void *data) -+{ -+ LoongarchMachineState *lsms = container_of(notifier, -+ LoongarchMachineState, machine_done); -+ loongarch_acpi_setup(); -+ loongarch_build_smbios(lsms); -+} -+ -+#ifdef CONFIG_TCG -+#define FEATURE_REG 0x1fe00008 -+#define VENDOR_REG 0x1fe00010 -+#define CPUNAME_REG 0x1fe00020 -+#define OTHER_FUNC_REG 0x1fe00420 -+#define _str(x) #x -+#define str(x) _str(x) -+#define SIMPLE_OPS(ADDR, SIZE) \ -+({\ -+ MemoryRegion *iomem = g_new(MemoryRegion, 1);\ -+ memory_region_init_io(iomem, NULL, &loongarch_qemu_ops, \ -+ (void *)ADDR, str(ADDR) , SIZE);\ -+ memory_region_add_subregion_overlap(address_space_mem, ADDR, iomem, 1);\ -+}) -+ -+static int reg180; -+ -+static void loongarch_qemu_write(void *opaque, hwaddr addr, -+ uint64_t val, unsigned size) -+{ -+ addr = ((hwaddr)(long)opaque) + addr; -+ addr = addr & 0xffffffff; -+ switch (addr) { -+ case 0x1fe00180: -+ reg180 = val; -+ break; -+ } -+} -+ -+static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ uint64_t feature = 0UL; -+ addr = ((hwaddr)(long)opaque) + addr; -+ addr = addr & 0xffffffff; -+ switch (addr) { -+ case 0x1fe00180: -+ return reg180; -+ case 0x1001041c: -+ return 0xa800; -+ case FEATURE_REG: -+ feature |= 1UL << 2 | 1UL << 3 | 1UL << 4 | 1UL << 11; -+ return feature ; -+ case VENDOR_REG: -+ return *(uint64_t *)"Loongson-3A5000"; -+ case CPUNAME_REG: -+ return *(uint64_t *)"3A5000"; -+ case 0x10013ffc: -+ return 0x80; -+ } -+ return 0; -+} -+ -+static const MemoryRegionOps loongarch_qemu_ops = { -+ .read = loongarch_qemu_read, -+ .write = loongarch_qemu_write, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+ .valid = { -+ .min_access_size = 4, -+ .max_access_size = 8, -+ }, -+ .impl = { -+ .min_access_size = 4, -+ .max_access_size = 8, -+ }, -+}; -+#endif -+ -+ -+static void loongarch_system_flash_cleanup_unused(LoongarchMachineState *lsms) -+{ -+ char *prop_name; -+ int i; -+ Object *dev_obj; -+ -+ for (i = 0; i < ARRAY_SIZE(lsms->flash); i++) { -+ dev_obj = OBJECT(lsms->flash[i]); -+ if (!object_property_get_bool(dev_obj, "realized", &error_abort)) { -+ prop_name = g_strdup_printf("pflash%d", i); -+ object_property_del(OBJECT(lsms), prop_name); -+ g_free(prop_name); -+ object_unparent(dev_obj); -+ lsms->flash[i] = NULL; -+ } -+ } -+} -+ -+ -+static bool loongarch_system_flash_init( LoongarchMachineState *lsms) -+{ -+ int i = 0; -+ int64_t size = 0; -+ PFlashCFI01 *pflash = NULL; -+ BlockBackend *pflash_blk; -+ -+ for(i = 0; i < ARRAY_SIZE(lsms->flash); i++) { -+ pflash_blk = NULL; -+ pflash = NULL; -+ -+ pflash = lsms->flash[i]; -+ pflash_cfi01_legacy_drive(pflash, -+ drive_get(IF_PFLASH, 0, i)); -+ -+ pflash_blk = pflash_cfi01_get_blk(pflash); -+ /*The pflash0 must be exist, or not support boot by pflash*/ -+ if(pflash_blk == NULL) { -+ if(i == 0) { -+ return false; -+ } else { -+ break; -+ } -+ } -+ -+ size = blk_getlength(pflash_blk); -+ if (size == 0 || size % FLASH_SECTOR_SIZE != 0) { -+ error_report("system firmware block device %s has invalid size " -+ "%" PRId64, -+ blk_name(pflash_blk), size); -+ error_report("its size must be a non-zero multiple of 0x%x", -+ FLASH_SECTOR_SIZE); -+ exit(1); -+ } -+ qdev_prop_set_uint32(DEVICE(pflash), "num-blocks", -+ size / FLASH_SECTOR_SIZE); -+ sysbus_realize_and_unref(SYS_BUS_DEVICE(pflash), &error_fatal); -+ if(i == 0) { -+ sysbus_mmio_map(SYS_BUS_DEVICE(pflash), 0, LS_BIOS_BASE); -+ } else { -+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(pflash), 0, LS_BIOS_VAR_BASE, 1); -+ } -+ } -+ -+ return true; -+} -+static void ls3a5k_bios_init(LoongarchMachineState *lsms, -+ ram_addr_t ram_size, -+ uint64_t highram_size, -+ uint64_t phyAddr_initrd, -+ const char *kernel_filename, -+ const char *kernel_cmdline, -+ const char *initrd_filename) -+{ -+ MemoryRegion *bios; -+ bool fw_cfg_used = false; -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ char *filename; -+ int bios_size; -+ const char *bios_name; -+ -+ bios_name = MACHINE(lsms)->firmware; -+ if (kernel_filename) { -+ loaderparams.ram_size = ram_size; -+ loaderparams.kernel_filename = kernel_filename; -+ loaderparams.kernel_cmdline = kernel_cmdline; -+ loaderparams.initrd_filename = initrd_filename; -+ } -+ -+ if(loongarch_system_flash_init(lsms)) { -+ fw_cfg_used = true; -+ } else { -+ bios = g_new(MemoryRegion, 1); -+ memory_region_init_ram(bios, NULL, "loongarch.bios", LS_BIOS_SIZE, &error_fatal); -+ memory_region_set_readonly(bios, true); -+ memory_region_add_subregion(get_system_memory(), LS_BIOS_BASE, bios); -+ -+ /* BIOS load */ -+ if (bios_name) { -+ if (access(bios_name, R_OK) == 0) { -+ load_image_targphys(bios_name, LS_BIOS_BASE, LS_BIOS_SIZE); -+ } else { -+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); -+ load_image_targphys(filename, LS_BIOS_BASE, LS_BIOS_SIZE); -+ g_free(filename); -+ } -+ fw_cfg_used = true; -+ } else { -+ if (strstr(lsmc->cpu_name, "5000")) { -+ bios_size = sizeof(ls3a5k_aui_boot_code); -+ rom_add_blob_fixed("bios", ls3a5k_aui_boot_code, bios_size, LS_BIOS_BASE); -+ } -+ -+ if (kernel_filename) { -+ lsms->reset_info[0]->vector = load_kernel(); -+ } else { -+ error_report("Please specify at lease one of -bios and -kernel"); -+ exit(1); -+ } -+ } -+ } -+ -+ loongarch_system_flash_cleanup_unused(lsms); -+ -+ if (fw_cfg_used) { -+ lsms->fw_cfg = loongarch_fw_cfg_init(ram_size, lsms); -+ rom_set_fw(lsms->fw_cfg); -+ fw_conf_init(ram_size); -+ rom_add_blob_fixed("fw_conf", (void *)&fw_config, -+ sizeof(fw_config), FW_CONF_ADDR); -+ -+ if (kernel_filename) { -+ fw_cfg_add_kernel_info(lsms->fw_cfg, highram_size, phyAddr_initrd); -+ } -+ } -+ -+ if (lsms->fw_cfg != NULL) { -+ fw_cfg_add_file(lsms->fw_cfg, "etc/memmap", -+ la_memmap_table, -+ sizeof(struct la_memmap_entry) * (la_memmap_entries)); -+ } -+ -+ return ; -+} -+static void create_fdt(LoongarchMachineState *lsms) -+{ -+ lsms->fdt = create_device_tree(&lsms->fdt_size); -+ if (!lsms->fdt) { -+ error_report("create_device_tree() failed"); -+ exit(1); -+ } -+ -+ /* Header */ -+ qemu_fdt_setprop_string(lsms->fdt, "/", "compatible", -+ "linux,dummy-loongson3"); -+ qemu_fdt_setprop_cell(lsms->fdt, "/", "#address-cells", 0x2); -+ qemu_fdt_setprop_cell(lsms->fdt, "/", "#size-cells", 0x2); -+} -+ -+static void fdt_add_cpu_nodes(const LoongarchMachineState *lsms) -+{ -+ int num; -+ const MachineState *ms = MACHINE(lsms); -+ int smp_cpus = ms->smp.cpus; -+ -+ qemu_fdt_add_subnode(lsms->fdt, "/cpus"); -+ qemu_fdt_setprop_cell(lsms->fdt, "/cpus", "#address-cells", 0x1); -+ qemu_fdt_setprop_cell(lsms->fdt, "/cpus", "#size-cells", 0x0); -+ -+ /* cpu nodes */ -+ for (num = smp_cpus - 1; num >= 0; num--) { -+ char *nodename = g_strdup_printf("/cpus/cpu@%d", num); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(qemu_get_cpu(num)); -+ -+ qemu_fdt_add_subnode(lsms->fdt, nodename); -+ qemu_fdt_setprop_string(lsms->fdt, nodename, "device_type", "cpu"); -+ qemu_fdt_setprop_string(lsms->fdt, nodename, "compatible", -+ cpu->dtb_compatible); -+ qemu_fdt_setprop_cell(lsms->fdt, nodename, "reg", num); -+ qemu_fdt_setprop_cell(lsms->fdt, nodename, "phandle", -+ qemu_fdt_alloc_phandle(lsms->fdt)); -+ g_free(nodename); -+ } -+ -+ /*cpu map */ -+ qemu_fdt_add_subnode(lsms->fdt, "/cpus/cpu-map"); -+ -+ for (num = smp_cpus - 1; num >= 0; num--) { -+ char *cpu_path = g_strdup_printf("/cpus/cpu@%d", num); -+ char *map_path; -+ -+ if (ms->smp.threads > 1) { -+ map_path = g_strdup_printf( -+ "/cpus/cpu-map/socket%d/core%d/thread%d", -+ num / (ms->smp.cores * ms->smp.threads), -+ (num / ms->smp.threads) % ms->smp.cores, -+ num % ms->smp.threads); -+ } else { -+ map_path = g_strdup_printf( -+ "/cpus/cpu-map/socket%d/core%d", -+ num / ms->smp.cores, -+ num % ms->smp.cores); -+ } -+ qemu_fdt_add_path(lsms->fdt, map_path); -+ qemu_fdt_setprop_phandle(lsms->fdt, map_path, "cpu", cpu_path); -+ -+ g_free(map_path); -+ g_free(cpu_path); -+ } -+} -+ -+static void fdt_add_fw_cfg_node(const LoongarchMachineState *lsms) -+{ -+ char *nodename; -+ hwaddr base = FW_CFG_ADDR; -+ -+ nodename = g_strdup_printf("/fw_cfg@%" PRIx64, base); -+ qemu_fdt_add_subnode(lsms->fdt, nodename); -+ qemu_fdt_setprop_string(lsms->fdt, nodename, -+ "compatible", "qemu,fw-cfg-mmio"); -+ qemu_fdt_setprop_sized_cells(lsms->fdt, nodename, "reg", -+ 2, base, 2, 0x8); -+ qemu_fdt_setprop(lsms->fdt, nodename, "dma-coherent", NULL, 0); -+ g_free(nodename); -+} -+ -+static void fdt_add_pcie_node(const LoongarchMachineState *lsms) -+{ -+ char *nodename; -+ hwaddr base_mmio = LS_ISA_MEM_BASE; -+ hwaddr size_mmio = LS_ISA_MEM_SIZE; -+ hwaddr base_pio = LS3A5K_ISA_IO_BASE; -+ hwaddr size_pio = LS_ISA_IO_SIZE; -+ hwaddr base_pcie = LS_PCIECFG_BASE; -+ hwaddr size_pcie = LS_PCIECFG_SIZE; -+ hwaddr base = base_pcie; -+ -+ nodename = g_strdup_printf("/pcie@%" PRIx64, base); -+ qemu_fdt_add_subnode(lsms->fdt, nodename); -+ qemu_fdt_setprop_string(lsms->fdt, nodename, -+ "compatible", "pci-host-ecam-generic"); -+ qemu_fdt_setprop_string(lsms->fdt, nodename, "device_type", "pci"); -+ qemu_fdt_setprop_cell(lsms->fdt, nodename, "#address-cells", 3); -+ qemu_fdt_setprop_cell(lsms->fdt, nodename, "#size-cells", 2); -+ qemu_fdt_setprop_cell(lsms->fdt, nodename, "linux,pci-domain", 0); -+ qemu_fdt_setprop_cells(lsms->fdt, nodename, "bus-range", 0, -+ PCIE_MMCFG_BUS(LS_PCIECFG_SIZE - 1)); -+ qemu_fdt_setprop(lsms->fdt, nodename, "dma-coherent", NULL, 0); -+ qemu_fdt_setprop_sized_cells(lsms->fdt, nodename, "reg", -+ 2, base_pcie, 2, size_pcie); -+ qemu_fdt_setprop_sized_cells(lsms->fdt, nodename, "ranges", -+ 1, FDT_PCI_RANGE_IOPORT, 2, 0, -+ 2, base_pio, 2, size_pio, -+ 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, -+ 2, base_mmio, 2, size_mmio); -+ g_free(nodename); -+ qemu_fdt_dumpdtb(lsms->fdt, lsms->fdt_size); -+} -+ -+static void ls3a5k_init(MachineState *args) -+{ -+ int i; -+ const char *cpu_model = args->cpu_type; -+ const char *kernel_filename = args->kernel_filename; -+ const char *kernel_cmdline = args->kernel_cmdline; -+ const char *initrd_filename = args->initrd_filename; -+ -+ ram_addr_t ram_size = args->ram_size; -+ MemoryRegion *address_space_mem = get_system_memory(); -+ ram_addr_t offset = 0; -+ MemoryRegion *isa_io = g_new(MemoryRegion, 1); -+ MemoryRegion *isa_mem = g_new(MemoryRegion, 1); -+ MachineState *machine = args; -+ MachineClass *mc = MACHINE_GET_CLASS(machine); -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ int smp_cpus = machine->smp.cpus; -+ int nb_numa_nodes = machine->numa_state->num_nodes; -+ NodeInfo *numa_info = machine->numa_state->nodes; -+ LOONGARCHCPU *cpu; -+ CPULOONGARCHState *env; -+ qemu_irq *ls7a_apic = NULL; -+ qemu_irq *pirq = NULL; -+ PCIBus *pci_bus = NULL; -+ char *ramName = NULL; -+ uint64_t lowram_size = 0, highram_size = 0, phyAddr = 0, -+ memmap_size = 0, highram_end_addr = 0; -+ -+ CPUArchIdList *possible_cpus; -+ if (strstr(lsmc->cpu_name, "5000")) { -+ if (strcmp(cpu_model, LOONGARCH_CPU_TYPE_NAME("Loongson-3A5000")) && -+ strcmp(cpu_model, LOONGARCH_CPU_TYPE_NAME("host"))) { -+ error_report("machine type %s does not match cpu type %s", -+ lsmc->cpu_name, cpu_model); -+ exit(1); -+ } -+ if (kvm_enabled()) { -+ kvm_vm_ioctl(kvm_state, KVM_LARCH_SET_CPUCFG, ls3a5k_cpucfgs); -+ } -+ } -+ -+ create_fdt(lsms); -+ -+ DPRINTF("isa 0x%lx\n", lsmc->isa_io_base); -+ DPRINTF("ht1lo 0x%lx\n", lsmc->ht1lo_pcicfg_base); -+ DPRINTF("cpu_name %s bridge_name %s\n", -+ lsmc->cpu_name, lsmc->bridge_name); -+ -+ /* init CPUs */ -+ mc->possible_cpu_arch_ids(machine); -+ possible_cpus = machine->possible_cpus; -+ -+ for (i = 0; i < smp_cpus; i++) { -+ Object *obj = NULL; -+ Error *local_err = NULL; -+ -+ obj = object_new(possible_cpus->cpus[i].type); -+ -+ object_property_set_uint(obj, "id", possible_cpus->cpus[i].arch_id, -+ &local_err); -+ object_property_set_bool(obj, "realized", true, &local_err); -+ -+ object_unref(obj); -+ error_propagate(&error_fatal, local_err); -+ -+ cpu = LOONGARCH_CPU(CPU(obj)); -+ if (cpu == NULL) { -+ fprintf(stderr, "Unable to find CPU definition\n"); -+ exit(1); -+ } -+ -+ env = &cpu->env; -+ cpu_states[i] = env; -+ env->CSR_TMID |= i; -+ -+ lsms->reset_info[i] = g_malloc0(sizeof(ResetData)); -+ lsms->reset_info[i]->cpu = cpu; -+ lsms->reset_info[i]->vector = env->active_tc.PC; -+ if (i == 0) { -+ qemu_register_reset(main_cpu_reset, lsms->reset_info[i]); -+ } else { -+ qemu_register_reset(slave_cpu_reset, lsms->reset_info[i]); -+ } -+ -+ /* Init CPU internal devices */ -+ cpu_init_irq(cpu); -+ cpu_loongarch_clock_init(cpu); -+ cpu_init_ipi(lsms, env->irq[12], i); -+ cpu_init_apic(lsms, env, i); -+ } -+ -+ lsms->hotpluged_cpu_num = 0; -+ fdt_add_cpu_nodes(lsms); -+ env = cpu_states[0]; -+ -+ /* node0 mem*/ -+ phyAddr = (uint64_t)0; -+ MemoryRegion *lowmem = g_new(MemoryRegion, 1); -+ ramName = g_strdup_printf("loongarch_ls3a.node%d.lowram", 0); -+ -+ lowram_size = MIN(ram_size, 256 * 0x100000); -+ memory_region_init_alias(lowmem, NULL, ramName, machine->ram, 0, lowram_size); -+ memory_region_add_subregion(address_space_mem, phyAddr, lowmem); -+ -+ offset += lowram_size; -+ if (nb_numa_nodes > 0) { -+ highram_size = numa_info[0].node_mem - S_256MiB; -+ if (numa_info[0].node_mem > S_1GiB) { -+ memmap_size = numa_info[0].node_mem - S_1GiB; -+ la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); -+ } -+ } else { -+ highram_size = ram_size - S_256MiB; -+ if (ram_size > S_1GiB) { -+ memmap_size = ram_size - S_1GiB; -+ la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); -+ } -+ } -+ -+ phyAddr = (uint64_t)0x90000000; -+ MemoryRegion *highmem = g_new(MemoryRegion, 1); -+ ramName = g_strdup_printf("loongarch_ls3a.node%d.highram", 0); -+ memory_region_init_alias(highmem, NULL, ramName, -+ machine->ram, offset, highram_size); -+ memory_region_add_subregion(address_space_mem, -+ phyAddr, highmem); -+ offset += highram_size; -+ phyAddr += highram_size; -+ -+ /* initrd address use high mem from high to low */ -+ highram_end_addr = phyAddr; -+ /* node1~ nodemax */ -+ for (i = 1; i < nb_numa_nodes; i++) { -+ MemoryRegion *nodemem = g_new(MemoryRegion, 1); -+ ramName = g_strdup_printf("loongarch_ls3a.node%d.ram", i); -+ memory_region_init_alias(nodemem, NULL, ramName, -+ machine->ram, offset, numa_info[i].node_mem); -+ memory_region_add_subregion(address_space_mem, -+ phyAddr, nodemem); -+ la_memmap_add_entry(phyAddr, numa_info[i].node_mem, SYSTEM_RAM); -+ offset += numa_info[i].node_mem; -+ phyAddr += numa_info[i].node_mem; -+ } -+ -+ fdt_add_fw_cfg_node(lsms); -+ ls3a5k_bios_init(lsms, ram_size, highram_size, highram_end_addr, -+ kernel_filename, kernel_cmdline, initrd_filename); -+ -+ lsms->machine_done.notify = loongarch_machine_done; -+ qemu_add_machine_init_done_notifier(&lsms->machine_done); -+ /*vmstate_register_ram_global(bios);*/ -+ -+ /* initialize hotplug memory address space */ -+ lsms->hotplug_memory_size = 0; -+ -+ /* always allocate the device memory information */ -+ machine->device_memory = g_malloc0(sizeof(*machine->device_memory)); -+ if (machine->ram_size < machine->maxram_size) { -+ int max_memslots; -+ -+ lsms->hotplug_memory_size = machine->maxram_size - machine->ram_size; -+ /* -+ * Limit the number of hotpluggable memory slots to half the number -+ * slots that KVM supports, leaving the other half for PCI and other -+ * devices. However ensure that number of slots doesn't drop below 32. -+ */ -+ max_memslots = LOONGARCH_MAX_RAM_SLOTS; -+ if (kvm_enabled()) { -+ max_memslots = kvm_get_max_memslots() / 2 ; -+ } -+ -+ if (machine->ram_slots == 0) -+ machine->ram_slots = lsms->hotplug_memory_size / -+ LOONGARCH_HOTPLUG_MEM_ALIGN; -+ -+ if (machine->ram_slots > max_memslots) { -+ error_report("Specified number of memory slots %" -+ PRIu64" exceeds max supported %d", -+ machine->ram_slots, max_memslots); -+ exit(1); -+ } -+ -+ lsms->ram_slots = machine->ram_slots; -+ -+ machine->device_memory->base = get_hotplug_membase(machine->ram_size); -+ memory_region_init(&machine->device_memory->mr, OBJECT(lsms), -+ "device-memory", lsms->hotplug_memory_size); -+ memory_region_add_subregion(get_system_memory(), -+ machine->device_memory->base, -+ &machine->device_memory->mr); -+ } -+ -+ memory_region_init_alias(isa_io, NULL, "isa-io", -+ get_system_io(), 0, LS_ISA_IO_SIZE); -+ memory_region_init(isa_mem, NULL, "isa-mem", LS_ISA_MEM_SIZE); -+ memory_region_add_subregion(get_system_memory(), lsmc->isa_io_base, isa_io); -+ memory_region_add_subregion(get_system_memory(), LS_ISA_MEM_BASE, isa_mem); -+ -+ if (!strcmp(lsmc->bridge_name, "ls7a")) { -+ /*Initialize the 7A IO interrupt subsystem*/ -+ DeviceState *ls7a_dev; -+ lsms->apic_xrupt_override = kvm_irqchip_in_kernel(); -+ ls7a_apic = ls3a_intctl_init(machine, cpu_states); -+ if (!ls7a_apic) { -+ perror("Init 7A APIC failed\n"); -+ exit(1); -+ } -+ pci_bus = ls7a_init(machine, ls7a_apic, &ls7a_dev); -+ -+ object_property_add_link(OBJECT(machine), -+ LOONGARCH_MACHINE_ACPI_DEVICE_PROP, -+ TYPE_HOTPLUG_HANDLER, -+ (Object **)&lsms->acpi_dev, -+ object_property_allow_set_link, -+ OBJ_PROP_LINK_STRONG); -+ object_property_set_link(OBJECT(machine), LOONGARCH_MACHINE_ACPI_DEVICE_PROP, -+ OBJECT(ls7a_dev), &error_abort); -+ -+#ifdef CONFIG_KVM -+ if (kvm_enabled()) { -+ kvm_direct_msi_allowed = (kvm_check_extension(kvm_state, -+ KVM_CAP_SIGNAL_MSI) > 0); -+ } else { -+ kvm_direct_msi_allowed = 0; -+ } -+ msi_nonbroken = kvm_direct_msi_allowed; -+#else -+ msi_nonbroken = true; -+#endif -+ sysbus_create_simple("ls7a_rtc", LS7A_RTC_REG_BASE, -+ ls7a_apic[LS7A_RTC_IRQ - LOONGARCH_PCH_IRQ_BASE]); -+ } -+ -+ /*Initialize the CPU serial device*/ -+ -+ if (serial_hd(0)) { -+ pirq = qemu_allocate_irqs(legacy_set_irq, ls7a_apic + -+ (LS7A_UART_IRQ - LOONGARCH_PCH_IRQ_BASE), 1); -+ serial_mm_init(address_space_mem, LS7A_UART_BASE, 0, pirq[0], -+ 115200, serial_hd(0), DEVICE_NATIVE_ENDIAN); -+ } -+ -+ /*network card*/ -+ network_init(pci_bus); -+ /* VGA setup. Don't bother loading the bios. */ -+ pci_vga_init(pci_bus); -+ -+ sysbus_realize_and_unref(SYS_BUS_DEVICE(qdev_new("iocsr")), &error_fatal); -+ -+#ifdef CONFIG_TCG -+ int nb_nodes = (smp_cpus - 1) / 4; -+ for (i = 0; i <= nb_nodes; i++) { -+ uint64_t off = (uint64_t)i << 44; -+ SIMPLE_OPS(((hwaddr)0x1fe00180 | off), 0x8); -+ SIMPLE_OPS(((hwaddr)0x1fe0019c | off), 0x8); -+ SIMPLE_OPS(((hwaddr)0x1fe001d0 | off), 0x8); -+ SIMPLE_OPS(((hwaddr)FEATURE_REG | off), 0x8); -+ SIMPLE_OPS(((hwaddr)VENDOR_REG | off), 0x8); -+ SIMPLE_OPS(((hwaddr)CPUNAME_REG | off), 0x8); -+ SIMPLE_OPS(((hwaddr)OTHER_FUNC_REG | off), 0x8); -+ } -+ -+ SIMPLE_OPS(0x1001041c, 0x4); -+ SIMPLE_OPS(0x10002000, 0x14); -+ SIMPLE_OPS(0x10013ffc, 0x4); -+#endif -+ -+ fdt_add_pcie_node(lsms); -+ -+ /* load fdt */ -+ MemoryRegion *fdt_rom = g_new(MemoryRegion, 1); -+ memory_region_init_rom(fdt_rom, NULL, "fdt", LS_FDT_SIZE, &error_fatal); -+ memory_region_add_subregion(get_system_memory(), LS_FDT_BASE, fdt_rom); -+ rom_add_blob_fixed("fdt", lsms->fdt, lsms->fdt_size, LS_FDT_BASE); -+} -+ -+static const CPUArchIdList *loongarch_possible_cpu_arch_ids(MachineState *ms) -+{ -+ int i; -+ int max_cpus = ms->smp.max_cpus; -+ -+ if (ms->possible_cpus) { -+ /* -+ * make sure that max_cpus hasn't changed since the first use, i.e. -+ * -smp hasn't been parsed after it -+ */ -+ assert(ms->possible_cpus->len == max_cpus); -+ return ms->possible_cpus; -+ } -+ -+ ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) + -+ sizeof(CPUArchId) * max_cpus); -+ ms->possible_cpus->len = max_cpus; -+ for (i = 0; i < ms->possible_cpus->len; i++) { -+ ms->possible_cpus->cpus[i].type = ms->cpu_type; -+ ms->possible_cpus->cpus[i].vcpus_count = 1; -+ ms->possible_cpus->cpus[i].props.has_core_id = true; -+ ms->possible_cpus->cpus[i].props.core_id = i; -+ ms->possible_cpus->cpus[i].arch_id = i; -+ } -+ return ms->possible_cpus; -+ -+} -+ -+static PFlashCFI01 *loongarch_pflash_create(LoongarchMachineState *lsms, -+ const char *name, -+ const char *alias_prop_name) -+{ -+ DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01); -+ -+ qdev_prop_set_uint64(dev, "sector-length", FLASH_SECTOR_SIZE); -+ qdev_prop_set_uint8(dev, "width", 1); -+ qdev_prop_set_string(dev, "name", name); -+ object_property_add_child(OBJECT(lsms), name, OBJECT(dev)); -+ object_property_add_alias(OBJECT(lsms), alias_prop_name, -+ OBJECT(dev), "drive"); -+ return PFLASH_CFI01(dev); -+} -+ -+ -+static void loongarch_system_flash_create(LoongarchMachineState *lsms) -+{ -+ lsms->flash[0] = loongarch_pflash_create(lsms, "system.flash0", -+ "pflash0"); -+ lsms->flash[1] = loongarch_pflash_create(lsms, "system.flash1", -+ "pflash1"); -+} -+ -+static void loongarch_machine_initfn(Object *obj) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(obj); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ lsms->acpi_build_enabled = lsmc->has_acpi_build; -+ loongarch_system_flash_create(lsms); -+ lsms->oem_id = g_strndup(EFI_ACPI_OEM_ID, 6); -+ lsms->oem_table_id = g_strndup(EFI_ACPI_OEM_TABLE_ID, 6); -+} -+ -+static void ls3a5k_ls7a_machine_options(MachineClass *m) -+{ -+ char *cpu_name = get_host_cpu_model_name(); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_CLASS(m); -+ m->desc = "Loongarch3a5k LS7A1000 machine"; -+ m->max_cpus = LOONGARCH_MAX_VCPUS; -+ m->alias = "loongson7a"; -+ m->is_default = 1; -+ lsmc->isa_io_base = LS3A5K_ISA_IO_BASE; -+ lsmc->ht1lo_pcicfg_base = LS3A5K_HT1LO_PCICFG_BASE; -+ lsmc->pciecfg_base = LS_PCIECFG_BASE; -+ lsmc->ls7a_ioapic_reg_base = LS3A5K_LS7A_IOAPIC_REG_BASE; -+ lsmc->node_shift = 44; -+ strncpy(lsmc->cpu_name, cpu_name, sizeof(lsmc->cpu_name) - 1); -+ lsmc->cpu_name[sizeof(lsmc->cpu_name) - 1] = 0; -+ strncpy(lsmc->bridge_name, "ls7a", sizeof(lsmc->bridge_name) - 1); -+ lsmc->bridge_name[sizeof(lsmc->bridge_name) - 1] = 0; -+ compat_props_add(m->compat_props, loongarch_compat, loongarch_compat_len); -+} -+ -+static void ls3a_board_reset(MachineState *ms) -+{ -+ qemu_devices_reset(); -+#ifdef CONFIG_KVM -+ struct loongarch_kvm_irqchip *chip; -+ int length; -+ -+ if (!kvm_enabled()) { -+ return; -+ } -+ length = sizeof(struct loongarch_kvm_irqchip) + -+ sizeof(struct loongarch_gipiState); -+ chip = g_malloc0(length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS3A_GIPI; -+ chip->len = length; -+ kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); -+ -+ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct ls7a_ioapic_state); -+ chip = g_realloc(chip, length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS7A_IOAPIC; -+ chip->len = length; -+ kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); -+ -+ g_free(chip); -+#endif -+} -+ -+static CpuInstanceProperties ls3a_cpu_index_to_props(MachineState *ms, unsigned cpu_index) -+{ -+ MachineClass *mc = MACHINE_GET_CLASS(ms); -+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); -+ -+ assert(cpu_index < possible_cpus->len); -+ return possible_cpus->cpus[cpu_index].props; -+} -+ -+static int64_t ls3a_get_default_cpu_node_id(const MachineState *ms, int idx) -+{ -+ int nb_numa_nodes = ms->numa_state->num_nodes; -+ int smp_cores = ms->smp.cores; -+ return idx / smp_cores % nb_numa_nodes; -+} -+ -+static void loongarch_class_init(ObjectClass *oc, void *data) -+{ -+ MachineClass *mc = MACHINE_CLASS(oc); -+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_CLASS(oc); -+ -+ lsmc->get_hotplug_handler = mc->get_hotplug_handler; -+ lsmc->has_acpi_build = true; -+ mc->get_hotplug_handler = loongarch_get_hotpug_handler; -+ mc->has_hotpluggable_cpus = true; -+ mc->cpu_index_to_instance_props = ls3a_cpu_index_to_props; -+ mc->possible_cpu_arch_ids = loongarch_possible_cpu_arch_ids; -+ mc->get_default_cpu_node_id = ls3a_get_default_cpu_node_id; -+ mc->default_ram_size = 1 * GiB; -+ mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("Loongson-3A5000"); -+ mc->default_ram_id = "loongarch_ls3a.ram"; -+ -+ mc->reset = ls3a_board_reset; -+ mc->max_cpus = LOONGARCH_MAX_VCPUS; -+ hc->pre_plug = loongarch_machine_device_pre_plug; -+ hc->plug = loongarch_machine_device_plug; -+ hc->unplug = longson_machine_device_unplug; -+ hc->unplug_request = loongarch_machine_device_unplug_request; -+ -+ object_class_property_add(oc, "acpi", "OnOffAuto", -+ loongarch_get_acpi, loongarch_set_acpi, -+ NULL, NULL); -+ object_class_property_set_description(oc, "acpi", -+ "Enable ACPI"); -+} -+ -+static const TypeInfo loongarch_info = { -+ .name = TYPE_LOONGARCH_MACHINE, -+ .parent = TYPE_MACHINE, -+ .abstract = true, -+ .instance_size = sizeof(LoongarchMachineState), -+ .instance_init = loongarch_machine_initfn, -+ .class_size = sizeof(LoongarchMachineClass), -+ .class_init = loongarch_class_init, -+ .interfaces = (InterfaceInfo[]) { -+ { TYPE_HOTPLUG_HANDLER }, -+ { } -+ }, -+ -+}; -+ -+static void loongarch_machine_register_types(void) -+{ -+ type_register_static(&loongarch_info); -+} -+ -+type_init(loongarch_machine_register_types) -+ -+DEFINE_LS3A5K_MACHINE(loongson7a_v1_0, "loongson7a_v1.0", -+ ls3a5k_ls7a_machine_options); -diff --git a/hw/loongarch/larch_hotplug.c b/hw/loongarch/larch_hotplug.c -new file mode 100644 -index 000000000..7bce95712 ---- /dev/null -+++ b/hw/loongarch/larch_hotplug.c -@@ -0,0 +1,355 @@ -+/* -+ * Hotplug emulation on Loongarch system. -+ * -+ * Copyright (c) 2018 Loongarch Inc. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include "qemu-common.h" -+#include "qemu/queue.h" -+#include "qemu/units.h" -+#include "qemu/cutils.h" -+#include "qemu/bcd.h" -+#include "hw/hotplug.h" -+#include "hw/loongarch/cpudevs.h" -+#include "hw/mem/memory-device.h" -+#include "sysemu/numa.h" -+#include "sysemu/cpus.h" -+#include "hw/loongarch/larch.h" -+#include "hw/cpu/core.h" -+#include "hw/nvram/fw_cfg.h" -+ -+/* find cpu slot in machine->possible_cpus by core_id */ -+static CPUArchId *loongarch_find_cpu_slot(MachineState *ms, uint32_t id, -+ int *idx) -+{ -+ int index = id; -+ -+ if (index >= ms->possible_cpus->len) { -+ return NULL; -+ } -+ if (idx) { -+ *idx = index; -+ } -+ return &ms->possible_cpus->cpus[index]; -+} -+ -+static void loongarch_memory_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ Error *local_err = NULL; -+ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); -+ HotplugHandlerClass *hhc; -+ uint64_t size; -+ -+ size = memory_device_get_region_size(MEMORY_DEVICE(dev), &error_abort); -+ if (size % LOONGARCH_HOTPLUG_MEM_ALIGN) { -+ error_setg(&local_err, "Hotplugged memory size must be a multiple of " -+ "%lld MB", LOONGARCH_HOTPLUG_MEM_ALIGN / MiB); -+ goto out; -+ } -+ -+ pc_dimm_plug(PC_DIMM(dev), MACHINE(lsms)); -+ -+ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); -+ hhc->plug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &error_abort); -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void loongarch_memory_unplug_request(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ Error *local_err = NULL; -+ HotplugHandlerClass *hhc; -+ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); -+ -+ if (!lsms->acpi_dev || !loongarch_is_acpi_enabled(lsms)) { -+ error_setg(&local_err, -+ "memory hotplug is not enabled: missing acpi device or acpi disabled"); -+ goto out; -+ } -+ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); -+ hhc->unplug_request(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); -+ -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void loongarch_cpu_unplug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ CPUArchId *found_cpu; -+ HotplugHandlerClass *hhc; -+ Error *local_err = NULL; -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); -+ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ -+ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); -+ hhc->unplug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); -+ -+ if (local_err) { -+ goto out; -+ } -+ -+ loongarch_cpu_destroy(machine, cpu); -+ -+ found_cpu = loongarch_find_cpu_slot(MACHINE(lsms), cpu->id, NULL); -+ found_cpu->cpu = NULL; -+ object_unparent(OBJECT(dev)); -+ lsms->hotpluged_cpu_num -= 1; -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void loongarch_memory_unplug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ Error *local_err = NULL; -+ HotplugHandlerClass *hhc; -+ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); -+ -+ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); -+ hhc->unplug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); -+ -+ if (local_err) { -+ goto out; -+ } -+ -+ pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev)); -+ object_unparent(OBJECT(dev)); -+ -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void loongarch_cpu_pre_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ MachineState *ms = MACHINE(OBJECT(hotplug_dev)); -+ MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev); -+ LoongarchMachineState *lsms = LoongarchMACHINE(ms); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); -+ CPUArchId *cpu_slot; -+ Error *local_err = NULL; -+ int index; -+ int free_index = lsms->hotpluged_cpu_num + ms->smp.cpus; -+ int max_cpus = ms->smp.max_cpus; -+ -+ if (dev->hotplugged && !mc->has_hotpluggable_cpus) { -+ error_setg(&local_err, "CPU hotplug not supported for this machine"); -+ goto out; -+ } -+ -+ if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { -+ error_setg(errp, "Invalid CPU type, expected cpu type: '%s'", -+ ms->cpu_type); -+ return; -+ } -+ -+ /* if ID is not set, set it based on core properties */ -+ if (cpu->id == UNASSIGNED_CPU_ID) { -+ if ((cpu->core_id) > (max_cpus - 1)) { -+ error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u", -+ cpu->core_id, max_cpus - 1); -+ return; -+ } -+ -+ if (free_index > (max_cpus - 1)) { -+ error_setg(errp, "The maximum number of CPUs cannot exceed %u.", -+ max_cpus); -+ return; -+ } -+ -+ if (cpu->core_id != free_index) { -+ error_setg(errp, "Invalid CPU core-id: %u must be :%u", -+ cpu->core_id, free_index); -+ return; -+ } -+ -+ cpu->id = cpu->core_id; -+ } -+ -+ cpu_slot = loongarch_find_cpu_slot(MACHINE(hotplug_dev), cpu->id, &index); -+ if (!cpu_slot) { -+ error_setg(&local_err, "core id %d out of range", cpu->id); -+ goto out; -+ } -+ -+ if (cpu_slot->cpu) { -+ error_setg(&local_err, "core %d already populated", cpu->id); -+ goto out; -+ } -+ -+ numa_cpu_pre_plug(cpu_slot, dev, &local_err); -+ -+ return ; -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void loongarch_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp) -+{ -+ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ PCDIMMDevice *dimm = PC_DIMM(dev); -+ Error *local_err = NULL; -+ uint64_t size; -+ -+ if (!lsms->acpi_dev || !loongarch_is_acpi_enabled(lsms)) { -+ error_setg(errp, -+ "memory hotplug is not enabled: missing acpi device or acpi disabled"); -+ return; -+ } -+ -+ size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &local_err); -+ if (local_err) { -+ error_propagate(errp, local_err); -+ return; -+ } -+ -+ if (size % LOONGARCH_HOTPLUG_MEM_ALIGN) { -+ error_setg(errp, "Hotplugged memory size must be a multiple of " -+ "%lld MB", LOONGARCH_HOTPLUG_MEM_ALIGN / MiB); -+ return; -+ } -+ -+ pc_dimm_pre_plug(dimm, MACHINE(hotplug_dev), NULL, errp); -+} -+ -+static void loongarch_cpu_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ CPUArchId *found_cpu; -+ HotplugHandlerClass *hhc; -+ Error *local_err = NULL; -+ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); -+ -+ if (lsms->acpi_dev) { -+ loongarch_cpu_create(machine, cpu, errp); -+ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); -+ hhc->plug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ } -+ -+ found_cpu = loongarch_find_cpu_slot(MACHINE(lsms), cpu->id, NULL); -+ found_cpu->cpu = OBJECT(dev); -+ lsms->hotpluged_cpu_num += 1; -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void loongarch_cpu_unplug_request(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); -+ Error *local_err = NULL; -+ HotplugHandlerClass *hhc; -+ int idx = -1; -+ -+ if (!lsms->acpi_dev) { -+ error_setg(&local_err, "CPU hot unplug not supported without ACPI"); -+ goto out; -+ } -+ -+ loongarch_find_cpu_slot(MACHINE(lsms), cpu->id, &idx); -+ assert(idx != -1); -+ if (idx == 0) { -+ error_setg(&local_err, "Boot CPU is unpluggable"); -+ goto out; -+ } -+ -+ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); -+ hhc->unplug_request(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); -+ -+ if (local_err) { -+ goto out; -+ } -+ -+ out: -+ error_propagate(errp, local_err); -+} -+ -+void longson_machine_device_unplug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); -+ -+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ loongarch_memory_unplug(hotplug_dev, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { -+ if (!mc->has_hotpluggable_cpus) { -+ error_setg(errp, "CPU hot unplug not supported on this machine"); -+ return; -+ } -+ loongarch_cpu_unplug(hotplug_dev, dev, errp); -+ } else { -+ error_setg(errp, "acpi: device unplug for not supported device" -+ " type: %s", object_get_typename(OBJECT(dev))); -+ } -+ -+ return; -+} -+ -+void loongarch_machine_device_unplug_request(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ loongarch_memory_unplug_request(hotplug_dev, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { -+ loongarch_cpu_unplug_request(hotplug_dev, dev, errp); -+ } -+} -+ -+HotplugHandler *loongarch_get_hotpug_handler(MachineState *machine, -+ DeviceState *dev) -+{ -+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || -+ object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { -+ return HOTPLUG_HANDLER(machine); -+ } -+ return NULL; -+} -+ -+void loongarch_machine_device_pre_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ loongarch_memory_pre_plug(hotplug_dev, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { -+ loongarch_cpu_pre_plug(hotplug_dev, dev, errp); -+ } -+} -+ -+void loongarch_machine_device_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ loongarch_memory_plug(hotplug_dev, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { -+ loongarch_cpu_plug(hotplug_dev, dev, errp); -+ } -+} -+ -diff --git a/hw/loongarch/larch_int.c b/hw/loongarch/larch_int.c -new file mode 100644 -index 000000000..ca073a19c ---- /dev/null -+++ b/hw/loongarch/larch_int.c -@@ -0,0 +1,91 @@ -+/* -+ * QEMU LOONGARCH interrupt support -+ * -+ * 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/main-loop.h" -+#include "hw/hw.h" -+#include "hw/irq.h" -+#include "hw/loongarch/cpudevs.h" -+#include "cpu.h" -+#include "sysemu/kvm.h" -+#include "kvm_larch.h" -+#ifdef CONFIG_KVM -+#include -+#endif -+ -+static void cpu_irq_request(void *opaque, int irq, int level) -+{ -+ LOONGARCHCPU *cpu = opaque; -+ CPULOONGARCHState *env = &cpu->env; -+ CPUState *cs = CPU(cpu); -+ bool locked = false; -+ -+ if (irq < 0 || irq > 13) { -+ return; -+ } -+ -+ /* Make sure locking works even if BQL is already held by the caller */ -+ if (!qemu_mutex_iothread_locked()) { -+ locked = true; -+ qemu_mutex_lock_iothread(); -+ } -+ -+ if (level) { -+ env->CSR_ESTAT |= 1 << irq; -+ } else { -+ env->CSR_ESTAT &= ~(1 << irq); -+ } -+ -+ if (kvm_enabled()) { -+ if (irq == 2) { -+ kvm_loongarch_set_interrupt(cpu, irq, level); -+ } else if (irq == 3) { -+ kvm_loongarch_set_interrupt(cpu, irq, level); -+ } else if (irq == 12) { -+ kvm_loongarch_set_ipi_interrupt(cpu, irq, level); -+ } -+ } -+ -+ if (env->CSR_ESTAT & CSR_ESTAT_IPMASK) { -+ cpu_interrupt(cs, CPU_INTERRUPT_HARD); -+ } else { -+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); -+ } -+ -+ if (locked) { -+ qemu_mutex_unlock_iothread(); -+ } -+} -+ -+void cpu_init_irq(LOONGARCHCPU *cpu) -+{ -+ CPULOONGARCHState *env = &cpu->env; -+ qemu_irq *qi; -+ int i; -+ -+ qi = qemu_allocate_irqs(cpu_irq_request, loongarch_env_get_cpu(env), N_IRQS); -+ for (i = 0; i < N_IRQS; i++) { -+ env->irq[i] = qi[i]; -+ } -+} -+ -+ -diff --git a/hw/loongarch/ls7a_nb.c b/hw/loongarch/ls7a_nb.c -new file mode 100644 -index 000000000..5a500fbd5 ---- /dev/null -+++ b/hw/loongarch/ls7a_nb.c -@@ -0,0 +1,352 @@ -+/* -+ * Loongarch 7A1000 north bridge support -+ * -+ * Copyright (c) 2019 Loongarch Technology -+ * Authors: -+ * Zhu Chen -+ * -+ * 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 "hw/hw.h" -+#include "hw/irq.h" -+#include "hw/sysbus.h" -+#include "hw/pci/pci.h" -+#include "hw/i386/pc.h" -+#include "hw/pci/pci_host.h" -+#include "hw/pci/pcie_host.h" -+#include "sysemu/sysemu.h" -+#include "exec/address-spaces.h" -+#include "qapi/error.h" -+#include "hw/loongarch/cpudevs.h" -+#include "hw/acpi/ls7a.h" -+#include "hw/i386/pc.h" -+#include "hw/isa/isa.h" -+#include "hw/boards.h" -+#include "qemu/log.h" -+#include "hw/loongarch/bios.h" -+#include "hw/loader.h" -+#include "elf.h" -+#include "exec/address-spaces.h" -+#include "exec/memory.h" -+#include "hw/pci/pci_bridge.h" -+#include "hw/pci/pci_bus.h" -+#include "linux/kvm.h" -+#include "sysemu/kvm.h" -+#include "sysemu/runstate.h" -+#include "sysemu/reset.h" -+#include "migration/vmstate.h" -+#include "hw/loongarch/larch.h" -+#include "hw/loongarch/ls7a.h" -+ -+#undef DEBUG_LS7A -+ -+#ifdef DEBUG_LS7A -+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) -+#else -+#define DPRINTF(fmt, ...) -+#endif -+ -+static void ls7a_reset(void *opaque) -+{ -+ uint64_t wmask; -+ wmask = ~(-1); -+ -+ PCIDevice *dev = opaque; -+ pci_set_word(dev->config + PCI_VENDOR_ID, 0x0014); -+ pci_set_word(dev->wmask + PCI_VENDOR_ID, wmask & 0xffff); -+ pci_set_word(dev->cmask + PCI_VENDOR_ID, 0xffff); -+ pci_set_word(dev->config + PCI_DEVICE_ID, 0x7a00); -+ pci_set_word(dev->wmask + PCI_DEVICE_ID, wmask & 0xffff); -+ pci_set_word(dev->cmask + PCI_DEVICE_ID, 0xffff); -+ pci_set_word(dev->config + 0x4, 0x0000); -+ pci_set_word(dev->config + PCI_STATUS, 0x0010); -+ pci_set_word(dev->wmask + PCI_STATUS, wmask & 0xffff); -+ pci_set_word(dev->cmask + PCI_STATUS, 0xffff); -+ pci_set_byte(dev->config + PCI_REVISION_ID, 0x0); -+ pci_set_byte(dev->wmask + PCI_REVISION_ID, wmask & 0xff); -+ pci_set_byte(dev->cmask + PCI_REVISION_ID, 0xff); -+ pci_set_byte(dev->config + 0x9, 0x00); -+ pci_set_byte(dev->wmask + 0x9, wmask & 0xff); -+ pci_set_byte(dev->cmask + 0x9, 0xff); -+ pci_set_byte(dev->config + 0xa, 0x00); -+ pci_set_byte(dev->wmask + 0xa, wmask & 0xff); -+ pci_set_byte(dev->cmask + 0xa, 0xff); -+ pci_set_byte(dev->config + 0xb, 0x06); -+ pci_set_byte(dev->wmask + 0xb, wmask & 0xff); -+ pci_set_byte(dev->cmask + 0xb, 0xff); -+ pci_set_byte(dev->config + 0xc, 0x00); -+ pci_set_byte(dev->wmask + 0xc, wmask & 0xff); -+ pci_set_byte(dev->cmask + 0xc, 0xff); -+ pci_set_byte(dev->config + 0xe, 0x80); -+ pci_set_byte(dev->wmask + 0xe, wmask & 0xff); -+ pci_set_byte(dev->cmask + 0xe, 0xff); -+} -+ -+static const VMStateDescription vmstate_ls7a_pcie = { -+ .name = "LS7A_PCIE", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = (VMStateField[]) { -+ VMSTATE_PCI_DEVICE(dev, LS7APCIState), -+ VMSTATE_STRUCT(pm, LS7APCIState, 0, vmstate_ls7a_pm, LS7APCIPMRegs), -+ VMSTATE_UINT32_ARRAY(regs, LS7APCIState, LS7A_REGS), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+static PCIINTxRoute ls7a_route_intx_pin_to_irq(void *opaque, int pin) -+{ -+ PCIINTxRoute route; -+ -+ route.irq = pin; -+ route.mode = PCI_INTX_ENABLED; -+ return route; -+} -+ -+static int pci_ls7a_map_irq(PCIDevice *d, int irq_num) -+{ -+ int irq; -+ -+ irq = 16 + ((PCI_SLOT(d->devfn) * 4 + irq_num) & 0xf); -+ return irq; -+} -+ -+static void pci_ls7a_set_irq(void *opaque, int irq_num, int level) -+{ -+ qemu_irq *pic = opaque; -+ DPRINTF("------ %s irq %d %d\n", __func__, irq_num, level); -+ qemu_set_irq(pic[irq_num], level); -+} -+ -+/* -+static int ls7a_pciehost_initfn(SysBusDevice *dev) -+{ -+ return 0; -+}*/ -+ -+static void ls7a_pcie_realize(PCIDevice *dev, Error **errp) -+{ -+ LS7APCIState *s = PCIE_LS7A(dev); -+ /* Ls7a North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" */ -+ pci_config_set_prog_interface(dev->config, 0x00); -+ -+ /* set the default value of north bridge pci config */ -+ qemu_register_reset(ls7a_reset, s); -+} -+ -+static void pci_ls7a_config_write(void *opaque, hwaddr addr, -+ uint64_t val, unsigned size) -+{ -+ hwaddr tmp_addr; -+ tmp_addr = addr & 0xffffff; -+ -+ pci_data_write(opaque, tmp_addr, val, size); -+} -+ -+static uint64_t pci_ls7a_config_read(void *opaque, -+ hwaddr addr, unsigned size) -+{ -+ uint64_t val; -+ hwaddr tmp_addr; -+ -+ tmp_addr = addr & 0xffffff; -+ val = pci_data_read(opaque, tmp_addr, size); -+ -+ if (addr & 0x3c) { -+ DPRINTF(TARGET_FMT_plx" val %lx\n", addr, val); -+ } -+ return val; -+} -+ -+static const MemoryRegionOps pci_ls7a_config_ops = { -+ .read = pci_ls7a_config_read, -+ .write = pci_ls7a_config_write, -+ /* Set to access 64bits data, because default to 32bits*/ -+ .valid = { -+ .min_access_size = 1, -+ .max_access_size = 4, -+ }, -+ /* Set to access 64bits data, because default to 32bits*/ -+ .impl = { -+ .min_access_size = 1, -+ .max_access_size = 4, -+ }, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+ -+}; -+ -+static AddressSpace *ls7a_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) -+{ -+ return &address_space_memory; -+} -+ -+static PCIBus *pci_ls7a_init(MachineState *machine, DeviceState *dev, -+ qemu_irq *pic) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ PCIExpressHost *e; -+ SysBusDevice *sysbus; -+ MemoryRegion *iomem = g_new(MemoryRegion, 1); -+ PCIHostState *phb; -+ -+ e = PCIE_HOST_BRIDGE(dev); -+ sysbus = SYS_BUS_DEVICE(e); -+ phb = PCI_HOST_BRIDGE(e); -+ phb->bus = pci_register_root_bus(dev, "pcie.0", pci_ls7a_set_irq, -+ pci_ls7a_map_irq, pic, -+ get_system_memory(), get_system_io(), -+ (1 << 3), 128, TYPE_PCIE_BUS); -+ pcie_host_mmcfg_update(e, true, lsmc->pciecfg_base, LS_PCIECFG_SIZE); -+ DPRINTF("------ %d\n", __LINE__); -+ -+ pci_bus_set_route_irq_fn(phb->bus, ls7a_route_intx_pin_to_irq); -+ memory_region_init_io(iomem, NULL, &pci_ls7a_config_ops, phb->bus, -+ "ls7a_pci_conf", HT1LO_PCICFG_SIZE); -+ sysbus_init_mmio(sysbus, iomem); -+ sysbus_mmio_map(sysbus, 0, lsmc->ht1lo_pcicfg_base); -+ -+ return phb->bus; -+} -+ -+PCIBus *ls7a_init(MachineState *machine, qemu_irq *pic, DeviceState **ls7a_dev) -+{ -+ DeviceState *dev; -+ PCIHostState *phb; -+ LS7APCIState *pbs; -+ PCIDevice *pcid; -+ PCIBus *pci_bus; -+ PCIExpressHost *e; -+ -+ /*1. init the HT PCI CFG*/ -+ DPRINTF("------ %d\n", __LINE__); -+ dev = qdev_new(TYPE_LS7A_PCIE_HOST_BRIDGE); -+ e = PCIE_HOST_BRIDGE(dev); -+ phb = PCI_HOST_BRIDGE(e); -+ -+ DPRINTF("------ %d\n", __LINE__); -+ pci_bus = pci_ls7a_init(machine, dev, pic); -+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); -+ phb->bus = pci_bus; -+ /* set the pcihost pointer after rs780_pcihost_initfn is called */ -+ DPRINTF("------ %d\n", __LINE__); -+ pcid = pci_new(PCI_DEVFN(0, 0), TYPE_PCIE_LS7A); -+ pbs = PCIE_LS7A(pcid); -+ pbs->pciehost = LS7A_PCIE_HOST_BRIDGE(dev); -+ pbs->pciehost->pci_dev = pbs; -+ -+ if (ls7a_dev) { -+ *ls7a_dev = DEVICE(pcid); -+ } -+ -+ pci_realize_and_unref(pcid, phb->bus, &error_fatal); -+ -+ /* IOMMU */ -+ pci_setup_iommu(phb->bus, ls7a_pci_dma_iommu, NULL); -+ -+ ls7a_pm_init(&pbs->pm, pic); -+ DPRINTF("------ %d\n", __LINE__); -+ /*3. init the north bridge VGA,not do now*/ -+ return pci_bus; -+} -+ -+LS7APCIState *get_ls7a_type(Object *obj) -+{ -+ LS7APCIState *pbs; -+ -+ pbs = PCIE_LS7A(obj); -+ return pbs; -+} -+ -+static void ls7a_pcie_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); -+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); -+ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(klass); -+ -+ k->realize = ls7a_pcie_realize; -+ k->vendor_id = 0x0014; -+ k->device_id = 0x7a00; -+ k->revision = 0x00; -+ k->class_id = PCI_CLASS_BRIDGE_HOST; -+ dc->desc = "LS7A1000 PCIE Host bridge"; -+ dc->vmsd = &vmstate_ls7a_pcie; -+ /* -+ * PCI-facing part of the host bridge, not usable without the -+ * host-facing part, which can't be device_add'ed, yet. -+ */ -+ dc->user_creatable = false; -+ hc->plug = ls7a_pm_device_plug_cb; -+ hc->unplug_request = ls7a_pm_device_unplug_request_cb; -+ hc->unplug = ls7a_pm_device_unplug_cb; -+ adevc->ospm_status = ls7a_pm_ospm_status; -+ adevc->send_event = ls7a_send_gpe; -+ adevc->madt_cpu = ls7a_madt_cpu_entry; -+} -+ -+static void ls7a_pci_add_properties(LS7APCIState *ls7a) -+{ -+ ls7a_pm_add_properties(OBJECT(ls7a), &ls7a->pm, NULL); -+} -+ -+static void ls7a_pci_initfn(Object *obj) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(obj); -+ -+ ls7a_pci_add_properties(ls7a); -+} -+ -+static const TypeInfo ls7a_pcie_device_info = { -+ .name = TYPE_PCIE_LS7A, -+ .parent = TYPE_PCI_DEVICE, -+ .instance_size = sizeof(LS7APCIState), -+ .class_init = ls7a_pcie_class_init, -+ .instance_init = ls7a_pci_initfn, -+ .interfaces = (InterfaceInfo[]) { -+ { TYPE_HOTPLUG_HANDLER }, -+ { TYPE_ACPI_DEVICE_IF }, -+ { INTERFACE_CONVENTIONAL_PCI_DEVICE }, -+ { }, -+ }, -+}; -+ -+static void ls7a_pciehost_class_init(ObjectClass *klass, void *data) -+{ -+ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); -+ k->parent_class.fw_name = "pci"; -+} -+ -+static const TypeInfo ls7a_pciehost_info = { -+ .name = TYPE_LS7A_PCIE_HOST_BRIDGE, -+ .parent = TYPE_PCIE_HOST_BRIDGE, -+ .instance_size = sizeof(LS7APCIEHost), -+ .class_init = ls7a_pciehost_class_init, -+}; -+ -+static void ls7a_register_types(void) -+{ -+ type_register_static(&ls7a_pciehost_info); -+ type_register_static(&ls7a_pcie_device_info); -+} -+ -+type_init(ls7a_register_types) -diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build -new file mode 100644 -index 000000000..81ee99a02 ---- /dev/null -+++ b/hw/loongarch/meson.build -@@ -0,0 +1,15 @@ -+loongarch_ss = ss.source_set() -+loongarch_ss.add(files('larch_3a.c'), fdt) -+loongarch_ss.add(files( -+ 'larch_int.c', -+ 'larch_hotplug.c', -+ 'ls7a_nb.c', -+ 'ioapic.c', -+ 'acpi-build.c', -+ 'ipi.c', -+ 'apic.c', -+ 'iocsr.c', -+)) -+ -+hw_arch += {'loongarch64': loongarch_ss} -+ -diff --git a/include/hw/loongarch/bios.h b/include/hw/loongarch/bios.h -new file mode 100644 -index 000000000..3677303bf ---- /dev/null -+++ b/include/hw/loongarch/bios.h -@@ -0,0 +1,5 @@ -+#include "qemu/units.h" -+#include "cpu.h" -+ -+#define BIOS_SIZE (4 * MiB) -+#define BIOS_FILENAME "loongarch_bios.bin" -diff --git a/include/hw/loongarch/cpudevs.h b/include/hw/loongarch/cpudevs.h -new file mode 100644 -index 000000000..c05ae7a7f ---- /dev/null -+++ b/include/hw/loongarch/cpudevs.h -@@ -0,0 +1,53 @@ -+#ifndef HW_LOONGARCH_CPUDEVS_H -+#define HW_LOONGARCH_CPUDEVS_H -+ -+#include "target/loongarch64/cpu-qom.h" -+ -+/* Definitions for LOONGARCH CPU internal devices. */ -+#define MAX_GIPI_CORE_NUM 256 -+#define MAX_GIPI_MBX_NUM 4 -+ -+#define LS3A_INTC_IP 8 -+#define MAX_CORES 256 -+#define EXTIOI_IRQS (256) -+#define EXTIOI_IRQS_BITMAP_SIZE (256 / 8) -+/* map to ipnum per 32 irqs */ -+#define EXTIOI_IRQS_IPMAP_SIZE (256 / 32) -+ -+typedef struct gipi_core { -+ uint32_t status; -+ uint32_t en; -+ uint32_t set; -+ uint32_t clear; -+ uint64_t buf[MAX_GIPI_MBX_NUM]; -+ qemu_irq irq; -+} gipi_core; -+ -+typedef struct gipiState { -+ gipi_core core[MAX_GIPI_CORE_NUM]; -+} gipiState; -+ -+typedef struct apicState { -+ /* hardware state */ -+ uint8_t ext_en[EXTIOI_IRQS_BITMAP_SIZE]; -+ uint8_t ext_bounce[EXTIOI_IRQS_BITMAP_SIZE]; -+ uint8_t ext_isr[EXTIOI_IRQS_BITMAP_SIZE]; -+ uint8_t ext_coreisr[MAX_CORES][EXTIOI_IRQS_BITMAP_SIZE]; -+ uint8_t ext_ipmap[EXTIOI_IRQS_IPMAP_SIZE]; -+ uint8_t ext_coremap[EXTIOI_IRQS]; -+ uint16_t ext_nodetype[16]; -+ uint64_t ext_control; -+ -+ /* software state */ -+ uint8_t ext_sw_ipmap[EXTIOI_IRQS]; -+ uint8_t ext_sw_coremap[EXTIOI_IRQS]; -+ uint8_t ext_ipisr[MAX_CORES * LS3A_INTC_IP][EXTIOI_IRQS_BITMAP_SIZE]; -+ -+ qemu_irq parent_irq[MAX_CORES][LS3A_INTC_IP]; -+ qemu_irq *irq; -+} apicState; -+ -+void cpu_init_irq(LOONGARCHCPU *cpu); -+void cpu_loongarch_clock_init(LOONGARCHCPU *cpu); -+ -+#endif -diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h -new file mode 100644 -index 000000000..0886ed52a ---- /dev/null -+++ b/include/hw/loongarch/larch.h -@@ -0,0 +1,163 @@ -+/* -+ * Hotplug emulation on Loongarch system. -+ * -+ * Copyright (c) 2018 Loongarch Inc. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+ -+#ifndef HW_LOONGARCH_H -+#define HW_LOONGARCH_H -+ -+#include "target/loongarch64/cpu.h" -+#include "qemu-common.h" -+#include "exec/memory.h" -+#include "hw/mem/pc-dimm.h" -+#include "hw/hotplug.h" -+#include "hw/boards.h" -+#include "hw/acpi/acpi.h" -+#include "qemu/notify.h" -+#include "qemu/error-report.h" -+#include "qemu/queue.h" -+#include "hw/acpi/memory_hotplug.h" -+#include "hw/loongarch/cpudevs.h" -+#include "hw/block/flash.h" -+ -+#define LOONGARCH_MAX_VCPUS 256 -+#define LOONGARCH_MAX_PFLASH 2 -+/* 256MB alignment for hotplug memory region */ -+#define LOONGARCH_HOTPLUG_MEM_ALIGN (1ULL << 28) -+#define LOONGARCH_MAX_RAM_SLOTS 10 -+ -+/* Memory types: */ -+#define SYSTEM_RAM 1 -+#define SYSTEM_RAM_RESERVED 2 -+#define ACPI_TABLE 3 -+#define ACPI_NVS 4 -+#define SYSTEM_PMEM 5 -+ -+#define MAX_MEM_MAP 128 -+ -+typedef struct LoongarchMachineClass { -+ /*< private >*/ -+ MachineClass parent_class; -+ -+ /* Methods: */ -+ HotplugHandler *(*get_hotplug_handler)(MachineState *machine, -+ DeviceState *dev); -+ -+ bool has_acpi_build; -+ -+ /* save different cpu address*/ -+ uint64_t isa_io_base; -+ uint64_t ht_control_regs_base; -+ uint64_t hpet_mmio_addr; -+ uint64_t smbus_cfg_base; -+ uint64_t ht1lo_pcicfg_base; -+ uint64_t pciecfg_base; -+ uint64_t ls7a_ioapic_reg_base; -+ uint32_t node_shift; -+ char cpu_name[40]; -+ char bridge_name[16]; -+ -+} LoongarchMachineClass; -+ -+typedef struct ResetData { -+ LOONGARCHCPU *cpu; -+ uint64_t vector; -+} ResetData; -+ -+typedef struct LoongarchMachineState { -+ /*< private >*/ -+ MachineState parent_obj; -+ -+ /* */ -+ ram_addr_t hotplug_memory_size; -+ -+ /* State for other subsystems/APIs: */ -+ Notifier machine_done; -+ /* Pointers to devices and objects: */ -+ HotplugHandler *acpi_dev; -+ int ram_slots; -+ ResetData *reset_info[LOONGARCH_MAX_VCPUS]; -+ DeviceState *rtc; -+ gipiState *gipi; -+ apicState *apic; -+ -+ FWCfgState *fw_cfg; -+ bool acpi_build_enabled; -+ bool apic_xrupt_override; -+ CPUArchIdList *possible_cpus; -+ PFlashCFI01 *flash[LOONGARCH_MAX_PFLASH]; -+ void *fdt; -+ int fdt_size; -+ unsigned int hotpluged_cpu_num; -+ OnOffAuto acpi; -+ char *oem_id; -+ char *oem_table_id; -+} LoongarchMachineState; -+ -+#define LOONGARCH_MACHINE_ACPI_DEVICE_PROP "loongarch-acpi-device" -+#define TYPE_LOONGARCH_MACHINE "loongarch-machine" -+ -+#define LoongarchMACHINE(obj) \ -+ OBJECT_CHECK(LoongarchMachineState, (obj), TYPE_LOONGARCH_MACHINE) -+#define LoongarchMACHINE_GET_CLASS(obj) \ -+ OBJECT_GET_CLASS(LoongarchMachineClass, (obj), TYPE_LOONGARCH_MACHINE) -+#define LoongarchMACHINE_CLASS(klass) \ -+ OBJECT_CLASS_CHECK(LoongarchMachineClass, (klass), TYPE_LOONGARCH_MACHINE) -+ -+#define DEFINE_LOONGARCH_MACHINE(suffix, namestr, initfn, optsfn) \ -+ static void loongarch_machine_##suffix##_class_init(ObjectClass *oc, void *data) \ -+ { \ -+ MachineClass *mc = MACHINE_CLASS(oc); \ -+ optsfn(mc); \ -+ mc->init = initfn; \ -+ } \ -+ static const TypeInfo loongarch_machine_type_##suffix = { \ -+ .name = namestr TYPE_MACHINE_SUFFIX, \ -+ .parent = TYPE_LOONGARCH_MACHINE, \ -+ .class_init = loongarch_machine_##suffix##_class_init, \ -+ }; \ -+ static void loongarch_machine_init_##suffix(void) \ -+ { \ -+ type_register(&loongarch_machine_type_##suffix); \ -+ } \ -+ type_init(loongarch_machine_init_##suffix) -+ -+void loongarch_machine_device_unplug_request(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp); -+void longson_machine_device_unplug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp); -+HotplugHandler *loongarch_get_hotpug_handler(MachineState *machine, -+ DeviceState *dev); -+void loongarch_machine_device_pre_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp); -+void loongarch_machine_device_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp); -+ -+LOONGARCHCPU *loongarch_cpu_create(MachineState *machine, LOONGARCHCPU *cpu, -+ Error **errp); -+void loongarch_cpu_destroy(MachineState *machine, LOONGARCHCPU *cpu); -+int cpu_init_ipi(LoongarchMachineState *ms, qemu_irq parent, int cpu); -+int cpu_init_apic(LoongarchMachineState *ms, CPULOONGARCHState *env, int cpu); -+int la_memmap_add_entry(uint64_t address, uint64_t length, uint32_t type); -+bool loongarch_is_acpi_enabled(LoongarchMachineState *vms); -+ -+/* acpi-build.c */ -+void ls7a_madt_cpu_entry(AcpiDeviceIf *adev, int uid, -+ const CPUArchIdList *apic_ids, GArray *entry, bool force_enabled); -+void slave_cpu_reset(void *opaque); -+extern uint64_t host_cpufreq; -+#endif -diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h -new file mode 100644 -index 000000000..686af763a ---- /dev/null -+++ b/include/hw/loongarch/ls7a.h -@@ -0,0 +1,152 @@ -+#ifndef HW_LS7A_H -+#define HW_LS7A_H -+ -+#include "hw/hw.h" -+#include "hw/isa/isa.h" -+#include "hw/sysbus.h" -+#include "hw/isa/apm.h" -+#include "hw/pci/pci.h" -+#include "hw/pci/pcie_host.h" -+#include "hw/pci/pci_bridge.h" -+#include "hw/acpi/acpi.h" -+#include "hw/acpi/ls7a.h" -+#include "hw/pci/pci_bus.h" -+ -+/* LS7A PCH Registers (Misc, Confreg) */ -+#define LS7A_PCH_REG_BASE 0x10000000UL -+#define LS3A5K_LS7A_IOAPIC_REG_BASE (LS7A_PCH_REG_BASE) -+#define LS7A_MISC_REG_BASE (LS7A_PCH_REG_BASE + 0x00080000) -+#define LS7A_ACPI_REG_BASE (LS7A_MISC_REG_BASE + 0x00050000) -+ -+#define LOONGARCH_PCH_IRQ_BASE 64 -+#define LS7A_UART_IRQ (LOONGARCH_PCH_IRQ_BASE + 2) -+#define LS7A_RTC_IRQ (LOONGARCH_PCH_IRQ_BASE + 3) -+#define LS7A_SCI_IRQ (LOONGARCH_PCH_IRQ_BASE + 4) -+#define LS7A_ACPI_IO_BASE 0x800 -+#define LS7A_ACPI_IO_SIZE 0x100 -+#define LS7A_PM_EVT_BLK (0x0C) /* 4 bytes */ -+#define LS7A_PM_CNT_BLK (0x14) /* 2 bytes */ -+#define LS7A_GPE0_STS_REG (0x28) /* 4 bytes */ -+#define LS7A_GPE0_ENA_REG (0x2C) /* 4 bytes */ -+#define LS7A_GPE0_RESET_REG (0x30) /* 4 bytes */ -+#define LS7A_PM_TMR_BLK (0x18) /* 4 bytes */ -+#define LS7A_GPE0_LEN (8) -+#define LS7A_RTC_REG_BASE (LS7A_MISC_REG_BASE + 0x00050100) -+#define LS7A_RTC_LEN (0x100) -+ -+#define ACPI_IO_BASE (LS7A_ACPI_REG_BASE) -+#define ACPI_GPE0_LEN (LS7A_GPE0_LEN) -+#define ACPI_IO_SIZE (LS7A_ACPI_IO_SIZE) -+#define ACPI_SCI_IRQ (LS7A_SCI_IRQ) -+ -+#define LS3A5K_ISA_IO_BASE 0x18000000UL -+#define LS_ISA_MEM_BASE 0x40000000 -+#define LS3A5K_HT1LO_PCICFG_BASE 0x1a000000 -+#define HT1LO_PCICFG_SIZE 0x02000000 -+#define LS_BIOS_BASE 0x1c000000 -+#define LS_BIOS_VAR_BASE 0x1c3a0000 -+#define LS_BIOS_SIZE (4 * 1024 * 1024) -+ -+#define FW_CFG_ADDR 0x1e020000 -+#define LS7A_REG_BASE 0x1FE00000 -+#define LS7A_PCICONFIG_BASE (LS7A_REG_BASE + 0x30) -+#define LS7A_PCICONFIG_SIZE (0x100) -+#define LS7A_INTERNAL_REG_BASE (LS7A_REG_BASE + 0x100) -+#define LS7A_INTERNAL_REG_SIZE (0xE0) -+#define LS7A_REGS (0xE0 >> 2) -+#define LS7A_UART_BASE 0x1fe001e0 -+#define LS7A_UART_LEN 0x8 -+ -+#define LS_FDT_BASE 0x1c400000 -+#define LS_FDT_SIZE 0x100000 -+ -+#define LS_PCIECFG_BASE 0x20000000 -+#define LS_PCIECFG_SIZE 0x08000000 -+#define MSI_ADDR_LOW 0x2FF00000 -+#define MSI_ADDR_HI 0x0 -+ -+#define SMP_GIPI_MAILBOX 0x1f000000ULL -+#define CORE0_STATUS_OFF 0x000 -+#define CORE0_EN_OFF 0x004 -+#define CORE0_SET_OFF 0x008 -+#define CORE0_CLEAR_OFF 0x00c -+#define CORE0_BUF_20 0x020 -+#define CORE0_BUF_28 0x028 -+#define CORE0_BUF_30 0x030 -+#define CORE0_BUF_38 0x038 -+#define CORE0_IPI_SEND 0x040 -+#define CORE0_MAIL_SEND 0x048 -+ -+#define INT_ROUTER_REGS_BASE 0x1fe01400UL -+#define INT_ROUTER_REGS_SIZE 0x100 -+#define INT_ROUTER_REGS_SYS_INT0 0x00 -+#define INT_ROUTER_REGS_SYS_INT1 0x01 -+#define INT_ROUTER_REGS_SYS_INT2 0x02 -+#define INT_ROUTER_REGS_SYS_INT3 0x03 -+#define INT_ROUTER_REGS_PCI_INT0 0x04 -+#define INT_ROUTER_REGS_PCI_INT1 0x05 -+#define INT_ROUTER_REGS_PCI_INT2 0x06 -+#define INT_ROUTER_REGS_PCI_INT3 0x07 -+#define INT_ROUTER_REGS_MATRIX_INT0 0x08 -+#define INT_ROUTER_REGS_MATRIX_INT1 0x09 -+#define INT_ROUTER_REGS_LPC_INT 0x0a -+#define INT_ROUTER_REGS_MC0 0x0b -+#define INT_ROUTER_REGS_MC1 0x0c -+#define INT_ROUTER_REGS_BARRIER 0x0d -+#define INT_ROUTER_REGS_THSENS_INT 0x0e -+#define INT_ROUTER_REGS_PCI_PERR 0x0f -+#define INT_ROUTER_REGS_HT0_INT0 0x10 -+#define INT_ROUTER_REGS_HT0_INT1 0x11 -+#define INT_ROUTER_REGS_HT0_INT2 0x12 -+#define INT_ROUTER_REGS_HT0_INT3 0x13 -+#define INT_ROUTER_REGS_HT0_INT4 0x14 -+#define INT_ROUTER_REGS_HT0_INT5 0x15 -+#define INT_ROUTER_REGS_HT0_INT6 0x16 -+#define INT_ROUTER_REGS_HT0_INT7 0x17 -+#define INT_ROUTER_REGS_HT1_INT0 0x18 -+#define INT_ROUTER_REGS_HT1_INT1 0x19 -+#define INT_ROUTER_REGS_HT1_INT2 0x1a -+#define INT_ROUTER_REGS_HT1_INT3 0x1b -+#define INT_ROUTER_REGS_HT1_INT4 0x1c -+#define INT_ROUTER_REGS_HT1_INT5 0x1d -+#define INT_ROUTER_REGS_HT1_INT6 0x1e -+#define INT_ROUTER_REGS_HT1_INT7 0x1f -+#define INT_ROUTER_REGS_ISR 0x20 -+#define INT_ROUTER_REGS_EN 0x24 -+#define INT_ROUTER_REGS_EN_SET 0x28 -+#define INT_ROUTER_REGS_EN_CLR 0x2c -+#define INT_ROUTER_REGS_EDGE 0x38 -+#define INT_ROUTER_REGS_CORE0_INTISR 0x40 -+#define INT_ROUTER_REGS_CORE1_INTISR 0x48 -+#define INT_ROUTER_REGS_CORE2_INTISR 0x50 -+#define INT_ROUTER_REGS_CORE3_INTISR 0x58 -+ -+typedef struct LS7APCIState LS7APCIState; -+typedef struct LS7APCIEHost { -+ PCIExpressHost parent_obj; -+ LS7APCIState *pci_dev; -+} LS7APCIEHost; -+ -+struct LS7APCIState { -+ PCIDevice dev; -+ -+ LS7APCIEHost *pciehost; -+ uint32_t regs[LS7A_REGS]; -+ -+ /* LS7A registers */ -+ MemoryRegion iomem; -+ LS7APCIPMRegs pm; -+}; -+ -+#define TYPE_LS7A_PCIE_HOST_BRIDGE "ls7a1000-pciehost" -+#define LS7A_PCIE_HOST_BRIDGE(obj) \ -+ OBJECT_CHECK(LS7APCIEHost, (obj), TYPE_LS7A_PCIE_HOST_BRIDGE) -+ -+#define TYPE_PCIE_LS7A "ls7a1000_pcie" -+#define PCIE_LS7A(obj) \ -+ OBJECT_CHECK(LS7APCIState, (obj), TYPE_PCIE_LS7A) -+ -+PCIBus *ls7a_init(MachineState *machine, qemu_irq *irq, DeviceState **ls7a_dev); -+LS7APCIState *get_ls7a_type(Object *obj); -+ -+#endif /* HW_LS7A_H */ --- -2.43.5 - diff --git a/0003-anolis-csv-i386-add-command-to-load-data-to-guest-me.patch b/0003-anolis-csv-i386-add-command-to-load-data-to-guest-me.patch deleted file mode 100644 index ba1f14a..0000000 --- a/0003-anolis-csv-i386-add-command-to-load-data-to-guest-me.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 6dcfcd61e610da4e8d7dcfb6c3eefd7fc8a67c45 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Wed, 25 Aug 2021 09:59:16 +0800 -Subject: [PATCH 3/8] anolis: csv/i386: add command to load data to guest - memory - -The KVM_CSV_LAUNCH_ENCRYPT_DATA command is used to load data to an -encrypted guest memory in an isolated memory region that guest owns. - -Signed-off-by: Xin Jiang -Change-Id: I6d4bea4969a0afa87fb8f2e52fb7ab02ec0db2ed ---- - linux-headers/linux/kvm.h | 7 ++++ - target/i386/csv-sysemu-stub.c | 5 +++ - target/i386/csv.c | 69 +++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 2 + - target/i386/trace-events | 3 ++ - 5 files changed, 86 insertions(+) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index b15b8f5550..53f9202ffb 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1813,6 +1813,13 @@ enum csv_cmd_id { - KVM_CSV_NR_MIN = 0xc0, - - KVM_CSV_INIT = KVM_CSV_NR_MIN, -+ KVM_CSV_LAUNCH_ENCRYPT_DATA, -+}; -+ -+struct kvm_csv_launch_encrypt_data { -+ __u64 gpa; -+ __u64 uaddr; -+ __u32 len; - }; - - struct kvm_csv_init_data { -diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c -index dbd710dc6f..236a6909d2 100644 ---- a/target/i386/csv-sysemu-stub.c -+++ b/target/i386/csv-sysemu-stub.c -@@ -19,3 +19,8 @@ int csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) - { - return 0; - } -+ -+int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) -+{ -+ g_assert_not_reached(); -+} -diff --git a/target/i386/csv.c b/target/i386/csv.c -index c11f59f30c..3b3dff5174 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -14,11 +14,13 @@ - #include "qemu/osdep.h" - - #include -+#include "qapi/error.h" - - #ifdef CONFIG_NUMA - #include - #endif - -+#include "trace.h" - #include "cpu.h" - #include "sev.h" - #include "csv.h" -@@ -93,3 +95,70 @@ csv_enabled(void) - - return sev_es_enabled() && (csv_guest.policy & GUEST_POLICY_CSV_BIT); - } -+ -+static bool -+csv_check_state(SevState state) -+{ -+ return *((SevState *)csv_guest.state) == state ? true : false; -+} -+ -+static int -+csv_ioctl(int cmd, void *data, int *error) -+{ -+ if (csv_guest.sev_ioctl) -+ return csv_guest.sev_ioctl(csv_guest.sev_fd, cmd, data, error); -+ else -+ return -1; -+} -+ -+static const char * -+fw_error_to_str(int code) -+{ -+ if (csv_guest.fw_error_to_str) -+ return csv_guest.fw_error_to_str(code); -+ else -+ return NULL; -+} -+ -+static int -+csv_launch_encrypt_data(uint64_t gpa, uint8_t *addr, uint64_t len) -+{ -+ int ret, fw_error; -+ struct kvm_csv_launch_encrypt_data update; -+ -+ if (!addr || !len) { -+ return 1; -+ } -+ -+ update.gpa = (__u64)gpa; -+ update.uaddr = (__u64)(unsigned long)addr; -+ update.len = len; -+ trace_kvm_csv_launch_encrypt_data(gpa, addr, len); -+ ret = csv_ioctl(KVM_CSV_LAUNCH_ENCRYPT_DATA, &update, &fw_error); -+ if (ret) { -+ error_report("%s: CSV LAUNCH_ENCRYPT_DATA ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ } -+ -+ return ret; -+} -+ -+int -+csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) -+{ -+ int ret = 0; -+ -+ if (!csv_enabled()) { -+ error_setg(errp, "%s: CSV is not enabled", __func__); -+ return -1; -+ } -+ -+ /* if CSV is in update state then load the data to secure memory */ -+ if (csv_check_state(SEV_STATE_LAUNCH_UPDATE)) { -+ ret = csv_launch_encrypt_data(gpa, ptr, len); -+ if (ret) -+ error_setg(errp, "%s: CSV fail to encrypt data", __func__); -+ } -+ -+ return ret; -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 886dbb2613..6f7b112d96 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -35,4 +35,6 @@ typedef struct CsvGuestState CsvGuestState; - extern struct CsvGuestState csv_guest; - extern int csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops); - -+int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); -+ - #endif -diff --git a/target/i386/trace-events b/target/i386/trace-events -index 2cd8726eeb..b7da9bd748 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -11,3 +11,6 @@ kvm_sev_launch_measurement(const char *value) "data %s" - kvm_sev_launch_finish(void) "" - kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d" - kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data %s" -+ -+# csv.c -+kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 --- -2.17.1 - diff --git a/0004-Add-target-loongarch64.patch b/0004-Add-target-loongarch64.patch deleted file mode 100644 index bca350b..0000000 --- a/0004-Add-target-loongarch64.patch +++ /dev/null @@ -1,15917 +0,0 @@ -From 73e64c37b5d0f8a12bad7562c4d442f95ee361b8 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Fri, 19 Aug 2022 23:44:33 -0400 -Subject: [PATCH 04/28] Add target/loongarch64. - -Change-Id: Idd3ed114968c4a1f1be5fe19dc279028775eb89d -Signed-off-by: lixianglai ---- - target/Kconfig | 1 + - target/loongarch64/Kconfig | 2 + - target/loongarch64/arch_dump.c | 174 ++ - target/loongarch64/cpu-csr.h | 869 ++++++++ - target/loongarch64/cpu-param.h | 30 + - target/loongarch64/cpu-qom.h | 54 + - target/loongarch64/cpu.c | 576 +++++ - target/loongarch64/cpu.h | 326 +++ - target/loongarch64/csr_helper.c | 704 ++++++ - target/loongarch64/fpu.c | 28 + - target/loongarch64/fpu_helper.c | 952 ++++++++ - target/loongarch64/fpu_helper.h | 129 ++ - target/loongarch64/gdbstub.c | 109 + - target/loongarch64/helper.c | 727 +++++++ - target/loongarch64/helper.h | 168 ++ - target/loongarch64/insn.decode | 514 +++++ - target/loongarch64/instmap.h | 216 ++ - target/loongarch64/internal.h | 184 ++ - target/loongarch64/kvm.c | 1622 ++++++++++++++ - target/loongarch64/kvm_larch.h | 41 + - target/loongarch64/larch-defs.h | 27 + - target/loongarch64/machine.c | 416 ++++ - target/loongarch64/meson.build | 35 + - target/loongarch64/op_helper.c | 533 +++++ - target/loongarch64/stabletimer.c | 122 ++ - target/loongarch64/tlb_helper.c | 729 +++++++ - target/loongarch64/trace-events | 3 + - target/loongarch64/trans.inc.c | 3472 ++++++++++++++++++++++++++++++ - target/loongarch64/translate.c | 2892 +++++++++++++++++++++++++ - target/meson.build | 1 + - 30 files changed, 15656 insertions(+) - create mode 100644 target/loongarch64/Kconfig - create mode 100644 target/loongarch64/arch_dump.c - create mode 100644 target/loongarch64/cpu-csr.h - create mode 100644 target/loongarch64/cpu-param.h - create mode 100644 target/loongarch64/cpu-qom.h - create mode 100644 target/loongarch64/cpu.c - create mode 100644 target/loongarch64/cpu.h - create mode 100644 target/loongarch64/csr_helper.c - create mode 100644 target/loongarch64/fpu.c - create mode 100644 target/loongarch64/fpu_helper.c - create mode 100644 target/loongarch64/fpu_helper.h - create mode 100644 target/loongarch64/gdbstub.c - create mode 100644 target/loongarch64/helper.c - create mode 100644 target/loongarch64/helper.h - create mode 100644 target/loongarch64/insn.decode - create mode 100644 target/loongarch64/instmap.h - create mode 100644 target/loongarch64/internal.h - create mode 100644 target/loongarch64/kvm.c - create mode 100644 target/loongarch64/kvm_larch.h - create mode 100644 target/loongarch64/larch-defs.h - create mode 100644 target/loongarch64/machine.c - create mode 100644 target/loongarch64/meson.build - create mode 100644 target/loongarch64/op_helper.c - create mode 100644 target/loongarch64/stabletimer.c - create mode 100644 target/loongarch64/tlb_helper.c - create mode 100644 target/loongarch64/trace-events - create mode 100644 target/loongarch64/trans.inc.c - create mode 100644 target/loongarch64/translate.c - -diff --git a/target/Kconfig b/target/Kconfig -index ae7f24fc6..50b46d048 100644 ---- a/target/Kconfig -+++ b/target/Kconfig -@@ -4,6 +4,7 @@ source avr/Kconfig - source cris/Kconfig - source hppa/Kconfig - source i386/Kconfig -+source loongarch64/Kconfig - source m68k/Kconfig - source microblaze/Kconfig - source mips/Kconfig -diff --git a/target/loongarch64/Kconfig b/target/loongarch64/Kconfig -new file mode 100644 -index 000000000..46b26b1a8 ---- /dev/null -+++ b/target/loongarch64/Kconfig -@@ -0,0 +1,2 @@ -+config LOONGARCH64 -+ bool -diff --git a/target/loongarch64/arch_dump.c b/target/loongarch64/arch_dump.c -new file mode 100644 -index 000000000..7b8708fdf ---- /dev/null -+++ b/target/loongarch64/arch_dump.c -@@ -0,0 +1,174 @@ -+/* Support for writing ELF notes for RM architectures -+ * -+ * Copyright (C) 2015 Red Hat Inc. -+ * -+ * Author: Andrew Jones -+ * -+ * 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 . -+ */ -+ -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "elf.h" -+#include "sysemu/dump.h" -+#include "internal.h" -+ -+/* struct user_pt_regs from arch/loongarch/include/uapi/asm/ptrace.h */ -+struct loongarch_user_regs { -+ uint64_t gpr[32]; -+ uint64_t lo; -+ uint64_t hi; -+ uint64_t csr_era; -+ uint64_t csr_badvaddr; -+ uint64_t csr_crmd; -+ uint64_t csr_ecfg; -+ uint64_t pad[7]; -+} QEMU_PACKED; -+ -+QEMU_BUILD_BUG_ON(sizeof(struct loongarch_user_regs) != 360); -+ -+/* struct elf_prstatus from include/uapi/linux/elfcore.h */ -+struct loongarch_elf_prstatus { -+ char pad1[32]; /* 32 == offsetof(struct elf_prstatus, pr_pid) */ -+ uint32_t pr_pid; -+ char pad2[76]; /* 76 == offsetof(struct elf_prstatus, pr_reg) - -+ offsetof(struct elf_prstatus, pr_ppid) */ -+ struct loongarch_user_regs pr_reg; -+ uint32_t pr_fpvalid; -+ char pad3[4]; -+} QEMU_PACKED; -+ -+QEMU_BUILD_BUG_ON(sizeof(struct loongarch_elf_prstatus) != 480); -+ -+/* struct user_fpsimd_state from arch/arm64/include/uapi/asm/ptrace.h -+ * -+ * While the vregs member of user_fpsimd_state is of type __uint128_t, -+ * QEMU uses an array of uint64_t, where the high half of the 128-bit -+ * value is always in the 2n+1'th index. Thus we also break the 128- -+ * bit values into two halves in this reproduction of user_fpsimd_state. -+ */ -+ -+struct loongarch_fpu_struct { -+ uint64_t fpr[32]; -+ unsigned int fir; -+ unsigned int fcsr; -+} QEMU_PACKED; -+ -+QEMU_BUILD_BUG_ON(sizeof(struct loongarch_fpu_struct) != 264); -+ -+struct loongarch_note { -+ Elf64_Nhdr hdr; -+ char name[8]; /* align_up(sizeof("CORE"), 4) */ -+ union { -+ struct loongarch_elf_prstatus prstatus; -+ struct loongarch_fpu_struct fpu; -+ }; -+} QEMU_PACKED; -+ -+#define LOONGARCH_NOTE_HEADER_SIZE offsetof(struct loongarch_note, prstatus) -+#define LOONGARCH_PRSTATUS_NOTE_SIZE (LOONGARCH_NOTE_HEADER_SIZE + \ -+ sizeof(struct loongarch_elf_prstatus)) -+#define LOONGARCH_PRFPREG_NOTE_SIZE (LOONGARCH_NOTE_HEADER_SIZE + \ -+ sizeof(struct loongarch_fpu_struct)) -+ -+static void loongarch_note_init(struct loongarch_note *note, DumpState *s, -+ const char *name, Elf64_Word namesz, -+ Elf64_Word type, Elf64_Word descsz) -+{ -+ memset(note, 0, sizeof(*note)); -+ -+ note->hdr.n_namesz = cpu_to_dump32(s, namesz); -+ note->hdr.n_descsz = cpu_to_dump32(s, descsz); -+ note->hdr.n_type = cpu_to_dump32(s, type); -+ -+ memcpy(note->name, name, namesz); -+} -+ -+static int loongarch_write_elf64_fprpreg(WriteCoreDumpFunction f, -+ CPULOONGARCHState *env, int cpuid, -+ DumpState *s) -+{ -+ struct loongarch_note note; -+ int ret, i; -+ -+ loongarch_note_init(¬e, s, "CORE", 5, NT_PRFPREG, sizeof(note.fpu)); -+ -+ note.fpu.fcsr = cpu_to_dump64(s, env->active_fpu.fcsr0); -+ -+ for (i = 0; i < 32; ++i) { -+ note.fpu.fpr[i] = cpu_to_dump64(s, env->active_fpu.fpr[i].fd); -+ } -+ -+ ret = f(¬e, LOONGARCH_PRFPREG_NOTE_SIZE, s); -+ if (ret < 0) { -+ return -1; -+ } -+ -+ return 0; -+} -+ -+int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, -+ int cpuid, DumpState *s) -+{ -+ struct loongarch_note note; -+ CPULOONGARCHState *env = &LOONGARCH_CPU(cs)->env; -+ int ret, i; -+ -+ loongarch_note_init(¬e, s, "CORE", 5, NT_PRSTATUS, sizeof(note.prstatus)); -+ -+ note.prstatus.pr_pid = cpu_to_dump32(s, cpuid); -+ note.prstatus.pr_fpvalid = cpu_to_dump32(s, 1); -+ -+ for (i = 0; i < 32; ++i) { -+ note.prstatus.pr_reg.gpr[i] = cpu_to_dump64(s, env->active_tc.gpr[i]); -+ } -+ note.prstatus.pr_reg.csr_era = cpu_to_dump64(s, env->CSR_ERA); -+ note.prstatus.pr_reg.csr_badvaddr = cpu_to_dump64(s, env->CSR_BADV); -+ note.prstatus.pr_reg.csr_crmd = cpu_to_dump64(s, env->CSR_CRMD); -+ note.prstatus.pr_reg.csr_ecfg = cpu_to_dump64(s, env->CSR_ECFG); -+ -+ ret = f(¬e, LOONGARCH_PRSTATUS_NOTE_SIZE, s); -+ if (ret < 0) { -+ return -1; -+ } -+ -+ ret = loongarch_write_elf64_fprpreg(f, env, cpuid, s); -+ if (ret < 0) { -+ return -1; -+ } -+ -+ return ret; -+} -+ -+int cpu_get_dump_info(ArchDumpInfo *info, -+ const GuestPhysBlockList *guest_phys_blocks) -+{ -+ info->d_machine = EM_LOONGARCH; -+ info->d_endian = ELFDATA2LSB; -+ info->d_class = ELFCLASS64; -+ -+ return 0; -+} -+ -+ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) -+{ -+ size_t note_size = 0; -+ -+ if (class == ELFCLASS64) { -+ note_size = LOONGARCH_PRSTATUS_NOTE_SIZE + LOONGARCH_PRFPREG_NOTE_SIZE; -+ } -+ -+ return note_size * nr_cpus; -+} -+ -diff --git a/target/loongarch64/cpu-csr.h b/target/loongarch64/cpu-csr.h -new file mode 100644 -index 000000000..e549bb46b ---- /dev/null -+++ b/target/loongarch64/cpu-csr.h -@@ -0,0 +1,869 @@ -+#ifndef _CPU_CSR_H_ -+#define _CPU_CSR_H_ -+ -+/* basic CSR register */ -+#define LOONGARCH_CSR_CRMD 0x0 /* 32 current mode info */ -+#define CSR_CRMD_DACM_SHIFT 7 -+#define CSR_CRMD_DACM_WIDTH 2 -+#define CSR_CRMD_DACM (0x3UL << CSR_CRMD_DACM_SHIFT) -+#define CSR_CRMD_DACF_SHIFT 5 -+#define CSR_CRMD_DACF_WIDTH 2 -+#define CSR_CRMD_DACF (0x3UL << CSR_CRMD_DACF_SHIFT) -+#define CSR_CRMD_PG_SHIFT 4 -+#define CSR_CRMD_PG (0x1UL << CSR_CRMD_PG_SHIFT) -+#define CSR_CRMD_DA_SHIFT 3 -+#define CSR_CRMD_DA (0x1UL << CSR_CRMD_DA_SHIFT) -+#define CSR_CRMD_IE_SHIFT 2 -+#define CSR_CRMD_IE (0x1UL << CSR_CRMD_IE_SHIFT) -+#define CSR_CRMD_PLV_SHIFT 0 -+#define CSR_CRMD_PLV_WIDTH 2 -+#define CSR_CRMD_PLV (0x3UL << CSR_CRMD_PLV_SHIFT) -+ -+#define PLV_USER 3 -+#define PLV_KERN 0 -+#define PLV_MASK 0x3 -+ -+#define LOONGARCH_CSR_PRMD 0x1 /* 32 prev-exception mode info */ -+#define CSR_PRMD_PIE_SHIFT 2 -+#define CSR_PRMD_PIE (0x1UL << CSR_PRMD_PIE_SHIFT) -+#define CSR_PRMD_PPLV_SHIFT 0 -+#define CSR_PRMD_PPLV_WIDTH 2 -+#define CSR_PRMD_PPLV (0x3UL << CSR_PRMD_PPLV_SHIFT) -+ -+#define LOONGARCH_CSR_EUEN 0x2 /* 32 coprocessor enable */ -+#define CSR_EUEN_LBTEN_SHIFT 3 -+#define CSR_EUEN_LBTEN (0x1UL << CSR_EUEN_LBTEN_SHIFT) -+#define CSR_EUEN_LASXEN_SHIFT 2 -+#define CSR_EUEN_LASXEN (0x1UL << CSR_EUEN_LASXEN_SHIFT) -+#define CSR_EUEN_LSXEN_SHIFT 1 -+#define CSR_EUEN_LSXEN (0x1UL << CSR_EUEN_LSXEN_SHIFT) -+#define CSR_EUEN_FPEN_SHIFT 0 -+#define CSR_EUEN_FPEN (0x1UL << CSR_EUEN_FPEN_SHIFT) -+ -+#define LOONGARCH_CSR_MISC 0x3 /* 32 misc config */ -+ -+#define LOONGARCH_CSR_ECFG 0x4 /* 32 exception config */ -+#define CSR_ECFG_VS_SHIFT 16 -+#define CSR_ECFG_VS_WIDTH 3 -+#define CSR_ECFG_VS (0x7UL << CSR_ECFG_VS_SHIFT) -+#define CSR_ECFG_IM_SHIFT 0 -+#define CSR_ECFG_IM_WIDTH 13 -+#define CSR_ECFG_IM (0x1fffUL << CSR_ECFG_IM_SHIFT) -+ -+#define CSR_ECFG_IPMASK 0x00001fff -+ -+#define LOONGARCH_CSR_ESTAT 0x5 /* Exception status */ -+#define CSR_ESTAT_ESUBCODE_SHIFT 22 -+#define CSR_ESTAT_ESUBCODE_WIDTH 9 -+#define CSR_ESTAT_ESUBCODE (0x1ffULL << CSR_ESTAT_ESUBCODE_SHIFT) -+#define CSR_ESTAT_EXC_SH 16 -+#define CSR_ESTAT_EXC_WIDTH 5 -+#define CSR_ESTAT_EXC (0x1fULL << CSR_ESTAT_EXC_SH) -+#define CSR_ESTAT_IS_SHIFT 0 -+#define CSR_ESTAT_IS_WIDTH 15 -+#define CSR_ESTAT_IS (0x7fffULL << CSR_ESTAT_IS_SHIFT) -+ -+#define CSR_ESTAT_IPMASK 0x00001fff -+ -+#define EXCODE_IP 64 -+#define EXCCODE_RSV 0 -+#define EXCCODE_TLBL 1 -+#define EXCCODE_TLBS 2 -+#define EXCCODE_TLBI 3 -+#define EXCCODE_MOD 4 -+#define EXCCODE_TLBRI 5 -+#define EXCCODE_TLBXI 6 -+#define EXCCODE_TLBPE 7 -+#define EXCCODE_ADE 8 -+#define EXCCODE_UNALIGN 9 -+#define EXCCODE_OOB 10 -+#define EXCCODE_SYS 11 -+#define EXCCODE_BP 12 -+#define EXCCODE_RI 13 -+#define EXCCODE_IPE 14 -+#define EXCCODE_FPDIS 15 -+#define EXCCODE_LSXDIS 16 -+#define EXCCODE_LASXDIS 17 -+#define EXCCODE_FPE 18 -+#define EXCCODE_WATCH 19 -+#define EXCCODE_BTDIS 20 -+#define EXCCODE_BTE 21 -+#define EXCCODE_PSI 22 -+#define EXCCODE_HYP 23 -+#define EXCCODE_FC 24 -+#define EXCCODE_SE 25 -+ -+#define LOONGARCH_CSR_ERA 0x6 /* 64 error PC */ -+ -+#define LOONGARCH_CSR_BADV 0x7 /* 64 bad virtual address */ -+ -+#define LOONGARCH_CSR_BADI 0x8 /* 32 bad instruction */ -+ -+#define LOONGARCH_CSR_EEPN 0xc /* 64 exception enter base address */ -+#define LOONGARCH_EEPN_CPUID (0x3ffULL << 0) -+ -+#define CU_FPE 1 -+#define CU_LSXE (1 << 1) -+#define CU_LASXE (1 << 2) -+#define CU_LBTE (1 << 3) -+ -+/* TLB related CSR register : start with TLB if no pagewalk */ -+/* 32 TLB Index, EHINV, PageSize, is_gtlb */ -+#define LOONGARCH_CSR_TLBIDX 0x10 -+#define CSR_TLBIDX_EHINV_SHIFT 31 -+#define CSR_TLBIDX_EHINV (0x1ULL << CSR_TLBIDX_EHINV_SHIFT) -+#define CSR_TLBIDX_PS_SHIFT 24 -+#define CSR_TLBIDX_PS_WIDTH 6 -+#define CSR_TLBIDX_PS (0x3fULL << CSR_TLBIDX_PS_SHIFT) -+#define CSR_TLBIDX_IDX_SHIFT 0 -+#define CSR_TLBIDX_IDX_WIDTH 12 -+#define CSR_TLBIDX_IDX (0xfffULL << CSR_TLBIDX_IDX_SHIFT) -+#define CSR_TLBIDX_SIZEM 0x3f000000 -+#define CSR_TLBIDX_SIZE CSR_TLBIDX_PS_SHIFT -+#define CSR_TLBIDX_IDXM 0xfff -+ -+#define LOONGARCH_CSR_TLBEHI 0x11 /* 64 TLB EntryHi without ASID */ -+ -+#define LOONGARCH_CSR_TLBELO0 0x12 /* 64 TLB EntryLo0 */ -+#define CSR_TLBLO0_RPLV_SHIFT 63 -+#define CSR_TLBLO0_RPLV (0x1ULL << CSR_TLBLO0_RPLV_SHIFT) -+#define CSR_TLBLO0_XI_SHIFT 62 -+#define CSR_TLBLO0_XI (0x1ULL << CSR_TLBLO0_XI_SHIFT) -+#define CSR_TLBLO0_RI_SHIFT 61 -+#define CSR_TLBLO0_RI (0x1ULL << CSR_TLBLO0_RI_SHIFT) -+#define CSR_TLBLO0_PPN_SHIFT 12 -+#define CSR_TLBLO0_PPN_WIDTH 36 /* ignore lower 12bits */ -+#define CSR_TLBLO0_PPN (0xfffffffffULL << CSR_TLBLO0_PPN_SHIFT) -+#define CSR_TLBLO0_GLOBAL_SHIFT 6 -+#define CSR_TLBLO0_GLOBAL (0x1ULL << CSR_TLBLO0_GLOBAL_SHIFT) -+#define CSR_TLBLO0_CCA_SHIFT 4 -+#define CSR_TLBLO0_CCA_WIDTH 2 -+#define CSR_TLBLO0_CCA (0x3ULL << CSR_TLBLO0_CCA_SHIFT) -+#define CSR_TLBLO0_PLV_SHIFT 2 -+#define CSR_TLBLO0_PLV_WIDTH 2 -+#define CSR_TLBLO0_PLV (0x3ULL << CSR_TLBLO0_PLV_SHIFT) -+#define CSR_TLBLO0_WE_SHIFT 1 -+#define CSR_TLBLO0_WE (0x1ULL << CSR_TLBLO0_WE_SHIFT) -+#define CSR_TLBLO0_V_SHIFT 0 -+#define CSR_TLBLO0_V (0x1ULL << CSR_TLBLO0_V_SHIFT) -+ -+#define LOONGARCH_CSR_TLBELO1 0x13 /* 64 TLB EntryLo1 */ -+#define CSR_TLBLO1_RPLV_SHIFT 63 -+#define CSR_TLBLO1_RPLV (0x1ULL << CSR_TLBLO1_RPLV_SHIFT) -+#define CSR_TLBLO1_XI_SHIFT 62 -+#define CSR_TLBLO1_XI (0x1ULL << CSR_TLBLO1_XI_SHIFT) -+#define CSR_TLBLO1_RI_SHIFT 61 -+#define CSR_TLBLO1_RI (0x1ULL << CSR_TLBLO1_RI_SHIFT) -+#define CSR_TLBLO1_PPN_SHIFT 12 -+#define CSR_TLBLO1_PPN_WIDTH 36 /* ignore lower 12bits */ -+#define CSR_TLBLO1_PPN (0xfffffffffULL << CSR_TLBLO1_PPN_SHIFT) -+#define CSR_TLBLO1_GLOBAL_SHIFT 6 -+#define CSR_TLBLO1_GLOBAL (0x1ULL << CSR_TLBLO1_GLOBAL_SHIFT) -+#define CSR_TLBLO1_CCA_SHIFT 4 -+#define CSR_TLBLO1_CCA_WIDTH 2 -+#define CSR_TLBLO1_CCA (0x3ULL << CSR_TLBLO1_CCA_SHIFT) -+#define CSR_TLBLO1_PLV_SHIFT 2 -+#define CSR_TLBLO1_PLV_WIDTH 2 -+#define CSR_TLBLO1_PLV (0x3ULL << CSR_TLBLO1_PLV_SHIFT) -+#define CSR_TLBLO1_WE_SHIFT 1 -+#define CSR_TLBLO1_WE (0x1ULL << CSR_TLBLO1_WE_SHIFT) -+#define CSR_TLBLO1_V_SHIFT 0 -+#define CSR_TLBLO1_V (0x1ULL << CSR_TLBLO1_V_SHIFT) -+ -+#define LOONGARCH_ENTRYLO_RI (1ULL << 61) -+#define LOONGARCH_ENTRYLO_XI (1ULL << 62) -+ -+#define LOONGARCH_CSR_TLBWIRED 0x14 /* 32 TLB wired */ -+#define LOONGARCH_CSR_GTLBC 0x15 /* guest-related TLB */ -+#define CSR_GTLBC_RID_SHIFT 16 -+#define CSR_GTLBC_RID_WIDTH 8 -+#define CSR_GTLBC_RID (0xffULL << CSR_GTLBC_RID_SHIFT) -+#define CSR_GTLBC_TOTI_SHIFT 13 -+#define CSR_GTLBC_TOTI (0x1ULL << CSR_GTLBC_TOTI_SHIFT) -+#define CSR_GTLBC_USERID_SHIFT 12 -+#define CSR_GTLBC_USERID (0x1ULL << CSR_GTLBC_USERID_SHIFT) -+#define CSR_GTLBC_GMTLBSZ_SHIFT 0 -+#define CSR_GTLBC_GMTLBSZ_WIDTH 6 -+#define CSR_GTLBC_GMTLBSZ (0x3fULL << CSR_GTLBC_GVTLBSZ_SHIFT) -+ -+#define LOONGARCH_CSR_TRGP 0x16 /* guest-related TLB */ -+#define CSR_TRGP_RID_SHIFT 16 -+#define CSR_TRGP_RID_WIDTH 8 -+#define CSR_TRGP_RID (0xffULL << CSR_TRGP_RID_SHIFT) -+#define CSR_TRGP_GTLB_SHIFT 0 -+#define CSR_TRGP_GTLB (1 << CSR_TRGP_GTLB_SHIFT) -+ -+#define LOONGARCH_CSR_ASID 0x18 /* 64 ASID */ -+#define CSR_ASID_BIT_SHIFT 16 /* ASIDBits */ -+#define CSR_ASID_BIT_WIDTH 8 -+#define CSR_ASID_BIT (0xffULL << CSR_ASID_BIT_SHIFT) -+#define CSR_ASID_ASID_SHIFT 0 -+#define CSR_ASID_ASID_WIDTH 10 -+#define CSR_ASID_ASID (0x3ffULL << CSR_ASID_ASID_SHIFT) -+ -+/* 64 page table base address when badv[47] = 0 */ -+#define LOONGARCH_CSR_PGDL 0x19 -+/* 64 page table base address when badv[47] = 1 */ -+#define LOONGARCH_CSR_PGDH 0x1a -+ -+#define LOONGARCH_CSR_PGD 0x1b /* 64 page table base */ -+ -+#define LOONGARCH_CSR_PWCTL0 0x1c /* 64 PWCtl0 */ -+#define CSR_PWCTL0_PTEW_SHIFT 30 -+#define CSR_PWCTL0_PTEW_WIDTH 2 -+#define CSR_PWCTL0_PTEW (0x3ULL << CSR_PWCTL0_PTEW_SHIFT) -+#define CSR_PWCTL0_DIR1WIDTH_SHIFT 25 -+#define CSR_PWCTL0_DIR1WIDTH_WIDTH 5 -+#define CSR_PWCTL0_DIR1WIDTH (0x1fULL << CSR_PWCTL0_DIR1WIDTH_SHIFT) -+#define CSR_PWCTL0_DIR1BASE_SHIFT 20 -+#define CSR_PWCTL0_DIR1BASE_WIDTH 5 -+#define CSR_PWCTL0_DIR1BASE (0x1fULL << CSR_PWCTL0_DIR1BASE_SHIFT) -+#define CSR_PWCTL0_DIR0WIDTH_SHIFT 15 -+#define CSR_PWCTL0_DIR0WIDTH_WIDTH 5 -+#define CSR_PWCTL0_DIR0WIDTH (0x1fULL << CSR_PWCTL0_DIR0WIDTH_SHIFT) -+#define CSR_PWCTL0_DIR0BASE_SHIFT 10 -+#define CSR_PWCTL0_DIR0BASE_WIDTH 5 -+#define CSR_PWCTL0_DIR0BASE (0x1fULL << CSR_PWCTL0_DIR0BASE_SHIFT) -+#define CSR_PWCTL0_PTWIDTH_SHIFT 5 -+#define CSR_PWCTL0_PTWIDTH_WIDTH 5 -+#define CSR_PWCTL0_PTWIDTH (0x1fULL << CSR_PWCTL0_PTWIDTH_SHIFT) -+#define CSR_PWCTL0_PTBASE_SHIFT 0 -+#define CSR_PWCTL0_PTBASE_WIDTH 5 -+#define CSR_PWCTL0_PTBASE (0x1fULL << CSR_PWCTL0_PTBASE_SHIFT) -+ -+#define LOONGARCH_CSR_PWCTL1 0x1d /* 64 PWCtl1 */ -+#define CSR_PWCTL1_DIR3WIDTH_SHIFT 18 -+#define CSR_PWCTL1_DIR3WIDTH_WIDTH 5 -+#define CSR_PWCTL1_DIR3WIDTH (0x1fULL << CSR_PWCTL1_DIR3WIDTH_SHIFT) -+#define CSR_PWCTL1_DIR3BASE_SHIFT 12 -+#define CSR_PWCTL1_DIR3BASE_WIDTH 5 -+#define CSR_PWCTL1_DIR3BASE (0x1fULL << CSR_PWCTL0_DIR3BASE_SHIFT) -+#define CSR_PWCTL1_DIR2WIDTH_SHIFT 6 -+#define CSR_PWCTL1_DIR2WIDTH_WIDTH 5 -+#define CSR_PWCTL1_DIR2WIDTH (0x1fULL << CSR_PWCTL1_DIR2WIDTH_SHIFT) -+#define CSR_PWCTL1_DIR2BASE_SHIFT 0 -+#define CSR_PWCTL1_DIR2BASE_WIDTH 5 -+#define CSR_PWCTL1_DIR2BASE (0x1fULL << CSR_PWCTL0_DIR2BASE_SHIFT) -+ -+#define LOONGARCH_CSR_STLBPGSIZE 0x1e /* 64 */ -+#define CSR_STLBPGSIZE_PS_WIDTH 6 -+#define CSR_STLBPGSIZE_PS (0x3f) -+ -+#define LOONGARCH_CSR_RVACFG 0x1f -+#define CSR_RVACFG_RDVA_WIDTH 4 -+#define CSR_RVACFG_RDVA (0xf) -+ -+/* read only CSR register : start with CPU */ -+#define LOONGARCH_CSR_CPUID 0x20 /* 32 CPU core number */ -+#define CSR_CPUID_CID_WIDTH 9 -+#define CSR_CPUID_CID (0x1ff) -+ -+#define LOONGARCH_CSR_PRCFG1 0x21 /* 32 CPU info */ -+#define CSR_CONF1_VSMAX_SHIFT 12 -+#define CSR_CONF1_VSMAX_WIDTH 3 -+#define CSR_CONF1_VSMAX (7ULL << CSR_CONF1_VSMAX_SHIFT) -+/* stable timer bits - 1, 0x2f = 47*/ -+#define CSR_CONF1_TMRBITS_SHIFT 4 -+#define CSR_CONF1_TMRBITS_WIDTH 8 -+#define CSR_CONF1_TMRBITS (0xffULL << CSR_CONF1_TMRBITS_SHIFT) -+#define CSR_CONF1_KSNUM_SHIFT 0 -+#define CSR_CONF1_KSNUM_WIDTH 4 -+#define CSR_CONF1_KSNUM (0x8) -+ -+#define LOONGARCH_CSR_PRCFG2 0x22 -+#define CSR_CONF2_PGMASK_SUPP 0x3ffff000 -+ -+#define LOONGARCH_CSR_PRCFG3 0x23 -+#define CSR_CONF3_STLBIDX_SHIFT 20 -+#define CSR_CONF3_STLBIDX_WIDTH 6 -+#define CSR_CONF3_STLBIDX (0x3fULL << CSR_CONF3_STLBIDX_SHIFT) -+#define CSR_STLB_SETS 256 -+#define CSR_CONF3_STLBWAYS_SHIFT 12 -+#define CSR_CONF3_STLBWAYS_WIDTH 8 -+#define CSR_CONF3_STLBWAYS (0xffULL << CSR_CONF3_STLBWAYS_SHIFT) -+#define CSR_STLBWAYS_SIZE 8 -+#define CSR_CONF3_MTLBSIZE_SHIFT 4 -+#define CSR_CONF3_MTLBSIZE_WIDTH 8 -+#define CSR_CONF3_MTLBSIZE (0xffULL << CSR_CONF3_MTLBSIZE_SHIFT) -+/* mean VTLB 64 index */ -+#define CSR_MTLB_SIZE 64 -+#define CSR_CONF3_TLBORG_SHIFT 0 -+#define CSR_CONF3_TLBORG_WIDTH 4 -+#define CSR_CONF3_TLBORG (0xfULL << CSR_CONF3_TLBORG_SHIFT) -+/* mean use MTLB+STLB */ -+#define TLB_ORG 2 -+ -+/* Kscratch : start with KS */ -+#define LOONGARCH_CSR_KS0 0x30 /* 64 */ -+#define LOONGARCH_CSR_KS1 0x31 /* 64 */ -+#define LOONGARCH_CSR_KS2 0x32 /* 64 */ -+#define LOONGARCH_CSR_KS3 0x33 /* 64 */ -+#define LOONGARCH_CSR_KS4 0x34 /* 64 */ -+#define LOONGARCH_CSR_KS5 0x35 /* 64 */ -+#define LOONGARCH_CSR_KS6 0x36 /* 64 */ -+#define LOONGARCH_CSR_KS7 0x37 /* 64 */ -+#define LOONGARCH_CSR_KS8 0x38 /* 64 */ -+ -+/* timer : start with TM */ -+#define LOONGARCH_CSR_TMID 0x40 /* 32 timer ID */ -+ -+#define LOONGARCH_CSR_TCFG 0x41 /* 64 timer config */ -+#define CSR_TCFG_VAL_SHIFT 2 -+#define CSR_TCFG_VAL_WIDTH 48 -+#define CSR_TCFG_VAL (0x3fffffffffffULL << CSR_TCFG_VAL_SHIFT) -+#define CSR_TCFG_PERIOD_SHIFT 1 -+#define CSR_TCFG_PERIOD (0x1ULL << CSR_TCFG_PERIOD_SHIFT) -+#define CSR_TCFG_EN (0x1) -+ -+#define LOONGARCH_CSR_TVAL 0x42 /* 64 timer ticks remain */ -+ -+#define LOONGARCH_CSR_CNTC 0x43 /* 64 timer offset */ -+ -+#define LOONGARCH_CSR_TINTCLR 0x44 /* 64 timer interrupt clear */ -+#define CSR_TINTCLR_TI_SHIFT 0 -+#define CSR_TINTCLR_TI (1 << CSR_TINTCLR_TI_SHIFT) -+ -+/* guest : start with GST */ -+#define LOONGARCH_CSR_GSTAT 0x50 /* 32 basic guest info */ -+#define CSR_GSTAT_GID_SHIFT 16 -+#define CSR_GSTAT_GID_WIDTH 8 -+#define CSR_GSTAT_GID (0xffULL << CSR_GSTAT_GID_SHIFT) -+#define CSR_GSTAT_GIDBIT_SHIFT 4 -+#define CSR_GSTAT_GIDBIT_WIDTH 6 -+#define CSR_GSTAT_GIDBIT (0x3fULL << CSR_GSTAT_GIDBIT_SHIFT) -+#define CSR_GSTAT_PVM_SHIFT 1 -+#define CSR_GSTAT_PVM (0x1ULL << CSR_GSTAT_PVM_SHIFT) -+#define CSR_GSTAT_VM_SHIFT 0 -+#define CSR_GSTAT_VM (0x1ULL << CSR_GSTAT_VM_SHIFT) -+ -+#define LOONGARCH_CSR_GCFG 0x51 /* 32 guest config */ -+#define CSR_GCFG_GPERF_SHIFT 24 -+#define CSR_GCFG_GPERF_WIDTH 3 -+#define CSR_GCFG_GPERF (0x7ULL << CSR_GCFG_GPERF_SHIFT) -+#define CSR_GCFG_GCI_SHIFT 20 -+#define CSR_GCFG_GCI_WIDTH 2 -+#define CSR_GCFG_GCI (0x3ULL << CSR_GCFG_GCI_SHIFT) -+#define CSR_GCFG_GCI_ALL (0x0ULL << CSR_GCFG_GCI_SHIFT) -+#define CSR_GCFG_GCI_HIT (0x1ULL << CSR_GCFG_GCI_SHIFT) -+#define CSR_GCFG_GCI_SECURE (0x2ULL << CSR_GCFG_GCI_SHIFT) -+#define CSR_GCFG_GCIP_SHIFT 16 -+#define CSR_GCFG_GCIP (0xfULL << CSR_GCFG_GCIP_SHIFT) -+#define CSR_GCFG_GCIP_ALL (0x1ULL << CSR_GCFG_GCIP_SHIFT) -+#define CSR_GCFG_GCIP_HIT (0x1ULL << (CSR_GCFG_GCIP_SHIFT + 1)) -+#define CSR_GCFG_GCIP_SECURE (0x1ULL << (CSR_GCFG_GCIP_SHIFT + 2)) -+#define CSR_GCFG_TORU_SHIFT 15 -+#define CSR_GCFG_TORU (0x1ULL << CSR_GCFG_TORU_SHIFT) -+#define CSR_GCFG_TORUP_SHIFT 14 -+#define CSR_GCFG_TORUP (0x1ULL << CSR_GCFG_TORUP_SHIFT) -+#define CSR_GCFG_TOP_SHIFT 13 -+#define CSR_GCFG_TOP (0x1ULL << CSR_GCFG_TOP_SHIFT) -+#define CSR_GCFG_TOPP_SHIFT 12 -+#define CSR_GCFG_TOPP (0x1ULL << CSR_GCFG_TOPP_SHIFT) -+#define CSR_GCFG_TOE_SHIFT 11 -+#define CSR_GCFG_TOE (0x1ULL << CSR_GCFG_TOE_SHIFT) -+#define CSR_GCFG_TOEP_SHIFT 10 -+#define CSR_GCFG_TOEP (0x1ULL << CSR_GCFG_TOEP_SHIFT) -+#define CSR_GCFG_TIT_SHIFT 9 -+#define CSR_GCFG_TIT (0x1ULL << CSR_GCFG_TIT_SHIFT) -+#define CSR_GCFG_TITP_SHIFT 8 -+#define CSR_GCFG_TITP (0x1ULL << CSR_GCFG_TITP_SHIFT) -+#define CSR_GCFG_SIT_SHIFT 7 -+#define CSR_GCFG_SIT (0x1ULL << CSR_GCFG_SIT_SHIFT) -+#define CSR_GCFG_SITP_SHIFT 6 -+#define CSR_GCFG_SITP (0x1ULL << CSR_GCFG_SITP_SHIFT) -+#define CSR_GCFG_CACTRL_SHIFT 4 -+#define CSR_GCFG_CACTRL_WIDTH 2 -+#define CSR_GCFG_CACTRL (0x3ULL << CSR_GCFG_CACTRL_SHIFT) -+#define CSR_GCFG_CACTRL_GUEST (0x0ULL << CSR_GCFG_CACTRL_SHIFT) -+#define CSR_GCFG_CACTRL_ROOT (0x1ULL << CSR_GCFG_CACTRL_SHIFT) -+#define CSR_GCFG_CACTRL_NEST (0x2ULL << CSR_GCFG_CACTRL_SHIFT) -+#define CSR_GCFG_CCCP_WIDTH 4 -+#define CSR_GCFG_CCCP (0xf) -+#define CSR_GCFG_CCCP_GUEST (0x1ULL << 0) -+#define CSR_GCFG_CCCP_ROOT (0x1ULL << 1) -+#define CSR_GCFG_CCCP_NEST (0x1ULL << 2) -+ -+#define LOONGARCH_CSR_GINTC 0x52 /* 64 guest exception control */ -+#define CSR_GINTC_HC_SHIFT 16 -+#define CSR_GINTC_HC_WIDTH 8 -+#define CSR_GINTC_HC (0xffULL << CSR_GINTC_HC_SHIFT) -+#define CSR_GINTC_PIP_SHIFT 8 -+#define CSR_GINTC_PIP_WIDTH 8 -+#define CSR_GINTC_PIP (0xffULL << CSR_GINTC_PIP_SHIFT) -+#define CSR_GINTC_VIP_SHIFT 0 -+#define CSR_GINTC_VIP_WIDTH 8 -+#define CSR_GINTC_VIP (0xff) -+ -+#define LOONGARCH_CSR_GCNTC 0x53 /* 64 guest timer offset */ -+ -+/* LLBCTL */ -+#define LOONGARCH_CSR_LLBCTL 0x60 /* 32 csr number to be changed */ -+#define CSR_LLBCTL_ROLLB_SHIFT 0 -+#define CSR_LLBCTL_ROLLB (1ULL << CSR_LLBCTL_ROLLB_SHIFT) -+#define CSR_LLBCTL_WCLLB_SHIFT 1 -+#define CSR_LLBCTL_WCLLB (1ULL << CSR_LLBCTL_WCLLB_SHIFT) -+#define CSR_LLBCTL_KLO_SHIFT 2 -+#define CSR_LLBCTL_KLO (1ULL << CSR_LLBCTL_KLO_SHIFT) -+ -+/* implement dependent */ -+#define LOONGARCH_CSR_IMPCTL1 0x80 /* 32 loongarch config */ -+#define CSR_MISPEC_SHIFT 20 -+#define CSR_MISPEC_WIDTH 8 -+#define CSR_MISPEC (0xffULL << CSR_MISPEC_SHIFT) -+#define CSR_SSEN_SHIFT 18 -+#define CSR_SSEN (1ULL << CSR_SSEN_SHIFT) -+#define CSR_SCRAND_SHIFT 17 -+#define CSR_SCRAND (1ULL << CSR_SCRAND_SHIFT) -+#define CSR_LLEXCL_SHIFT 16 -+#define CSR_LLEXCL (1ULL << CSR_LLEXCL_SHIFT) -+#define CSR_DISVC_SHIFT 15 -+#define CSR_DISVC (1ULL << CSR_DISVC_SHIFT) -+#define CSR_VCLRU_SHIFT 14 -+#define CSR_VCLRU (1ULL << CSR_VCLRU_SHIFT) -+#define CSR_DCLRU_SHIFT 13 -+#define CSR_DCLRU (1ULL << CSR_DCLRU_SHIFT) -+#define CSR_FASTLDQ_SHIFT 12 -+#define CSR_FASTLDQ (1ULL << CSR_FASTLDQ_SHIFT) -+#define CSR_USERCAC_SHIFT 11 -+#define CSR_USERCAC (1ULL << CSR_USERCAC_SHIFT) -+#define CSR_ANTI_MISPEC_SHIFT 10 -+#define CSR_ANTI_MISPEC (1ULL << CSR_ANTI_MISPEC_SHIFT) -+#define CSR_ANTI_FLUSHSFB_SHIFT 9 -+#define CSR_ANTI_FLUSHSFB (1ULL << CSR_ANTI_FLUSHSFB_SHIFT) -+#define CSR_STFILL_SHIFT 8 -+#define CSR_STFILL (1ULL << CSR_STFILL_SHIFT) -+#define CSR_LIFEP_SHIFT 7 -+#define CSR_LIFEP (1ULL << CSR_LIFEP_SHIFT) -+#define CSR_LLSYNC_SHIFT 6 -+#define CSR_LLSYNC (1ULL << CSR_LLSYNC_SHIFT) -+#define CSR_BRBTDIS_SHIFT 5 -+#define CSR_BRBTDIS (1ULL << CSR_BRBTDIS_SHIFT) -+#define CSR_RASDIS_SHIFT 4 -+#define CSR_RASDIS (1ULL << CSR_RASDIS_SHIFT) -+#define CSR_STPRE_SHIFT 2 -+#define CSR_STPRE_WIDTH 2 -+#define CSR_STPRE (3ULL << CSR_STPRE_SHIFT) -+#define CSR_INSTPRE_SHIFT 1 -+#define CSR_INSTPRE (1ULL << CSR_INSTPRE_SHIFT) -+#define CSR_DATAPRE_SHIFT 0 -+#define CSR_DATAPRE (1ULL << CSR_DATAPRE_SHIFT) -+ -+#define LOONGARCH_CSR_IMPCTL2 0x81 /* 32 Flush */ -+#define CSR_IMPCTL2_MTLB_SHIFT 0 -+#define CSR_IMPCTL2_MTLB (1ULL << CSR_IMPCTL2_MTLB_SHIFT) -+#define CSR_IMPCTL2_STLB_SHIFT 1 -+#define CSR_IMPCTL2_STLB (1ULL << CSR_IMPCTL2_STLB_SHIFT) -+#define CSR_IMPCTL2_DTLB_SHIFT 2 -+#define CSR_IMPCTL2_DTLB (1ULL << CSR_IMPCTL2_DTLB_SHIFT) -+#define CSR_IMPCTL2_ITLB_SHIFT 3 -+#define CSR_IMPCTL2_ITLB (1ULL << CSR_IMPCTL2_ITLB_SHIFT) -+#define CSR_IMPCTL2_BTAC_SHIFT 4 -+#define CSR_IMPCTL2_BTAC (1ULL << CSR_IMPCTL2_BTAC_SHIFT) -+ -+#define LOONGARCH_FLUSH_VTLB 1 -+#define LOONGARCH_FLUSH_FTLB (1 << 1) -+#define LOONGARCH_FLUSH_DTLB (1 << 2) -+#define LOONGARCH_FLUSH_ITLB (1 << 3) -+#define LOONGARCH_FLUSH_BTAC (1 << 4) -+ -+#define LOONGARCH_CSR_GNMI 0x82 -+ -+/* TLB Refill Only */ -+#define LOONGARCH_CSR_TLBRENT 0x88 /* 64 TLB refill exception address */ -+#define LOONGARCH_CSR_TLBRBADV 0x89 /* 64 TLB refill badvaddr */ -+#define LOONGARCH_CSR_TLBRERA 0x8a /* 64 TLB refill ERA */ -+#define LOONGARCH_CSR_TLBRSAVE 0x8b /* 64 KScratch for TLB refill */ -+#define LOONGARCH_CSR_TLBRELO0 0x8c /* 64 TLB refill entrylo0 */ -+#define LOONGARCH_CSR_TLBRELO1 0x8d /* 64 TLB refill entrylo1 */ -+#define LOONGARCH_CSR_TLBREHI 0x8e /* 64 TLB refill entryhi */ -+#define LOONGARCH_CSR_TLBRPRMD 0x8f /* 64 TLB refill mode info */ -+ -+/* error related */ -+#define LOONGARCH_CSR_ERRCTL 0x90 /* 32 ERRCTL */ -+#define LOONGARCH_CSR_ERRINFO 0x91 -+#define LOONGARCH_CSR_ERRINFO1 0x92 -+#define LOONGARCH_CSR_ERRENT 0x93 /* 64 error exception base */ -+#define LOONGARCH_CSR_ERRERA 0x94 /* 64 error exception PC */ -+#define LOONGARCH_CSR_ERRSAVE 0x95 /* 64 KScratch for error exception */ -+ -+#define LOONGARCH_CSR_CTAG 0x98 /* 64 TagLo + TagHi */ -+ -+/* direct map windows */ -+#define LOONGARCH_CSR_DMWIN0 0x180 /* 64 direct map win0: MEM & IF */ -+#define LOONGARCH_CSR_DMWIN1 0x181 /* 64 direct map win1: MEM & IF */ -+#define LOONGARCH_CSR_DMWIN2 0x182 /* 64 direct map win2: MEM */ -+#define LOONGARCH_CSR_DMWIN3 0x183 /* 64 direct map win3: MEM */ -+#define CSR_DMW_PLV0 0x1 -+#define CSR_DMW_PLV1 0x2 -+#define CSR_DMW_PLV2 0x4 -+#define CSR_DMW_PLV3 0x8 -+#define CSR_DMW_BASE_SH 48 -+#define dmwin_va2pa(va) \ -+ (va & (((unsigned long)1 << CSR_DMW_BASE_SH) - 1)) -+ -+/* performance counter */ -+#define LOONGARCH_CSR_PERFCTRL0 0x200 /* 32 perf event 0 config */ -+#define LOONGARCH_CSR_PERFCNTR0 0x201 /* 64 perf event 0 count value */ -+#define LOONGARCH_CSR_PERFCTRL1 0x202 /* 32 perf event 1 config */ -+#define LOONGARCH_CSR_PERFCNTR1 0x203 /* 64 perf event 1 count value */ -+#define LOONGARCH_CSR_PERFCTRL2 0x204 /* 32 perf event 2 config */ -+#define LOONGARCH_CSR_PERFCNTR2 0x205 /* 64 perf event 2 count value */ -+#define LOONGARCH_CSR_PERFCTRL3 0x206 /* 32 perf event 3 config */ -+#define LOONGARCH_CSR_PERFCNTR3 0x207 /* 64 perf event 3 count value */ -+#define CSR_PERFCTRL_PLV0 (1ULL << 16) -+#define CSR_PERFCTRL_PLV1 (1ULL << 17) -+#define CSR_PERFCTRL_PLV2 (1ULL << 18) -+#define CSR_PERFCTRL_PLV3 (1ULL << 19) -+#define CSR_PERFCTRL_IE (1ULL << 20) -+#define CSR_PERFCTRL_EVENT 0x3ff -+ -+/* debug */ -+#define LOONGARCH_CSR_MWPC 0x300 /* data breakpoint config */ -+#define LOONGARCH_CSR_MWPS 0x301 /* data breakpoint status */ -+ -+#define LOONGARCH_CSR_DB0ADDR 0x310 /* data breakpoint 0 address */ -+#define LOONGARCH_CSR_DB0MASK 0x311 /* data breakpoint 0 mask */ -+#define LOONGARCH_CSR_DB0CTL 0x312 /* data breakpoint 0 control */ -+#define LOONGARCH_CSR_DB0ASID 0x313 /* data breakpoint 0 asid */ -+ -+#define LOONGARCH_CSR_DB1ADDR 0x318 /* data breakpoint 1 address */ -+#define LOONGARCH_CSR_DB1MASK 0x319 /* data breakpoint 1 mask */ -+#define LOONGARCH_CSR_DB1CTL 0x31a /* data breakpoint 1 control */ -+#define LOONGARCH_CSR_DB1ASID 0x31b /* data breakpoint 1 asid */ -+ -+#define LOONGARCH_CSR_DB2ADDR 0x320 /* data breakpoint 2 address */ -+#define LOONGARCH_CSR_DB2MASK 0x321 /* data breakpoint 2 mask */ -+#define LOONGARCH_CSR_DB2CTL 0x322 /* data breakpoint 2 control */ -+#define LOONGARCH_CSR_DB2ASID 0x323 /* data breakpoint 2 asid */ -+ -+#define LOONGARCH_CSR_DB3ADDR 0x328 /* data breakpoint 3 address */ -+#define LOONGARCH_CSR_DB3MASK 0x329 /* data breakpoint 3 mask */ -+#define LOONGARCH_CSR_DB3CTL 0x32a /* data breakpoint 3 control */ -+#define LOONGARCH_CSR_DB3ASID 0x32b /* data breakpoint 3 asid */ -+ -+#define LOONGARCH_CSR_FWPC 0x380 /* instruction breakpoint config */ -+#define LOONGARCH_CSR_FWPS 0x381 /* instruction breakpoint status */ -+ -+#define LOONGARCH_CSR_IB0ADDR 0x390 /* inst breakpoint 0 address */ -+#define LOONGARCH_CSR_IB0MASK 0x391 /* inst breakpoint 0 mask */ -+#define LOONGARCH_CSR_IB0CTL 0x392 /* inst breakpoint 0 control */ -+#define LOONGARCH_CSR_IB0ASID 0x393 /* inst breakpoint 0 asid */ -+#define LOONGARCH_CSR_IB1ADDR 0x398 /* inst breakpoint 1 address */ -+#define LOONGARCH_CSR_IB1MASK 0x399 /* inst breakpoint 1 mask */ -+#define LOONGARCH_CSR_IB1CTL 0x39a /* inst breakpoint 1 control */ -+#define LOONGARCH_CSR_IB1ASID 0x39b /* inst breakpoint 1 asid */ -+ -+#define LOONGARCH_CSR_IB2ADDR 0x3a0 /* inst breakpoint 2 address */ -+#define LOONGARCH_CSR_IB2MASK 0x3a1 /* inst breakpoint 2 mask */ -+#define LOONGARCH_CSR_IB2CTL 0x3a2 /* inst breakpoint 2 control */ -+#define LOONGARCH_CSR_IB2ASID 0x3a3 /* inst breakpoint 2 asid */ -+ -+#define LOONGARCH_CSR_IB3ADDR 0x3a8 /* inst breakpoint 3 address */ -+#define LOONGARCH_CSR_IB3MASK 0x3a9 /* inst breakpoint 3 mask */ -+#define LOONGARCH_CSR_IB3CTL 0x3aa /* inst breakpoint 3 control */ -+#define LOONGARCH_CSR_IB3ASID 0x3ab /* inst breakpoint 3 asid */ -+ -+#define LOONGARCH_CSR_IB4ADDR 0x3b0 /* inst breakpoint 4 address */ -+#define LOONGARCH_CSR_IB4MASK 0x3b1 /* inst breakpoint 4 mask */ -+#define LOONGARCH_CSR_IB4CTL 0x3b2 /* inst breakpoint 4 control */ -+#define LOONGARCH_CSR_IB4ASID 0x3b3 /* inst breakpoint 4 asid */ -+ -+#define LOONGARCH_CSR_IB5ADDR 0x3b8 /* inst breakpoint 5 address */ -+#define LOONGARCH_CSR_IB5MASK 0x3b9 /* inst breakpoint 5 mask */ -+#define LOONGARCH_CSR_IB5CTL 0x3ba /* inst breakpoint 5 control */ -+#define LOONGARCH_CSR_IB5ASID 0x3bb /* inst breakpoint 5 asid */ -+ -+#define LOONGARCH_CSR_IB6ADDR 0x3c0 /* inst breakpoint 6 address */ -+#define LOONGARCH_CSR_IB6MASK 0x3c1 /* inst breakpoint 6 mask */ -+#define LOONGARCH_CSR_IB6CTL 0x3c2 /* inst breakpoint 6 control */ -+#define LOONGARCH_CSR_IB6ASID 0x3c3 /* inst breakpoint 6 asid */ -+ -+#define LOONGARCH_CSR_IB7ADDR 0x3c8 /* inst breakpoint 7 address */ -+#define LOONGARCH_CSR_IB7MASK 0x3c9 /* inst breakpoint 7 mask */ -+#define LOONGARCH_CSR_IB7CTL 0x3ca /* inst breakpoint 7 control */ -+#define LOONGARCH_CSR_IB7ASID 0x3cb /* inst breakpoint 7 asid */ -+ -+#define LOONGARCH_CSR_DEBUG 0x500 /* debug config */ -+#define CSR_DEBUG_DM 0 -+#define CSR_DEBUG_DMVER 1 -+#define CSR_DEBUG_DINT 8 -+#define CSR_DEBUG_DBP 9 -+#define CSR_DEBUG_DIB 10 -+#define CSR_DEBUG_DDB 11 -+ -+#define LOONGARCH_CSR_DERA 0x501 /* debug era */ -+#define LOONGARCH_CSR_DESAVE 0x502 /* debug save */ -+ -+#define LOONGARCH_CSR_PRID 0xc0 /* 32 LOONGARCH CP0 PRID */ -+ -+#define LOONGARCH_CPUCFG0 0x0 -+#define CPUCFG0_3A5000_PRID 0x0014c010 -+ -+#define LOONGARCH_CPUCFG1 0x1 -+#define CPUCFG1_ISGR32 BIT(0) -+#define CPUCFG1_ISGR64 BIT(1) -+#define CPUCFG1_PAGING BIT(2) -+#define CPUCFG1_IOCSR BIT(3) -+#define CPUCFG1_PABITS (47 << 4) -+#define CPUCFG1_VABITS (47 << 12) -+#define CPUCFG1_UAL BIT(20) -+#define CPUCFG1_RI BIT(21) -+#define CPUCFG1_XI BIT(22) -+#define CPUCFG1_RPLV BIT(23) -+#define CPUCFG1_HUGEPG BIT(24) -+#define CPUCFG1_IOCSRBRD BIT(25) -+#define CPUCFG1_MSGINT BIT(26) -+ -+#define LOONGARCH_CPUCFG2 0x2 -+#define CPUCFG2_FP BIT(0) -+#define CPUCFG2_FPSP BIT(1) -+#define CPUCFG2_FPDP BIT(2) -+#define CPUCFG2_FPVERS (0 << 3) -+#define CPUCFG2_LSX BIT(6) -+#define CPUCFG2_LASX BIT(7) -+#define CPUCFG2_COMPLEX BIT(8) -+#define CPUCFG2_CRYPTO BIT(9) -+#define CPUCFG2_LVZP BIT(10) -+#define CPUCFG2_LVZVER (0 << 11) -+#define CPUCFG2_LLFTP BIT(14) -+#define CPUCFG2_LLFTPREV (1 << 15) -+#define CPUCFG2_X86BT BIT(18) -+#define CPUCFG2_ARMBT BIT(19) -+#define CPUCFG2_MIPSBT BIT(20) -+#define CPUCFG2_LSPW BIT(21) -+#define CPUCFG2_LAM BIT(22) -+ -+#define LOONGARCH_CPUCFG3 0x3 -+#define CPUCFG3_CCDMA BIT(0) -+#define CPUCFG3_SFB BIT(1) -+#define CPUCFG3_UCACC BIT(2) -+#define CPUCFG3_LLEXC BIT(3) -+#define CPUCFG3_SCDLY BIT(4) -+#define CPUCFG3_LLDBAR BIT(5) -+#define CPUCFG3_ITLBT BIT(6) -+#define CPUCFG3_ICACHET BIT(7) -+#define CPUCFG3_SPW_LVL (4 << 8) -+#define CPUCFG3_SPW_HG_HF BIT(11) -+#define CPUCFG3_RVA BIT(12) -+#define CPUCFG3_RVAMAX (7 << 13) -+ -+#define LOONGARCH_CPUCFG4 0x4 -+#define CCFREQ_100M 100000000 /* 100M */ -+ -+#define LOONGARCH_CPUCFG5 0x5 -+#define CPUCFG5_CCMUL 1 -+#define CPUCFG5_CCDIV (1 << 16) -+ -+#define LOONGARCH_CPUCFG6 0x6 -+#define CPUCFG6_PMP BIT(0) -+#define CPUCFG6_PAMVER (1 << 1) -+#define CPUCFG6_PMNUM (3 << 4) -+#define CPUCFG6_PMBITS (63 << 8) -+#define CPUCFG6_UPM BIT(14) -+ -+#define LOONGARCH_CPUCFG16 0x10 -+#define CPUCFG16_L1_IUPRE BIT(0) -+#define CPUCFG16_L1_UNIFY BIT(1) -+#define CPUCFG16_L1_DPRE BIT(2) -+#define CPUCFG16_L2_IUPRE BIT(3) -+#define CPUCFG16_L2_IUUNIFY BIT(4) -+#define CPUCFG16_L2_IUPRIV BIT(5) -+#define CPUCFG16_L2_IUINCL BIT(6) -+#define CPUCFG16_L2_DPRE BIT(7) -+#define CPUCFG16_L2_DPRIV BIT(8) -+#define CPUCFG16_L2_DINCL BIT(9) -+#define CPUCFG16_L3_IUPRE BIT(10) -+#define CPUCFG16_L3_IUUNIFY BIT(11) -+#define CPUCFG16_L3_IUPRIV BIT(12) -+#define CPUCFG16_L3_IUINCL BIT(13) -+#define CPUCFG16_L3_DPRE BIT(14) -+#define CPUCFG16_L3_DPRIV BIT(15) -+#define CPUCFG16_L3_DINCL BIT(16) -+ -+#define LOONGARCH_CPUCFG17 0x11 -+#define CPUCFG17_L1I_WAYS_M (3 << 0) -+#define CPUCFG17_L1I_SETS_M (8 << 16) -+#define CPUCFG17_L1I_SIZE_M (6 << 24) -+ -+#define LOONGARCH_CPUCFG18 0x12 -+#define CPUCFG18_L1D_WAYS_M (3 << 0) -+#define CPUCFG18_L1D_SETS_M (8 << 16) -+#define CPUCFG18_L1D_SIZE_M (6 << 24) -+ -+#define LOONGARCH_CPUCFG19 0x13 -+#define CPUCFG19_L2_WAYS_M (0xf << 0) -+#define CPUCFG19_L2_SETS_M (8 << 16) -+#define CPUCFG19_L2_SIZE_M (6 << 24) -+ -+#define LOONGARCH_CPUCFG20 0x14 -+#define CPUCFG20_L3_WAYS_M (0xf << 0) -+#define CPUCFG20_L3_SETS_M (0xe << 16) -+#define CPUCFG20_L3_SIZE_M (0x6 << 24) -+ -+#define LOONGARCH_PAGE_HUGE 0x40 -+#define LOONGARCH_HUGE_GLOBAL 0x1000 -+#define LOONGARCH_HUGE_GLOBAL_SH 12 -+ -+/* All CSR register -+ * -+ * default value in target/loongarch/cpu.c -+ * reset function in target/loongarch/translate.c:cpu_state_reset() -+ * -+ * This macro will be used only twice. -+ * > In target/loongarch/cpu.h:CPULOONGARCHState -+ * > In target/loongarch/internal.h:loongarch_def_t -+ * -+ * helper_function to rd/wr: -+ * > declare in target/loongarch/helper.h -+ * > realize in target/loongarch/op_helper.c -+ * -+ * during translate: -+ * > gen_csr_rdl() -+ * > gen_csr_wrl() -+ * > gen_csr_rdq() -+ * > gen_csr_wrq() -+ */ -+#define CPU_LOONGARCH_CSR \ -+ uint64_t CSR_CRMD; \ -+ uint64_t CSR_PRMD; \ -+ uint64_t CSR_EUEN; \ -+ uint64_t CSR_MISC; \ -+ uint64_t CSR_ECFG; \ -+ uint64_t CSR_ESTAT; \ -+ uint64_t CSR_ERA; \ -+ uint64_t CSR_BADV; \ -+ uint64_t CSR_BADI; \ -+ uint64_t CSR_EEPN; \ -+ uint64_t CSR_TLBIDX; \ -+ uint64_t CSR_TLBEHI; \ -+ uint64_t CSR_TLBELO0; \ -+ uint64_t CSR_TLBELO1; \ -+ uint64_t CSR_TLBWIRED; \ -+ uint64_t CSR_GTLBC; \ -+ uint64_t CSR_TRGP; \ -+ uint64_t CSR_ASID; \ -+ uint64_t CSR_PGDL; \ -+ uint64_t CSR_PGDH; \ -+ uint64_t CSR_PGD; \ -+ uint64_t CSR_PWCTL0; \ -+ uint64_t CSR_PWCTL1; \ -+ uint64_t CSR_STLBPGSIZE; \ -+ uint64_t CSR_RVACFG; \ -+ uint64_t CSR_CPUID; \ -+ uint64_t CSR_PRCFG1; \ -+ uint64_t CSR_PRCFG2; \ -+ uint64_t CSR_PRCFG3; \ -+ uint64_t CSR_KS0; \ -+ uint64_t CSR_KS1; \ -+ uint64_t CSR_KS2; \ -+ uint64_t CSR_KS3; \ -+ uint64_t CSR_KS4; \ -+ uint64_t CSR_KS5; \ -+ uint64_t CSR_KS6; \ -+ uint64_t CSR_KS7; \ -+ uint64_t CSR_KS8; \ -+ uint64_t CSR_TMID; \ -+ uint64_t CSR_TCFG; \ -+ uint64_t CSR_TVAL; \ -+ uint64_t CSR_CNTC; \ -+ uint64_t CSR_TINTCLR; \ -+ uint64_t CSR_GSTAT; \ -+ uint64_t CSR_GCFG; \ -+ uint64_t CSR_GINTC; \ -+ uint64_t CSR_GCNTC; \ -+ uint64_t CSR_LLBCTL; \ -+ uint64_t CSR_IMPCTL1; \ -+ uint64_t CSR_IMPCTL2; \ -+ uint64_t CSR_GNMI; \ -+ uint64_t CSR_TLBRENT; \ -+ uint64_t CSR_TLBRBADV; \ -+ uint64_t CSR_TLBRERA; \ -+ uint64_t CSR_TLBRSAVE; \ -+ uint64_t CSR_TLBRELO0; \ -+ uint64_t CSR_TLBRELO1; \ -+ uint64_t CSR_TLBREHI; \ -+ uint64_t CSR_TLBRPRMD; \ -+ uint64_t CSR_ERRCTL; \ -+ uint64_t CSR_ERRINFO; \ -+ uint64_t CSR_ERRINFO1; \ -+ uint64_t CSR_ERRENT; \ -+ uint64_t CSR_ERRERA; \ -+ uint64_t CSR_ERRSAVE; \ -+ uint64_t CSR_CTAG; \ -+ uint64_t CSR_DMWIN0; \ -+ uint64_t CSR_DMWIN1; \ -+ uint64_t CSR_DMWIN2; \ -+ uint64_t CSR_DMWIN3; \ -+ uint64_t CSR_PERFCTRL0; \ -+ uint64_t CSR_PERFCNTR0; \ -+ uint64_t CSR_PERFCTRL1; \ -+ uint64_t CSR_PERFCNTR1; \ -+ uint64_t CSR_PERFCTRL2; \ -+ uint64_t CSR_PERFCNTR2; \ -+ uint64_t CSR_PERFCTRL3; \ -+ uint64_t CSR_PERFCNTR3; \ -+ uint64_t CSR_MWPC; \ -+ uint64_t CSR_MWPS; \ -+ uint64_t CSR_DB0ADDR; \ -+ uint64_t CSR_DB0MASK; \ -+ uint64_t CSR_DB0CTL; \ -+ uint64_t CSR_DB0ASID; \ -+ uint64_t CSR_DB1ADDR; \ -+ uint64_t CSR_DB1MASK; \ -+ uint64_t CSR_DB1CTL; \ -+ uint64_t CSR_DB1ASID; \ -+ uint64_t CSR_DB2ADDR; \ -+ uint64_t CSR_DB2MASK; \ -+ uint64_t CSR_DB2CTL; \ -+ uint64_t CSR_DB2ASID; \ -+ uint64_t CSR_DB3ADDR; \ -+ uint64_t CSR_DB3MASK; \ -+ uint64_t CSR_DB3CTL; \ -+ uint64_t CSR_DB3ASID; \ -+ uint64_t CSR_FWPC; \ -+ uint64_t CSR_FWPS; \ -+ uint64_t CSR_IB0ADDR; \ -+ uint64_t CSR_IB0MASK; \ -+ uint64_t CSR_IB0CTL; \ -+ uint64_t CSR_IB0ASID; \ -+ uint64_t CSR_IB1ADDR; \ -+ uint64_t CSR_IB1MASK; \ -+ uint64_t CSR_IB1CTL; \ -+ uint64_t CSR_IB1ASID; \ -+ uint64_t CSR_IB2ADDR; \ -+ uint64_t CSR_IB2MASK; \ -+ uint64_t CSR_IB2CTL; \ -+ uint64_t CSR_IB2ASID; \ -+ uint64_t CSR_IB3ADDR; \ -+ uint64_t CSR_IB3MASK; \ -+ uint64_t CSR_IB3CTL; \ -+ uint64_t CSR_IB3ASID; \ -+ uint64_t CSR_IB4ADDR; \ -+ uint64_t CSR_IB4MASK; \ -+ uint64_t CSR_IB4CTL; \ -+ uint64_t CSR_IB4ASID; \ -+ uint64_t CSR_IB5ADDR; \ -+ uint64_t CSR_IB5MASK; \ -+ uint64_t CSR_IB5CTL; \ -+ uint64_t CSR_IB5ASID; \ -+ uint64_t CSR_IB6ADDR; \ -+ uint64_t CSR_IB6MASK; \ -+ uint64_t CSR_IB6CTL; \ -+ uint64_t CSR_IB6ASID; \ -+ uint64_t CSR_IB7ADDR; \ -+ uint64_t CSR_IB7MASK; \ -+ uint64_t CSR_IB7CTL; \ -+ uint64_t CSR_IB7ASID; \ -+ uint64_t CSR_DEBUG; \ -+ uint64_t CSR_DERA; \ -+ uint64_t CSR_DESAVE; \ -+ -+#define LOONGARCH_CSR_32(_R, _S) \ -+ (KVM_REG_LOONGARCH_CSR | KVM_REG_SIZE_U32 | (8 * (_R) + (_S))) -+ -+#define LOONGARCH_CSR_64(_R, _S) \ -+ (KVM_REG_LOONGARCH_CSR | KVM_REG_SIZE_U64 | (8 * (_R) + (_S))) -+ -+#define KVM_IOC_CSRID(id) LOONGARCH_CSR_64(id, 0) -+ -+#endif -diff --git a/target/loongarch64/cpu-param.h b/target/loongarch64/cpu-param.h -new file mode 100644 -index 000000000..24ca458af ---- /dev/null -+++ b/target/loongarch64/cpu-param.h -@@ -0,0 +1,30 @@ -+#ifndef CPU_PARAM_H -+#define CPU_PARAM_H -+ -+/* If we want to use host float regs... */ -+/* #define USE_HOST_FLOAT_REGS */ -+ -+/* Real pages are variable size... */ -+#define TARGET_PAGE_BITS 14 -+ -+#define LOONGARCH_TLB_MAX 2112 -+ -+#define TARGET_LONG_BITS 64 -+#define TARGET_PHYS_ADDR_SPACE_BITS 48 -+#define TARGET_VIRT_ADDR_SPACE_BITS 48 -+ -+/* -+ * bit definitions for insn_flags (ISAs/ASEs flags) -+ * ------------------------------------------------ -+ */ -+#define ISA_LARCH32 0x00000001ULL -+#define ISA_LARCH64 0x00000002ULL -+#define INSN_LOONGARCH 0x00010000ULL -+ -+#define CPU_LARCH32 (ISA_LARCH32) -+#define CPU_LARCH64 (ISA_LARCH32 | ISA_LARCH64) -+ -+#define NB_MMU_MODES 4 -+ -+#endif /* QEMU_LOONGARCH_DEFS_H */ -+ -diff --git a/target/loongarch64/cpu-qom.h b/target/loongarch64/cpu-qom.h -new file mode 100644 -index 000000000..ee9c1de57 ---- /dev/null -+++ b/target/loongarch64/cpu-qom.h -@@ -0,0 +1,54 @@ -+/* -+ * QEMU LOONGARCH 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 -+ * -+ */ -+#ifndef QEMU_LOONGARCH_CPU_QOM_H -+#define QEMU_LOONGARCH_CPU_QOM_H -+ -+#include "hw/core/cpu.h" -+ -+#define TYPE_LOONGARCH_CPU "loongarch-cpu" -+ -+#define LOONGARCH_CPU_CLASS(klass) \ -+ OBJECT_CLASS_CHECK(LOONGARCHCPUClass, (klass), TYPE_LOONGARCH_CPU) -+#define LOONGARCH_CPU(obj) \ -+ OBJECT_CHECK(LOONGARCHCPU, (obj), TYPE_LOONGARCH_CPU) -+#define LOONGARCH_CPU_GET_CLASS(obj) \ -+ OBJECT_GET_CLASS(LOONGARCHCPUClass, (obj), TYPE_LOONGARCH_CPU) -+ -+/** -+ * LOONGARCHCPUClass: -+ * @parent_realize: The parent class' realize handler. -+ * @parent_reset: The parent class' reset handler. -+ * -+ * A LOONGARCH CPU model. -+ */ -+typedef struct LOONGARCHCPUClass { -+ /*< private >*/ -+ CPUClass parent_class; -+ /*< public >*/ -+ -+ DeviceRealize parent_realize; -+ DeviceUnrealize parent_unrealize; -+ DeviceReset parent_reset; -+ const struct loongarch_def_t *cpu_def; -+} LOONGARCHCPUClass; -+ -+typedef struct LOONGARCHCPU LOONGARCHCPU; -+ -+#endif -diff --git a/target/loongarch64/cpu.c b/target/loongarch64/cpu.c -new file mode 100644 -index 000000000..a4535d34a ---- /dev/null -+++ b/target/loongarch64/cpu.c -@@ -0,0 +1,576 @@ -+/* -+ * QEMU LOONGARCH 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 -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include "qapi/visitor.h" -+#include "cpu.h" -+#include "internal.h" -+#include "kvm_larch.h" -+#include "qemu-common.h" -+#include "hw/qdev-properties.h" -+#include "sysemu/kvm.h" -+#include "exec/exec-all.h" -+#include "sysemu/arch_init.h" -+#include "cpu-csr.h" -+#include "qemu/qemu-print.h" -+#include "qapi/qapi-commands-machine-target.h" -+#ifdef CONFIG_TCG -+#include "hw/core/tcg-cpu-ops.h" -+#endif /* CONFIG_TCG */ -+ -+#define LOONGARCH_CONFIG1 \ -+((0x8 << CSR_CONF1_KSNUM_SHIFT) | (0x2f << CSR_CONF1_TMRBITS_SHIFT) | \ -+ (0x7 << CSR_CONF1_VSMAX_SHIFT)) -+ -+#define LOONGARCH_CONFIG3 \ -+((0x2 << CSR_CONF3_TLBORG_SHIFT) | (0x3f << CSR_CONF3_MTLBSIZE_SHIFT) | \ -+ (0x7 << CSR_CONF3_STLBWAYS_SHIFT) | (0x8 << CSR_CONF3_STLBIDX_SHIFT)) -+ -+/*****************************************************************************/ -+/* LOONGARCH CPU definitions */ -+const loongarch_def_t loongarch_defs[] = { -+ { -+ .name = "Loongson-3A5000", -+ -+ /* for LoongISA CSR */ -+ .CSR_PRCFG1 = LOONGARCH_CONFIG1, -+ .CSR_PRCFG2 = 0x3ffff000, -+ .CSR_PRCFG3 = LOONGARCH_CONFIG3, -+ .CSR_CRMD = (0 << CSR_CRMD_PLV_SHIFT) | (0 << CSR_CRMD_IE_SHIFT) | -+ (1 << CSR_CRMD_DA_SHIFT) | (0 << CSR_CRMD_PG_SHIFT) | -+ (1 << CSR_CRMD_DACF_SHIFT) | (1 << CSR_CRMD_DACM_SHIFT) , -+ .CSR_ECFG = 0x7 << 16, -+ .CSR_STLBPGSIZE = 0xe, -+ .CSR_RVACFG = 0x0, -+ .CSR_ASID = 0xa0000, -+ .FCSR0 = 0x0, -+ .FCSR0_rw_bitmask = 0x1f1f03df, -+ .PABITS = 48, -+ .insn_flags = CPU_LARCH64 | INSN_LOONGARCH, -+ .mmu_type = MMU_TYPE_LS3A5K, -+ }, -+ { -+ .name = "host", -+ -+ /* for LoongISA CSR */ -+ .CSR_PRCFG1 = LOONGARCH_CONFIG1, -+ .CSR_PRCFG2 = 0x3ffff000, -+ .CSR_PRCFG3 = LOONGARCH_CONFIG3, -+ .CSR_CRMD = (0 << CSR_CRMD_PLV_SHIFT) | (0 << CSR_CRMD_IE_SHIFT) | -+ (1 << CSR_CRMD_DA_SHIFT) | (0 << CSR_CRMD_PG_SHIFT) | -+ (1 << CSR_CRMD_DACF_SHIFT) | (1 << CSR_CRMD_DACM_SHIFT) , -+ .CSR_ECFG = 0x7 << 16, -+ .CSR_STLBPGSIZE = 0xe, -+ .CSR_RVACFG = 0x0, -+ .FCSR0 = 0x0, -+ .FCSR0_rw_bitmask = 0x1f1f03df, -+ .PABITS = 48, -+ .insn_flags = CPU_LARCH64 | INSN_LOONGARCH, -+ .mmu_type = MMU_TYPE_LS3A5K, -+ }, -+}; -+const int loongarch_defs_number = ARRAY_SIZE(loongarch_defs); -+ -+void loongarch_cpu_list(void) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(loongarch_defs); i++) { -+ qemu_printf("LOONGARCH '%s'\n", -+ loongarch_defs[i].name); -+ } -+} -+ -+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) -+{ -+ CpuDefinitionInfoList *cpu_list = NULL; -+ const loongarch_def_t *def; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(loongarch_defs); i++) { -+ CpuDefinitionInfoList *entry; -+ CpuDefinitionInfo *info; -+ -+ def = &loongarch_defs[i]; -+ info = g_malloc0(sizeof(*info)); -+ info->name = g_strdup(def->name); -+ -+ entry = g_malloc0(sizeof(*entry)); -+ entry->value = info; -+ entry->next = cpu_list; -+ cpu_list = entry; -+ } -+ -+ return cpu_list; -+} -+ -+static void loongarch_cpu_set_pc(CPUState *cs, vaddr value) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ env->active_tc.PC = value & ~(target_ulong)1; -+} -+ -+static bool loongarch_cpu_has_work(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ bool has_work = false; -+ -+ /* It is implementation dependent if non-enabled -+ interrupts wake-up the CPU, however most of the implementations only -+ check for interrupts that can be taken. */ -+ if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && -+ cpu_loongarch_hw_interrupts_pending(env)) { -+ has_work = true; -+ } -+ -+ return has_work; -+} -+ -+const char * const regnames[] = { -+ "r0", "ra", "tp", "sp", "a0", "a1", "a2", "a3", -+ "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", -+ "t4", "t5", "t6", "t7", "t8", "x0", "fp", "s0", -+ "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", -+}; -+ -+const char * const fregnames[] = { -+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", -+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", -+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", -+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", -+}; -+ -+static void fpu_dump_state(CPULOONGARCHState *env, FILE *f, -+ fprintf_function fpu_fprintf, int flags) -+{ -+ int i; -+ int is_fpu64 = 1; -+ -+#define printfpr(fp) \ -+ do { \ -+ if (is_fpu64) \ -+ fpu_fprintf(f, "w:%08x d:%016" PRIx64 \ -+ " fd:%13g fs:%13g psu: %13g\n", \ -+ (fp)->w[FP_ENDIAN_IDX], (fp)->d, \ -+ (double)(fp)->fd, \ -+ (double)(fp)->fs[FP_ENDIAN_IDX], \ -+ (double)(fp)->fs[!FP_ENDIAN_IDX]); \ -+ else { \ -+ fpr_t tmp; \ -+ tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \ -+ tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \ -+ fpu_fprintf(f, "w:%08x d:%016" PRIx64 \ -+ " fd:%13g fs:%13g psu:%13g\n", \ -+ tmp.w[FP_ENDIAN_IDX], tmp.d, \ -+ (double)tmp.fd, \ -+ (double)tmp.fs[FP_ENDIAN_IDX], \ -+ (double)tmp.fs[!FP_ENDIAN_IDX]); \ -+ } \ -+ } while (0) -+ -+ -+ fpu_fprintf(f, "FCSR0 0x%08x SR.FR %d fp_status 0x%02x\n", -+ env->active_fpu.fcsr0, is_fpu64, -+ get_float_exception_flags(&env->active_fpu.fp_status)); -+ for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) { -+ fpu_fprintf(f, "%3s: ", fregnames[i]); -+ printfpr(&env->active_fpu.fpr[i]); -+ } -+ -+#undef printfpr -+} -+ -+void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int i; -+ -+ qemu_fprintf(f, "pc:\t %lx\n", env->active_tc.PC); -+ for (i = 0; i < 32; i++) { -+ if ((i & 3) == 0) { -+ qemu_fprintf(f, "GPR%02d:", i); -+ } -+ qemu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], -+ env->active_tc.gpr[i]); -+ if ((i & 3) == 3) { -+ qemu_fprintf(f, "\n"); -+ } -+ } -+ qemu_fprintf(f, "EUEN 0x%lx\n", env->CSR_EUEN); -+ qemu_fprintf(f, "ESTAT 0x%lx\n", env->CSR_ESTAT); -+ qemu_fprintf(f, "ERA 0x%lx\n", env->CSR_ERA); -+ qemu_fprintf(f, "CRMD 0x%lx\n", env->CSR_CRMD); -+ qemu_fprintf(f, "PRMD 0x%lx\n", env->CSR_PRMD); -+ qemu_fprintf(f, "BadVAddr 0x%lx\n", env->CSR_BADV); -+ qemu_fprintf(f, "TLB refill ERA 0x%lx\n", env->CSR_TLBRERA); -+ qemu_fprintf(f, "TLB refill BadV 0x%lx\n", env->CSR_TLBRBADV); -+ qemu_fprintf(f, "EEPN 0x%lx\n", env->CSR_EEPN); -+ qemu_fprintf(f, "BadInstr 0x%lx\n", env->CSR_BADI); -+ qemu_fprintf(f, "PRCFG1 0x%lx\nPRCFG2 0x%lx\nPRCFG3 0x%lx\n", -+ env->CSR_PRCFG1, env->CSR_PRCFG3, env->CSR_PRCFG3); -+ if ((flags & CPU_DUMP_FPU) && (env->hflags & LARCH_HFLAG_FPU)) { -+ fpu_dump_state(env, f, qemu_fprintf, flags); -+ } -+} -+ -+void cpu_state_reset(CPULOONGARCHState *env) -+{ -+ LOONGARCHCPU *cpu = loongarch_env_get_cpu(env); -+ CPUState *cs = CPU(cpu); -+ -+ /* Reset registers to their default values */ -+ env->CSR_PRCFG1 = env->cpu_model->CSR_PRCFG1; -+ env->CSR_PRCFG2 = env->cpu_model->CSR_PRCFG2; -+ env->CSR_PRCFG3 = env->cpu_model->CSR_PRCFG3; -+ env->CSR_CRMD = env->cpu_model->CSR_CRMD; -+ env->CSR_ECFG = env->cpu_model->CSR_ECFG; -+ env->CSR_STLBPGSIZE = env->cpu_model->CSR_STLBPGSIZE; -+ env->CSR_RVACFG = env->cpu_model->CSR_RVACFG; -+ env->CSR_ASID = env->cpu_model->CSR_ASID; -+ -+ env->current_tc = 0; -+ env->active_fpu.fcsr0_rw_bitmask = env->cpu_model->FCSR0_rw_bitmask; -+ env->active_fpu.fcsr0 = env->cpu_model->FCSR0; -+ env->insn_flags = env->cpu_model->insn_flags; -+ -+#if !defined(CONFIG_USER_ONLY) -+ env->CSR_ERA = env->active_tc.PC; -+ env->active_tc.PC = env->exception_base; -+#ifdef CONFIG_TCG -+ env->tlb->tlb_in_use = env->tlb->nb_tlb; -+#endif -+ env->CSR_TLBWIRED = 0; -+ env->CSR_TMID = cs->cpu_index; -+ env->CSR_CPUID = (cs->cpu_index & 0x1ff); -+ env->CSR_EEPN |= (uint64_t)0x80000000; -+ env->CSR_TLBRENT |= (uint64_t)0x80000000; -+#endif -+ -+ /* Count register increments in debug mode, EJTAG version 1 */ -+ env->CSR_DEBUG = (1 << CSR_DEBUG_DINT) | (0x1 << CSR_DEBUG_DMVER); -+ -+ compute_hflags(env); -+ restore_fp_status(env); -+ cs->exception_index = EXCP_NONE; -+} -+ -+/* CPUClass::reset() */ -+static void loongarch_cpu_reset(DeviceState *dev) -+{ -+ CPUState *s = CPU(dev); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(s); -+ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(cpu); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ mcc->parent_reset(dev); -+ -+ memset(env, 0, offsetof(CPULOONGARCHState, end_reset_fields)); -+ -+ cpu_state_reset(env); -+ -+#ifndef CONFIG_USER_ONLY -+ if (kvm_enabled()) { -+ kvm_loongarch_reset_vcpu(cpu); -+ } -+#endif -+} -+ -+static void loongarch_cpu_disas_set_info(CPUState *s, disassemble_info *info) -+{ -+ info->print_insn = print_insn_loongarch; -+} -+ -+static void fpu_init(CPULOONGARCHState *env, const loongarch_def_t *def) -+{ -+ memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu)); -+} -+ -+void cpu_loongarch_realize_env(CPULOONGARCHState *env) -+{ -+ env->exception_base = 0x1C000000; -+ -+#ifdef CONFIG_TCG -+#ifndef CONFIG_USER_ONLY -+ mmu_init(env, env->cpu_model); -+#endif -+#endif -+ fpu_init(env, env->cpu_model); -+} -+ -+static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp) -+{ -+ CPUState *cs = CPU(dev); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); -+ LOONGARCHCPUClass *mcc = LOONGARCH_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_loongarch_realize_env(&cpu->env); -+ -+ loongarch_cpu_register_gdb_regs_for_features(cs); -+ -+ cpu_reset(cs); -+ qemu_init_vcpu(cs); -+ -+ mcc->parent_realize(dev, errp); -+ cpu->hotplugged = 1; -+} -+ -+static void loongarch_cpu_unrealizefn(DeviceState *dev) -+{ -+ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(dev); -+ -+#ifndef CONFIG_USER_ONLY -+ cpu_remove_sync(CPU(dev)); -+#endif -+ -+ mcc->parent_unrealize(dev); -+} -+static void loongarch_cpu_initfn(Object *obj) -+{ -+ CPUState *cs = CPU(obj); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(obj); -+ CPULOONGARCHState *env = &cpu->env; -+ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(obj); -+ cpu_set_cpustate_pointers(cpu); -+ cs->env_ptr = env; -+ env->cpu_model = mcc->cpu_def; -+ cs->halted = 1; -+ cpu->dtb_compatible = "loongarch,Loongson-3A5000"; -+} -+ -+static char *loongarch_cpu_type_name(const char *cpu_model) -+{ -+ return g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"), cpu_model); -+} -+ -+static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model) -+{ -+ ObjectClass *oc; -+ char *typename; -+ -+ typename = loongarch_cpu_type_name(cpu_model); -+ oc = object_class_by_name(typename); -+ g_free(typename); -+ return oc; -+} -+ -+static int64_t loongarch_cpu_get_arch_id(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ -+ return cpu->id; -+} -+ -+static Property loongarch_cpu_properties[] = { -+ DEFINE_PROP_INT32("core-id", LOONGARCHCPU, core_id, -1), -+ DEFINE_PROP_INT32("id", LOONGARCHCPU, id, UNASSIGNED_CPU_ID), -+ DEFINE_PROP_INT32("node-id", LOONGARCHCPU, node_id, CPU_UNSET_NUMA_NODE_ID), -+ -+ DEFINE_PROP_END_OF_LIST() -+}; -+ -+#ifdef CONFIG_TCG -+static void loongarch_cpu_synchronize_from_tb(CPUState *cs,const TranslationBlock *tb) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ env->active_tc.PC = tb->pc; -+ env->hflags &= ~LARCH_HFLAG_BMASK; -+ env->hflags |= tb->flags & LARCH_HFLAG_BMASK; -+} -+ -+static const struct TCGCPUOps loongarch_tcg_ops = { -+ .initialize = loongarch_tcg_init, -+ .synchronize_from_tb = loongarch_cpu_synchronize_from_tb, -+ -+ .tlb_fill = loongarch_cpu_tlb_fill, -+ .cpu_exec_interrupt = loongarch_cpu_exec_interrupt, -+ .do_interrupt = loongarch_cpu_do_interrupt, -+ -+#ifndef CONFIG_USER_ONLY -+ .do_unaligned_access = loongarch_cpu_do_unaligned_access, -+#endif /* !CONFIG_USER_ONLY */ -+}; -+#endif /* CONFIG_TCG */ -+ -+ -+#if !defined(CONFIG_USER_ONLY) -+static int get_physical_address(CPULOONGARCHState *env, hwaddr *physical, -+ int *prot, target_ulong real_address, -+ int rw, int access_type, int mmu_idx) -+{ -+ int user_mode = mmu_idx == LARCH_HFLAG_UM; -+ int kernel_mode = !user_mode; -+ unsigned plv, base_c, base_v, tmp; -+ -+ /* effective address (modified for KVM T&E kernel segments) */ -+ target_ulong address = real_address; -+ -+ /* Check PG */ -+ if (!(env->CSR_CRMD & CSR_CRMD_PG)) { -+ /* DA mode */ -+ *physical = address & 0xffffffffffffUL; -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ -+ plv = kernel_mode | (user_mode << 3); -+ base_v = address >> CSR_DMW_BASE_SH; -+ /* Check direct map window 0 */ -+ base_c = env->CSR_DMWIN0 >> CSR_DMW_BASE_SH; -+ if ((plv & env->CSR_DMWIN0) && (base_c == base_v)) { -+ *physical = dmwin_va2pa(address); -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ /* Check direct map window 1 */ -+ base_c = env->CSR_DMWIN1 >> CSR_DMW_BASE_SH; -+ if ((plv & env->CSR_DMWIN1) && (base_c == base_v)) { -+ *physical = dmwin_va2pa(address); -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ /* Check valid extension */ -+ tmp = address >> 47; -+ if (!(tmp == 0 || tmp == 0x1ffff)) { -+ return TLBRET_BADADDR; -+ } -+ /* mapped address */ -+ return env->tlb->map_address(env, physical, prot, real_address, rw, -+ access_type); -+} -+ -+hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ hwaddr phys_addr; -+ int prot; -+ -+ if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT, -+ cpu_mmu_index(env, false)) != 0) { -+ return -1; -+ } -+ return phys_addr; -+} -+#endif -+ -+ -+#ifndef CONFIG_USER_ONLY -+#include "hw/core/sysemu-cpu-ops.h" -+ -+static const struct SysemuCPUOps loongarch_sysemu_ops = { -+ .write_elf64_note = loongarch_cpu_write_elf64_note, -+ .get_phys_page_debug = loongarch_cpu_get_phys_page_debug, -+ .legacy_vmsd = &vmstate_loongarch_cpu, -+}; -+#endif -+ -+ -+static void loongarch_cpu_class_init(ObjectClass *c, void *data) -+{ -+ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_CLASS(c); -+ CPUClass *cc = CPU_CLASS(c); -+ DeviceClass *dc = DEVICE_CLASS(c); -+ -+ device_class_set_props(dc, loongarch_cpu_properties); -+ device_class_set_parent_realize(dc, loongarch_cpu_realizefn, -+ &mcc->parent_realize); -+ -+ device_class_set_parent_unrealize(dc, loongarch_cpu_unrealizefn, -+ &mcc->parent_unrealize); -+ -+ device_class_set_parent_reset(dc, loongarch_cpu_reset, &mcc->parent_reset); -+ cc->get_arch_id = loongarch_cpu_get_arch_id; -+ -+ cc->class_by_name = loongarch_cpu_class_by_name; -+ cc->has_work = loongarch_cpu_has_work; -+ cc->dump_state = loongarch_cpu_dump_state; -+ cc->set_pc = loongarch_cpu_set_pc; -+ cc->gdb_read_register = loongarch_cpu_gdb_read_register; -+ cc->gdb_write_register = loongarch_cpu_gdb_write_register; -+ cc->disas_set_info = loongarch_cpu_disas_set_info; -+#ifndef CONFIG_USER_ONLY -+ cc->sysemu_ops = &loongarch_sysemu_ops; -+#endif /* !CONFIG_USER_ONLY */ -+ -+ cc->gdb_num_core_regs = 33; -+ cc->gdb_core_xml_file = "loongarch-base64.xml"; -+ cc->gdb_stop_before_watchpoint = true; -+ -+ dc->user_creatable = true; -+#ifdef CONFIG_TCG -+ cc->tcg_ops = &loongarch_tcg_ops; -+#endif /* CONFIG_TCG */ -+} -+ -+static const TypeInfo loongarch_cpu_type_info = { -+ .name = TYPE_LOONGARCH_CPU, -+ .parent = TYPE_CPU, -+ .instance_size = sizeof(LOONGARCHCPU), -+ .instance_init = loongarch_cpu_initfn, -+ .abstract = true, -+ .class_size = sizeof(LOONGARCHCPUClass), -+ .class_init = loongarch_cpu_class_init, -+}; -+ -+static void loongarch_cpu_cpudef_class_init(ObjectClass *oc, void *data) -+{ -+ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_CLASS(oc); -+ mcc->cpu_def = data; -+} -+ -+static void loongarch_register_cpudef_type(const struct loongarch_def_t *def) -+{ -+ char *typename = loongarch_cpu_type_name(def->name); -+ TypeInfo ti = { -+ .name = typename, -+ .parent = TYPE_LOONGARCH_CPU, -+ .class_init = loongarch_cpu_cpudef_class_init, -+ .class_data = (void *)def, -+ }; -+ -+ type_register(&ti); -+ g_free(typename); -+} -+ -+static void loongarch_cpu_register_types(void) -+{ -+ int i; -+ -+ type_register_static(&loongarch_cpu_type_info); -+ for (i = 0; i < loongarch_defs_number; i++) { -+ loongarch_register_cpudef_type(&loongarch_defs[i]); -+ } -+} -+ -+type_init(loongarch_cpu_register_types) -diff --git a/target/loongarch64/cpu.h b/target/loongarch64/cpu.h -new file mode 100644 -index 000000000..10facb3b7 ---- /dev/null -+++ b/target/loongarch64/cpu.h -@@ -0,0 +1,326 @@ -+#ifndef LOONGARCH_CPU_H -+#define LOONGARCH_CPU_H -+ -+ -+#define CPUArchState struct CPULOONGARCHState -+ -+#include "qemu-common.h" -+#include "cpu-qom.h" -+#include "larch-defs.h" -+#include "exec/cpu-defs.h" -+#include "fpu/softfloat.h" -+#include "sysemu/sysemu.h" -+#include "cpu-csr.h" -+ -+#define TCG_GUEST_DEFAULT_MO (0) -+ -+struct CPULOONGARCHState; -+typedef LOONGARCHCPU ArchCPU; -+typedef struct CPULOONGARCHTLBContext CPULOONGARCHTLBContext; -+ -+#define LASX_REG_WIDTH (256) -+typedef union lasx_reg_t lasx_reg_t; -+union lasx_reg_t { -+ int64_t val64[LASX_REG_WIDTH / 64]; -+}; -+ -+typedef union fpr_t fpr_t; -+union fpr_t { -+ float64 fd; /* ieee double precision */ -+ float32 fs[2];/* ieee single precision */ -+ uint64_t d; /* binary double fixed-point */ -+ uint32_t w[2]; /* binary single fixed-point */ -+/* FPU/LASX register mapping is not tested on big-endian hosts. */ -+ lasx_reg_t lasx; /* vector data */ -+}; -+/* define FP_ENDIAN_IDX to access the same location -+ * in the fpr_t union regardless of the host endianness -+ */ -+#if defined(HOST_WORDS_BIGENDIAN) -+# define FP_ENDIAN_IDX 1 -+#else -+# define FP_ENDIAN_IDX 0 -+#endif -+ -+typedef struct CPULOONGARCHFPUContext { -+ /* Floating point registers */ -+ fpr_t fpr[32]; -+ float_status fp_status; -+ -+ bool cf[8]; -+ /* fcsr0 -+ * 31:29 |28:24 |23:21 |20:16 |15:10 |9:8 |7 |6 |5 |4:0 -+ * Cause Flags RM DAE TM Enables -+ */ -+ uint32_t fcsr0; -+ uint32_t fcsr0_rw_bitmask; -+ uint32_t vcsr16; -+} CPULOONGARCHFPUContext; -+ -+/* fp control and status register definition */ -+#define FCSR0_M1 0xdf /* DAE, TM and Enables */ -+#define FCSR0_M2 0x1f1f0000 /* Cause and Flags */ -+#define FCSR0_M3 0x300 /* Round Mode */ -+#define FCSR0_RM 8 /* Round Mode bit num on fcsr0 */ -+#define GET_FP_CAUSE(reg) (((reg) >> 24) & 0x1f) -+#define GET_FP_ENABLE(reg) (((reg) >> 0) & 0x1f) -+#define GET_FP_FLAGS(reg) (((reg) >> 16) & 0x1f) -+#define SET_FP_CAUSE(reg, v) do { (reg) = ((reg) & ~(0x1f << 24)) | \ -+ ((v & 0x1f) << 24); \ -+ } while (0) -+#define SET_FP_ENABLE(reg, v) do { (reg) = ((reg) & ~(0x1f << 0)) | \ -+ ((v & 0x1f) << 0); \ -+ } while (0) -+#define SET_FP_FLAGS(reg, v) do { (reg) = ((reg) & ~(0x1f << 16)) | \ -+ ((v & 0x1f) << 16); \ -+ } while (0) -+#define UPDATE_FP_FLAGS(reg, v) do { (reg) |= ((v & 0x1f) << 16); } while (0) -+#define FP_INEXACT 1 -+#define FP_UNDERFLOW 2 -+#define FP_OVERFLOW 4 -+#define FP_DIV0 8 -+#define FP_INVALID 16 -+ -+#define TARGET_INSN_START_EXTRA_WORDS 2 -+ -+typedef struct loongarch_def_t loongarch_def_t; -+ -+#define LOONGARCH_FPU_MAX 1 -+#define LOONGARCH_KSCRATCH_NUM 8 -+ -+typedef struct TCState TCState; -+struct TCState { -+ target_ulong gpr[32]; -+ target_ulong PC; -+}; -+ -+#define N_IRQS 14 -+#define IRQ_TIMER 11 -+#define IRQ_IPI 12 -+#define IRQ_UART 2 -+ -+typedef struct CPULOONGARCHState CPULOONGARCHState; -+struct CPULOONGARCHState { -+ TCState active_tc; -+ CPULOONGARCHFPUContext active_fpu; -+ -+ uint32_t current_tc; -+ uint64_t scr[4]; -+ uint32_t PABITS; -+ -+ /* LoongISA CSR register */ -+ CPU_LOONGARCH_CSR -+ uint64_t lladdr; -+ target_ulong llval; -+ uint64_t llval_wp; -+ uint32_t llnewval_wp; -+ -+ CPULOONGARCHFPUContext fpus[LOONGARCH_FPU_MAX]; -+ /* QEMU */ -+ int error_code; -+#define EXCP_TLB_NOMATCH 0x1 -+#define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */ -+ uint32_t hflags; /* CPU State */ -+ /* TMASK defines different execution modes */ -+#define LARCH_HFLAG_TMASK 0x5F5807FF -+ /* -+ * The KSU flags must be the lowest bits in hflags. The flag order -+ * must be the same as defined for CP0 Status. This allows to use -+ * the bits as the value of mmu_idx. -+ */ -+#define LARCH_HFLAG_KSU 0x00003 /* kernel/user mode mask */ -+#define LARCH_HFLAG_UM 0x00003 /* user mode flag */ -+#define LARCH_HFLAG_KM 0x00000 /* kernel mode flag */ -+#define LARCH_HFLAG_64 0x00008 /* 64-bit instructions enabled */ -+#define LARCH_HFLAG_FPU 0x00020 /* FPU enabled */ -+#define LARCH_HFLAG_AWRAP 0x00200 /* 32-bit compatibility address wrapping */ -+ /* If translation is interrupted between the branch instruction and -+ * the delay slot, record what type of branch it is so that we can -+ * resume translation properly. It might be possible to reduce -+ * this from three bits to two. */ -+#define LARCH_HFLAG_BMASK 0x03800 -+#define LARCH_HFLAG_B 0x00800 /* Unconditional branch */ -+#define LARCH_HFLAG_BC 0x01000 /* Conditional branch */ -+#define LARCH_HFLAG_BR 0x02000 /* branch to register (can't link TB) */ -+#define LARCH_HFLAG_LSX 0x1000000 -+#define LARCH_HFLAG_LASX 0x2000000 -+#define LARCH_HFLAG_LBT 0x40000000 -+ target_ulong btarget; /* Jump / branch target */ -+ target_ulong bcond; /* Branch condition (if needed) */ -+ -+ uint64_t insn_flags; /* Supported instruction set */ -+ int cpu_cfg[64]; -+ -+ /* Fields up to this point are cleared by a CPU reset */ -+ struct {} end_reset_fields; -+ -+ /* Fields from here on are preserved across CPU reset. */ -+#if !defined(CONFIG_USER_ONLY) -+ CPULOONGARCHTLBContext *tlb; -+#endif -+ -+ const loongarch_def_t *cpu_model; -+ void *irq[N_IRQS]; -+ QEMUTimer *timer; /* Internal timer */ -+ MemoryRegion *itc_tag; /* ITC Configuration Tags */ -+ target_ulong exception_base; /* ExceptionBase input to the core */ -+ struct { -+ uint64_t guest_addr; -+ } st; -+}; -+ -+ -+/* CPU can't have 0xFFFFFFFF APIC ID, use that value to distinguish -+ * that ID hasn't been set yet -+ */ -+#define UNASSIGNED_CPU_ID 0xFFFFFFFF -+ -+/** -+ * LOONGARCHCPU: -+ * @env: #CPULOONGARCHState -+ * -+ * A LOONGARCH CPU. -+ */ -+struct LOONGARCHCPU { -+ /*< private >*/ -+ CPUState parent_obj; -+ /*< public >*/ -+ CPUNegativeOffsetState neg; -+ CPULOONGARCHState env; -+ int32_t id; -+ int hotplugged; -+ uint8_t online_vcpus; -+ uint8_t is_migrate; -+ uint64_t counter_value; -+ uint32_t cpu_freq; -+ uint32_t count_ctl; -+ uint64_t pending_exceptions; -+ uint64_t pending_exceptions_clr; -+ uint64_t core_ext_ioisr[4]; -+ VMChangeStateEntry *cpuStateEntry; -+ int32_t node_id; /* NUMA node this CPU belongs to */ -+ int32_t core_id; -+ struct kvm_msrs *kvm_msr_buf; -+ /* 'compatible' string for this CPU for Linux device trees */ -+ const char *dtb_compatible; -+}; -+ -+static inline LOONGARCHCPU *loongarch_env_get_cpu(CPULOONGARCHState *env) -+{ -+ return container_of(env, LOONGARCHCPU, env); -+} -+ -+#define ENV_GET_CPU(e) CPU(loongarch_env_get_cpu(e)) -+ -+#define ENV_OFFSET offsetof(LOONGARCHCPU, env) -+ -+void loongarch_cpu_list(void); -+ -+#define cpu_signal_handler cpu_loongarch_signal_handler -+#define cpu_list loongarch_cpu_list -+ -+/* MMU modes definitions. We carefully match the indices with our -+ hflags layout. */ -+#define MMU_MODE0_SUFFIX _kernel -+#define MMU_MODE1_SUFFIX _super -+#define MMU_MODE2_SUFFIX _user -+#define MMU_MODE3_SUFFIX _error -+#define MMU_USER_IDX 3 -+ -+static inline int hflags_mmu_index(uint32_t hflags) -+{ -+ return hflags & LARCH_HFLAG_KSU; -+} -+ -+static inline int cpu_mmu_index(CPULOONGARCHState *env, bool ifetch) -+{ -+ return hflags_mmu_index(env->hflags); -+} -+ -+#include "exec/cpu-all.h" -+ -+/* Memory access type : -+ * may be needed for precise access rights control and precise exceptions. -+ */ -+enum { -+ /* 1 bit to define user level / supervisor access */ -+ ACCESS_USER = 0x00, -+ ACCESS_SUPER = 0x01, -+ /* 1 bit to indicate direction */ -+ ACCESS_STORE = 0x02, -+ /* Type of instruction that generated the access */ -+ ACCESS_CODE = 0x10, /* Code fetch access */ -+ ACCESS_INT = 0x20, /* Integer load/store access */ -+ ACCESS_FLOAT = 0x30, /* floating point load/store access */ -+}; -+ -+/* Exceptions */ -+enum { -+ EXCP_NONE = -1, -+ EXCP_RESET = 0, -+ EXCP_SRESET, -+ EXCP_DINT, -+ EXCP_NMI, -+ EXCP_EXT_INTERRUPT, /* 7 */ -+ EXCP_AdEL, -+ EXCP_AdES, -+ EXCP_TLBF, -+ EXCP_IBE, -+ EXCP_SYSCALL, -+ EXCP_BREAK, -+ EXCP_FPDIS, -+ EXCP_LSXDIS, -+ EXCP_LASXDIS, -+ EXCP_RI, -+ EXCP_OVERFLOW, -+ EXCP_TRAP, -+ EXCP_FPE, -+ EXCP_LTLBL, -+ EXCP_TLBL, -+ EXCP_TLBS, -+ EXCP_DBE, -+ EXCP_TLBXI, -+ EXCP_TLBRI, -+ EXCP_TLBPE, -+ EXCP_BTDIS, -+ -+ EXCP_LAST = EXCP_BTDIS, -+}; -+ -+/* -+ * This is an internally generated WAKE request line. -+ * It is driven by the CPU itself. Raised when the MT -+ * block wants to wake a VPE from an inactive state and -+ * cleared when VPE goes from active to inactive. -+ */ -+#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0 -+ -+int cpu_loongarch_signal_handler(int host_signum, void *pinfo, void *puc); -+ -+#define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU -+#define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX -+#define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU -+ -+/* helper.c */ -+target_ulong exception_resume_pc(CPULOONGARCHState *env); -+ -+/* gdbstub.c */ -+void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs); -+void mmu_init(CPULOONGARCHState *env, const loongarch_def_t *def); -+ -+static inline void cpu_get_tb_cpu_state(CPULOONGARCHState *env, target_ulong *pc, -+ target_ulong *cs_base, uint32_t *flags) -+{ -+ *pc = env->active_tc.PC; -+ *cs_base = 0; -+ *flags = env->hflags & (LARCH_HFLAG_TMASK | LARCH_HFLAG_BMASK); -+} -+ -+static inline bool cpu_refill_state(CPULOONGARCHState *env) -+{ -+ return env->CSR_TLBRERA & 0x1; -+} -+ -+extern const char * const regnames[]; -+extern const char * const fregnames[]; -+#endif /* LOONGARCH_CPU_H */ -diff --git a/target/loongarch64/csr_helper.c b/target/loongarch64/csr_helper.c -new file mode 100644 -index 000000000..182e59e92 ---- /dev/null -+++ b/target/loongarch64/csr_helper.c -@@ -0,0 +1,704 @@ -+/* -+ * loongarch tlb emulation helpers for qemu. -+ * -+ * Copyright (c) 2020 - 2021 -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/main-loop.h" -+#include "cpu.h" -+#include "internal.h" -+#include "qemu/host-utils.h" -+#include "exec/helper-proto.h" -+#include "exec/exec-all.h" -+#include "exec/cpu_ldst.h" -+#include "sysemu/kvm.h" -+#include "hw/irq.h" -+#include "cpu-csr.h" -+#include "instmap.h" -+ -+#ifndef CONFIG_USER_ONLY -+target_ulong helper_csr_rdq(CPULOONGARCHState *env, uint64_t csr) -+{ -+ int64_t v; -+ -+#define CASE_CSR_RDQ(csr) \ -+ case LOONGARCH_CSR_ ## csr: \ -+ { \ -+ v = env->CSR_ ## csr; \ -+ break; \ -+ }; \ -+ -+ switch (csr) { -+ CASE_CSR_RDQ(CRMD) -+ CASE_CSR_RDQ(PRMD) -+ CASE_CSR_RDQ(EUEN) -+ CASE_CSR_RDQ(MISC) -+ CASE_CSR_RDQ(ECFG) -+ CASE_CSR_RDQ(ESTAT) -+ CASE_CSR_RDQ(ERA) -+ CASE_CSR_RDQ(BADV) -+ CASE_CSR_RDQ(BADI) -+ CASE_CSR_RDQ(EEPN) -+ CASE_CSR_RDQ(TLBIDX) -+ CASE_CSR_RDQ(TLBEHI) -+ CASE_CSR_RDQ(TLBELO0) -+ CASE_CSR_RDQ(TLBELO1) -+ CASE_CSR_RDQ(TLBWIRED) -+ CASE_CSR_RDQ(GTLBC) -+ CASE_CSR_RDQ(TRGP) -+ CASE_CSR_RDQ(ASID) -+ CASE_CSR_RDQ(PGDL) -+ CASE_CSR_RDQ(PGDH) -+ CASE_CSR_RDQ(PGD) -+ CASE_CSR_RDQ(PWCTL0) -+ CASE_CSR_RDQ(PWCTL1) -+ CASE_CSR_RDQ(STLBPGSIZE) -+ CASE_CSR_RDQ(RVACFG) -+ CASE_CSR_RDQ(CPUID) -+ CASE_CSR_RDQ(PRCFG1) -+ CASE_CSR_RDQ(PRCFG2) -+ CASE_CSR_RDQ(PRCFG3) -+ CASE_CSR_RDQ(KS0) -+ CASE_CSR_RDQ(KS1) -+ CASE_CSR_RDQ(KS2) -+ CASE_CSR_RDQ(KS3) -+ CASE_CSR_RDQ(KS4) -+ CASE_CSR_RDQ(KS5) -+ CASE_CSR_RDQ(KS6) -+ CASE_CSR_RDQ(KS7) -+ CASE_CSR_RDQ(KS8) -+ CASE_CSR_RDQ(TMID) -+ CASE_CSR_RDQ(TCFG) -+ case LOONGARCH_CSR_TVAL: -+ v = cpu_loongarch_get_stable_timer_ticks(env); -+ break; -+ CASE_CSR_RDQ(CNTC) -+ CASE_CSR_RDQ(TINTCLR) -+ CASE_CSR_RDQ(GSTAT) -+ CASE_CSR_RDQ(GCFG) -+ CASE_CSR_RDQ(GINTC) -+ CASE_CSR_RDQ(GCNTC) -+ CASE_CSR_RDQ(LLBCTL) -+ CASE_CSR_RDQ(IMPCTL1) -+ CASE_CSR_RDQ(IMPCTL2) -+ CASE_CSR_RDQ(GNMI) -+ CASE_CSR_RDQ(TLBRENT) -+ CASE_CSR_RDQ(TLBRBADV) -+ CASE_CSR_RDQ(TLBRERA) -+ CASE_CSR_RDQ(TLBRSAVE) -+ CASE_CSR_RDQ(TLBRELO0) -+ CASE_CSR_RDQ(TLBRELO1) -+ CASE_CSR_RDQ(TLBREHI) -+ CASE_CSR_RDQ(TLBRPRMD) -+ CASE_CSR_RDQ(ERRCTL) -+ CASE_CSR_RDQ(ERRINFO) -+ CASE_CSR_RDQ(ERRINFO1) -+ CASE_CSR_RDQ(ERRENT) -+ CASE_CSR_RDQ(ERRERA) -+ CASE_CSR_RDQ(ERRSAVE) -+ CASE_CSR_RDQ(CTAG) -+ CASE_CSR_RDQ(DMWIN0) -+ CASE_CSR_RDQ(DMWIN1) -+ CASE_CSR_RDQ(DMWIN2) -+ CASE_CSR_RDQ(DMWIN3) -+ CASE_CSR_RDQ(PERFCTRL0) -+ CASE_CSR_RDQ(PERFCNTR0) -+ CASE_CSR_RDQ(PERFCTRL1) -+ CASE_CSR_RDQ(PERFCNTR1) -+ CASE_CSR_RDQ(PERFCTRL2) -+ CASE_CSR_RDQ(PERFCNTR2) -+ CASE_CSR_RDQ(PERFCTRL3) -+ CASE_CSR_RDQ(PERFCNTR3) -+ /* debug */ -+ CASE_CSR_RDQ(MWPC) -+ CASE_CSR_RDQ(MWPS) -+ CASE_CSR_RDQ(DB0ADDR) -+ CASE_CSR_RDQ(DB0MASK) -+ CASE_CSR_RDQ(DB0CTL) -+ CASE_CSR_RDQ(DB0ASID) -+ CASE_CSR_RDQ(DB1ADDR) -+ CASE_CSR_RDQ(DB1MASK) -+ CASE_CSR_RDQ(DB1CTL) -+ CASE_CSR_RDQ(DB1ASID) -+ CASE_CSR_RDQ(DB2ADDR) -+ CASE_CSR_RDQ(DB2MASK) -+ CASE_CSR_RDQ(DB2CTL) -+ CASE_CSR_RDQ(DB2ASID) -+ CASE_CSR_RDQ(DB3ADDR) -+ CASE_CSR_RDQ(DB3MASK) -+ CASE_CSR_RDQ(DB3CTL) -+ CASE_CSR_RDQ(DB3ASID) -+ CASE_CSR_RDQ(FWPC) -+ CASE_CSR_RDQ(FWPS) -+ CASE_CSR_RDQ(IB0ADDR) -+ CASE_CSR_RDQ(IB0MASK) -+ CASE_CSR_RDQ(IB0CTL) -+ CASE_CSR_RDQ(IB0ASID) -+ CASE_CSR_RDQ(IB1ADDR) -+ CASE_CSR_RDQ(IB1MASK) -+ CASE_CSR_RDQ(IB1CTL) -+ CASE_CSR_RDQ(IB1ASID) -+ CASE_CSR_RDQ(IB2ADDR) -+ CASE_CSR_RDQ(IB2MASK) -+ CASE_CSR_RDQ(IB2CTL) -+ CASE_CSR_RDQ(IB2ASID) -+ CASE_CSR_RDQ(IB3ADDR) -+ CASE_CSR_RDQ(IB3MASK) -+ CASE_CSR_RDQ(IB3CTL) -+ CASE_CSR_RDQ(IB3ASID) -+ CASE_CSR_RDQ(IB4ADDR) -+ CASE_CSR_RDQ(IB4MASK) -+ CASE_CSR_RDQ(IB4CTL) -+ CASE_CSR_RDQ(IB4ASID) -+ CASE_CSR_RDQ(IB5ADDR) -+ CASE_CSR_RDQ(IB5MASK) -+ CASE_CSR_RDQ(IB5CTL) -+ CASE_CSR_RDQ(IB5ASID) -+ CASE_CSR_RDQ(IB6ADDR) -+ CASE_CSR_RDQ(IB6MASK) -+ CASE_CSR_RDQ(IB6CTL) -+ CASE_CSR_RDQ(IB6ASID) -+ CASE_CSR_RDQ(IB7ADDR) -+ CASE_CSR_RDQ(IB7MASK) -+ CASE_CSR_RDQ(IB7CTL) -+ CASE_CSR_RDQ(IB7ASID) -+ CASE_CSR_RDQ(DEBUG) -+ CASE_CSR_RDQ(DERA) -+ CASE_CSR_RDQ(DESAVE) -+ default : -+ assert(0); -+ } -+ -+#undef CASE_CSR_RDQ -+ compute_hflags(env); -+ return v; -+} -+ -+target_ulong helper_csr_wrq(CPULOONGARCHState *env, target_ulong val, -+ uint64_t csr) -+{ -+ int64_t old_v, v; -+ old_v = -1; -+ v = val; -+ -+#define CASE_CSR_WRQ(csr) \ -+ case LOONGARCH_CSR_ ## csr: \ -+ { \ -+ old_v = env->CSR_ ## csr; \ -+ env->CSR_ ## csr = v; \ -+ break; \ -+ }; \ -+ -+ switch (csr) { -+ CASE_CSR_WRQ(CRMD) -+ CASE_CSR_WRQ(PRMD) -+ CASE_CSR_WRQ(EUEN) -+ CASE_CSR_WRQ(MISC) -+ CASE_CSR_WRQ(ECFG) -+ CASE_CSR_WRQ(ESTAT) -+ CASE_CSR_WRQ(ERA) -+ CASE_CSR_WRQ(BADV) -+ CASE_CSR_WRQ(BADI) -+ CASE_CSR_WRQ(EEPN) -+ CASE_CSR_WRQ(TLBIDX) -+ CASE_CSR_WRQ(TLBEHI) -+ CASE_CSR_WRQ(TLBELO0) -+ CASE_CSR_WRQ(TLBELO1) -+ CASE_CSR_WRQ(TLBWIRED) -+ CASE_CSR_WRQ(GTLBC) -+ CASE_CSR_WRQ(TRGP) -+ CASE_CSR_WRQ(ASID) -+ CASE_CSR_WRQ(PGDL) -+ CASE_CSR_WRQ(PGDH) -+ CASE_CSR_WRQ(PGD) -+ CASE_CSR_WRQ(PWCTL0) -+ CASE_CSR_WRQ(PWCTL1) -+ CASE_CSR_WRQ(STLBPGSIZE) -+ CASE_CSR_WRQ(RVACFG) -+ CASE_CSR_WRQ(CPUID) -+ CASE_CSR_WRQ(PRCFG1) -+ CASE_CSR_WRQ(PRCFG2) -+ CASE_CSR_WRQ(PRCFG3) -+ CASE_CSR_WRQ(KS0) -+ CASE_CSR_WRQ(KS1) -+ CASE_CSR_WRQ(KS2) -+ CASE_CSR_WRQ(KS3) -+ CASE_CSR_WRQ(KS4) -+ CASE_CSR_WRQ(KS5) -+ CASE_CSR_WRQ(KS6) -+ CASE_CSR_WRQ(KS7) -+ CASE_CSR_WRQ(KS8) -+ CASE_CSR_WRQ(TMID) -+ case LOONGARCH_CSR_TCFG: -+ old_v = env->CSR_TCFG; -+ cpu_loongarch_store_stable_timer_config(env, v); -+ break; -+ CASE_CSR_WRQ(TVAL) -+ CASE_CSR_WRQ(CNTC) -+ case LOONGARCH_CSR_TINTCLR: -+ old_v = 0; -+ qemu_irq_lower(env->irq[IRQ_TIMER]); -+ break; -+ CASE_CSR_WRQ(GSTAT) -+ CASE_CSR_WRQ(GCFG) -+ CASE_CSR_WRQ(GINTC) -+ CASE_CSR_WRQ(GCNTC) -+ CASE_CSR_WRQ(LLBCTL) -+ CASE_CSR_WRQ(IMPCTL1) -+ case LOONGARCH_CSR_IMPCTL2: -+ if (v & CSR_IMPCTL2_MTLB) { -+ ls3a5k_flush_vtlb(env); -+ } -+ if (v & CSR_IMPCTL2_STLB) { -+ ls3a5k_flush_ftlb(env); -+ } -+ break; -+ CASE_CSR_WRQ(GNMI) -+ CASE_CSR_WRQ(TLBRENT) -+ CASE_CSR_WRQ(TLBRBADV) -+ CASE_CSR_WRQ(TLBRERA) -+ CASE_CSR_WRQ(TLBRSAVE) -+ CASE_CSR_WRQ(TLBRELO0) -+ CASE_CSR_WRQ(TLBRELO1) -+ CASE_CSR_WRQ(TLBREHI) -+ CASE_CSR_WRQ(TLBRPRMD) -+ CASE_CSR_WRQ(ERRCTL) -+ CASE_CSR_WRQ(ERRINFO) -+ CASE_CSR_WRQ(ERRINFO1) -+ CASE_CSR_WRQ(ERRENT) -+ CASE_CSR_WRQ(ERRERA) -+ CASE_CSR_WRQ(ERRSAVE) -+ CASE_CSR_WRQ(CTAG) -+ CASE_CSR_WRQ(DMWIN0) -+ CASE_CSR_WRQ(DMWIN1) -+ CASE_CSR_WRQ(DMWIN2) -+ CASE_CSR_WRQ(DMWIN3) -+ CASE_CSR_WRQ(PERFCTRL0) -+ CASE_CSR_WRQ(PERFCNTR0) -+ CASE_CSR_WRQ(PERFCTRL1) -+ CASE_CSR_WRQ(PERFCNTR1) -+ CASE_CSR_WRQ(PERFCTRL2) -+ CASE_CSR_WRQ(PERFCNTR2) -+ CASE_CSR_WRQ(PERFCTRL3) -+ CASE_CSR_WRQ(PERFCNTR3) -+ /* debug */ -+ CASE_CSR_WRQ(MWPC) -+ CASE_CSR_WRQ(MWPS) -+ CASE_CSR_WRQ(DB0ADDR) -+ CASE_CSR_WRQ(DB0MASK) -+ CASE_CSR_WRQ(DB0CTL) -+ CASE_CSR_WRQ(DB0ASID) -+ CASE_CSR_WRQ(DB1ADDR) -+ CASE_CSR_WRQ(DB1MASK) -+ CASE_CSR_WRQ(DB1CTL) -+ CASE_CSR_WRQ(DB1ASID) -+ CASE_CSR_WRQ(DB2ADDR) -+ CASE_CSR_WRQ(DB2MASK) -+ CASE_CSR_WRQ(DB2CTL) -+ CASE_CSR_WRQ(DB2ASID) -+ CASE_CSR_WRQ(DB3ADDR) -+ CASE_CSR_WRQ(DB3MASK) -+ CASE_CSR_WRQ(DB3CTL) -+ CASE_CSR_WRQ(DB3ASID) -+ CASE_CSR_WRQ(FWPC) -+ CASE_CSR_WRQ(FWPS) -+ CASE_CSR_WRQ(IB0ADDR) -+ CASE_CSR_WRQ(IB0MASK) -+ CASE_CSR_WRQ(IB0CTL) -+ CASE_CSR_WRQ(IB0ASID) -+ CASE_CSR_WRQ(IB1ADDR) -+ CASE_CSR_WRQ(IB1MASK) -+ CASE_CSR_WRQ(IB1CTL) -+ CASE_CSR_WRQ(IB1ASID) -+ CASE_CSR_WRQ(IB2ADDR) -+ CASE_CSR_WRQ(IB2MASK) -+ CASE_CSR_WRQ(IB2CTL) -+ CASE_CSR_WRQ(IB2ASID) -+ CASE_CSR_WRQ(IB3ADDR) -+ CASE_CSR_WRQ(IB3MASK) -+ CASE_CSR_WRQ(IB3CTL) -+ CASE_CSR_WRQ(IB3ASID) -+ CASE_CSR_WRQ(IB4ADDR) -+ CASE_CSR_WRQ(IB4MASK) -+ CASE_CSR_WRQ(IB4CTL) -+ CASE_CSR_WRQ(IB4ASID) -+ CASE_CSR_WRQ(IB5ADDR) -+ CASE_CSR_WRQ(IB5MASK) -+ CASE_CSR_WRQ(IB5CTL) -+ CASE_CSR_WRQ(IB5ASID) -+ CASE_CSR_WRQ(IB6ADDR) -+ CASE_CSR_WRQ(IB6MASK) -+ CASE_CSR_WRQ(IB6CTL) -+ CASE_CSR_WRQ(IB6ASID) -+ CASE_CSR_WRQ(IB7ADDR) -+ CASE_CSR_WRQ(IB7MASK) -+ CASE_CSR_WRQ(IB7CTL) -+ CASE_CSR_WRQ(IB7ASID) -+ CASE_CSR_WRQ(DEBUG) -+ CASE_CSR_WRQ(DERA) -+ CASE_CSR_WRQ(DESAVE) -+ default : -+ assert(0); -+ } -+ -+ if (csr == LOONGARCH_CSR_ASID) { -+ if (old_v != v) { -+ tlb_flush(CPU(loongarch_env_get_cpu(env))); -+ } -+ } -+ -+#undef CASE_CSR_WRQ -+ compute_hflags(env); -+ return old_v; -+} -+ -+target_ulong helper_csr_xchgq(CPULOONGARCHState *env, target_ulong val, -+ target_ulong mask, uint64_t csr) -+{ -+ target_ulong v, tmp; -+ v = val & mask; -+ -+#define CASE_CSR_XCHGQ(csr) \ -+ case LOONGARCH_CSR_ ## csr: \ -+ { \ -+ val = env->CSR_ ## csr; \ -+ env->CSR_ ## csr = (env->CSR_ ## csr) & (~mask); \ -+ env->CSR_ ## csr = (env->CSR_ ## csr) | v; \ -+ break; \ -+ }; \ -+ -+ switch (csr) { -+ CASE_CSR_XCHGQ(CRMD) -+ CASE_CSR_XCHGQ(PRMD) -+ CASE_CSR_XCHGQ(EUEN) -+ CASE_CSR_XCHGQ(MISC) -+ CASE_CSR_XCHGQ(ECFG) -+ case LOONGARCH_CSR_ESTAT: -+ val = env->CSR_ESTAT; -+ qatomic_and(&env->CSR_ESTAT, ~mask); -+ qatomic_or(&env->CSR_ESTAT, v); -+ break; -+ CASE_CSR_XCHGQ(ERA) -+ CASE_CSR_XCHGQ(BADV) -+ CASE_CSR_XCHGQ(BADI) -+ CASE_CSR_XCHGQ(EEPN) -+ CASE_CSR_XCHGQ(TLBIDX) -+ CASE_CSR_XCHGQ(TLBEHI) -+ CASE_CSR_XCHGQ(TLBELO0) -+ CASE_CSR_XCHGQ(TLBELO1) -+ CASE_CSR_XCHGQ(TLBWIRED) -+ CASE_CSR_XCHGQ(GTLBC) -+ CASE_CSR_XCHGQ(TRGP) -+ CASE_CSR_XCHGQ(ASID) -+ CASE_CSR_XCHGQ(PGDL) -+ CASE_CSR_XCHGQ(PGDH) -+ CASE_CSR_XCHGQ(PGD) -+ CASE_CSR_XCHGQ(PWCTL0) -+ CASE_CSR_XCHGQ(PWCTL1) -+ CASE_CSR_XCHGQ(STLBPGSIZE) -+ CASE_CSR_XCHGQ(RVACFG) -+ CASE_CSR_XCHGQ(CPUID) -+ CASE_CSR_XCHGQ(PRCFG1) -+ CASE_CSR_XCHGQ(PRCFG2) -+ CASE_CSR_XCHGQ(PRCFG3) -+ CASE_CSR_XCHGQ(KS0) -+ CASE_CSR_XCHGQ(KS1) -+ CASE_CSR_XCHGQ(KS2) -+ CASE_CSR_XCHGQ(KS3) -+ CASE_CSR_XCHGQ(KS4) -+ CASE_CSR_XCHGQ(KS5) -+ CASE_CSR_XCHGQ(KS6) -+ CASE_CSR_XCHGQ(KS7) -+ CASE_CSR_XCHGQ(KS8) -+ CASE_CSR_XCHGQ(TMID) -+ case LOONGARCH_CSR_TCFG: -+ val = env->CSR_TCFG; -+ tmp = val & ~mask; -+ tmp |= v; -+ cpu_loongarch_store_stable_timer_config(env, tmp); -+ break; -+ CASE_CSR_XCHGQ(TVAL) -+ CASE_CSR_XCHGQ(CNTC) -+ CASE_CSR_XCHGQ(TINTCLR) -+ CASE_CSR_XCHGQ(GSTAT) -+ CASE_CSR_XCHGQ(GCFG) -+ CASE_CSR_XCHGQ(GINTC) -+ CASE_CSR_XCHGQ(GCNTC) -+ CASE_CSR_XCHGQ(LLBCTL) -+ CASE_CSR_XCHGQ(IMPCTL1) -+ CASE_CSR_XCHGQ(IMPCTL2) -+ CASE_CSR_XCHGQ(GNMI) -+ CASE_CSR_XCHGQ(TLBRENT) -+ CASE_CSR_XCHGQ(TLBRBADV) -+ CASE_CSR_XCHGQ(TLBRERA) -+ CASE_CSR_XCHGQ(TLBRSAVE) -+ CASE_CSR_XCHGQ(TLBRELO0) -+ CASE_CSR_XCHGQ(TLBRELO1) -+ CASE_CSR_XCHGQ(TLBREHI) -+ CASE_CSR_XCHGQ(TLBRPRMD) -+ CASE_CSR_XCHGQ(ERRCTL) -+ CASE_CSR_XCHGQ(ERRINFO) -+ CASE_CSR_XCHGQ(ERRINFO1) -+ CASE_CSR_XCHGQ(ERRENT) -+ CASE_CSR_XCHGQ(ERRERA) -+ CASE_CSR_XCHGQ(ERRSAVE) -+ CASE_CSR_XCHGQ(CTAG) -+ CASE_CSR_XCHGQ(DMWIN0) -+ CASE_CSR_XCHGQ(DMWIN1) -+ CASE_CSR_XCHGQ(DMWIN2) -+ CASE_CSR_XCHGQ(DMWIN3) -+ CASE_CSR_XCHGQ(PERFCTRL0) -+ CASE_CSR_XCHGQ(PERFCNTR0) -+ CASE_CSR_XCHGQ(PERFCTRL1) -+ CASE_CSR_XCHGQ(PERFCNTR1) -+ CASE_CSR_XCHGQ(PERFCTRL2) -+ CASE_CSR_XCHGQ(PERFCNTR2) -+ CASE_CSR_XCHGQ(PERFCTRL3) -+ CASE_CSR_XCHGQ(PERFCNTR3) -+ /* debug */ -+ CASE_CSR_XCHGQ(MWPC) -+ CASE_CSR_XCHGQ(MWPS) -+ CASE_CSR_XCHGQ(DB0ADDR) -+ CASE_CSR_XCHGQ(DB0MASK) -+ CASE_CSR_XCHGQ(DB0CTL) -+ CASE_CSR_XCHGQ(DB0ASID) -+ CASE_CSR_XCHGQ(DB1ADDR) -+ CASE_CSR_XCHGQ(DB1MASK) -+ CASE_CSR_XCHGQ(DB1CTL) -+ CASE_CSR_XCHGQ(DB1ASID) -+ CASE_CSR_XCHGQ(DB2ADDR) -+ CASE_CSR_XCHGQ(DB2MASK) -+ CASE_CSR_XCHGQ(DB2CTL) -+ CASE_CSR_XCHGQ(DB2ASID) -+ CASE_CSR_XCHGQ(DB3ADDR) -+ CASE_CSR_XCHGQ(DB3MASK) -+ CASE_CSR_XCHGQ(DB3CTL) -+ CASE_CSR_XCHGQ(DB3ASID) -+ CASE_CSR_XCHGQ(FWPC) -+ CASE_CSR_XCHGQ(FWPS) -+ CASE_CSR_XCHGQ(IB0ADDR) -+ CASE_CSR_XCHGQ(IB0MASK) -+ CASE_CSR_XCHGQ(IB0CTL) -+ CASE_CSR_XCHGQ(IB0ASID) -+ CASE_CSR_XCHGQ(IB1ADDR) -+ CASE_CSR_XCHGQ(IB1MASK) -+ CASE_CSR_XCHGQ(IB1CTL) -+ CASE_CSR_XCHGQ(IB1ASID) -+ CASE_CSR_XCHGQ(IB2ADDR) -+ CASE_CSR_XCHGQ(IB2MASK) -+ CASE_CSR_XCHGQ(IB2CTL) -+ CASE_CSR_XCHGQ(IB2ASID) -+ CASE_CSR_XCHGQ(IB3ADDR) -+ CASE_CSR_XCHGQ(IB3MASK) -+ CASE_CSR_XCHGQ(IB3CTL) -+ CASE_CSR_XCHGQ(IB3ASID) -+ CASE_CSR_XCHGQ(IB4ADDR) -+ CASE_CSR_XCHGQ(IB4MASK) -+ CASE_CSR_XCHGQ(IB4CTL) -+ CASE_CSR_XCHGQ(IB4ASID) -+ CASE_CSR_XCHGQ(IB5ADDR) -+ CASE_CSR_XCHGQ(IB5MASK) -+ CASE_CSR_XCHGQ(IB5CTL) -+ CASE_CSR_XCHGQ(IB5ASID) -+ CASE_CSR_XCHGQ(IB6ADDR) -+ CASE_CSR_XCHGQ(IB6MASK) -+ CASE_CSR_XCHGQ(IB6CTL) -+ CASE_CSR_XCHGQ(IB6ASID) -+ CASE_CSR_XCHGQ(IB7ADDR) -+ CASE_CSR_XCHGQ(IB7MASK) -+ CASE_CSR_XCHGQ(IB7CTL) -+ CASE_CSR_XCHGQ(IB7ASID) -+ CASE_CSR_XCHGQ(DEBUG) -+ CASE_CSR_XCHGQ(DERA) -+ CASE_CSR_XCHGQ(DESAVE) -+ default : -+ assert(0); -+ } -+ -+#undef CASE_CSR_XCHGQ -+ compute_hflags(env); -+ return val; -+} -+ -+static target_ulong confbus_addr(CPULOONGARCHState *env, int cpuid, -+ target_ulong csr_addr) -+{ -+ target_ulong addr; -+ target_ulong node_addr; -+ int cores_per_node = ((0x60018 >> 3) & 0xff) + 1; -+ -+ switch (cores_per_node) { -+ case 4: -+ assert(cpuid < 64); -+ node_addr = ((target_ulong)(cpuid & 0x3c) << 42); -+ break; -+ case 8: -+ assert(cpuid < 128); -+ node_addr = ((target_ulong)(cpuid & 0x78) << 41) + -+ ((target_ulong)(cpuid & 0x4) << 14); -+ break; -+ case 16: -+ assert(cpuid < 256); -+ node_addr = ((target_ulong)(cpuid & 0xf0) << 40) + -+ ((target_ulong)(cpuid & 0xc) << 14); -+ break; -+ default: -+ assert(0); -+ break; -+ } -+ -+ /* -+ * per core address -+ *0x10xx => ipi -+ * 0x18xx => extioi isr -+ */ -+ if (((csr_addr & 0xff00) == 0x1000)) { -+ addr = (csr_addr & 0xff) + (target_ulong)(cpuid << 8); -+ addr = 0x800000001f000000UL + addr; -+ return addr; -+ } else if ((csr_addr & 0xff00) == 0x1800) { -+ addr = (csr_addr & 0xff) + ((target_ulong)(cpuid << 8)); -+ addr = 0x800000001f020000UL + addr; -+ return addr; -+ } else if ((csr_addr & 0xff00) >= 0x1400 && (csr_addr & 0xff00) < 0x1d00) { -+ addr = 0x800000001f010000UL + ((csr_addr & 0xfff) - 0x400); -+ return addr; -+ } else if (csr_addr == 0x408) { -+ addr = csr_addr; -+ } else { -+ addr = csr_addr + node_addr; -+ } -+ -+ addr = 0x800000001fe00000UL + addr; -+ return addr; -+} -+ -+void helper_iocsr(CPULOONGARCHState *env, target_ulong r_addr, -+ target_ulong r_val, uint32_t op) -+{ -+ target_ulong addr; -+ target_ulong val = env->active_tc.gpr[r_val]; -+ int mask; -+ -+ addr = confbus_addr(env, CPU(loongarch_env_get_cpu(env))->cpu_index, -+ env->active_tc.gpr[r_addr]); -+ -+ switch (env->active_tc.gpr[r_addr]) { -+ /* IPI send */ -+ case 0x1040: -+ if (op != OPC_LARCH_ST_W) { -+ return; -+ } -+ op = OPC_LARCH_ST_W; -+ break; -+ -+ /* Mail send */ -+ case 0x1048: -+ if (op != OPC_LARCH_ST_D) { -+ return; -+ } -+ op = OPC_LARCH_ST_D; -+ break; -+ -+ /* ANY send */ -+ case 0x1158: -+ if (op != OPC_LARCH_ST_D) { -+ return; -+ } -+ addr = confbus_addr(env, (val >> 16) & 0x3ff, val & 0xffff); -+ mask = (val >> 27) & 0xf; -+ val = (val >> 32); -+ switch (mask) { -+ case 0: -+ op = OPC_LARCH_ST_W; -+ break; -+ case 0x7: -+ op = OPC_LARCH_ST_B; -+ addr += 3; -+ val >>= 24; -+ break; -+ case 0xb: -+ op = OPC_LARCH_ST_B; -+ addr += 2; -+ val >>= 16; -+ break; -+ case 0xd: -+ op = OPC_LARCH_ST_B; -+ addr += 1; -+ val >>= 8; -+ break; -+ case 0xe: -+ op = OPC_LARCH_ST_B; -+ break; -+ case 0xc: -+ op = OPC_LARCH_ST_H; -+ break; -+ case 0x3: -+ op = OPC_LARCH_ST_H; -+ addr += 2; -+ val >>= 16; -+ break; -+ default: -+ qemu_log("Unsupported any_send mask0x%x\n", mask); -+ break; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ switch (op) { -+ case OPC_LARCH_LD_D: -+ env->active_tc.gpr[r_val] = cpu_ldq_data_ra(env, addr, -+ GETPC()); -+ break; -+ case OPC_LARCH_LD_W: -+ env->active_tc.gpr[r_val] = cpu_ldl_data_ra(env, addr, -+ GETPC()); -+ break; -+ case OPC_LARCH_LD_H: -+ assert(0); -+ break; -+ case OPC_LARCH_LD_B: -+ assert(0); -+ break; -+ case OPC_LARCH_ST_D: -+ cpu_stq_data_ra(env, addr, val, GETPC()); -+ break; -+ case OPC_LARCH_ST_W: -+ cpu_stl_data_ra(env, addr, val, GETPC()); -+ break; -+ case OPC_LARCH_ST_H: -+ cpu_stb_data_ra(env, addr, val, GETPC()); -+ break; -+ case OPC_LARCH_ST_B: -+ cpu_stb_data_ra(env, addr, val, GETPC()); -+ break; -+ default: -+ qemu_log("Unknown op 0x%x", op); -+ assert(0); -+ } -+} -+#endif -+ -+target_ulong helper_cpucfg(CPULOONGARCHState *env, target_ulong rj) -+{ -+ return 0; -+} -+ -+ -diff --git a/target/loongarch64/fpu.c b/target/loongarch64/fpu.c -new file mode 100644 -index 000000000..795458205 ---- /dev/null -+++ b/target/loongarch64/fpu.c -@@ -0,0 +1,28 @@ -+/* -+ * loongarch float point emulation helpers for qemu. -+ * -+ * Copyright (c) 2020-2021 -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+#include "qemu/osdep.h" -+#include "fpu/softfloat.h" -+ -+/* convert loongarch rounding mode in fcsr0 to IEEE library */ -+unsigned int ieee_rm[] = { -+ float_round_nearest_even, -+ float_round_to_zero, -+ float_round_up, -+ float_round_down -+}; -diff --git a/target/loongarch64/fpu_helper.c b/target/loongarch64/fpu_helper.c -new file mode 100644 -index 000000000..42d7f05ca ---- /dev/null -+++ b/target/loongarch64/fpu_helper.c -@@ -0,0 +1,952 @@ -+/* -+ * loongarch float point emulation helpers for qemu. -+ * -+ * Copyright (c) 2020-2021 -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "internal.h" -+#include "qemu/host-utils.h" -+#include "exec/helper-proto.h" -+#include "exec/exec-all.h" -+#include "fpu/softfloat.h" -+ -+#define FP_TO_INT32_OVERFLOW 0x7fffffff -+#define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL -+ -+#define FLOAT_CLASS_SIGNALING_NAN 0x001 -+#define FLOAT_CLASS_QUIET_NAN 0x002 -+#define FLOAT_CLASS_NEGATIVE_INFINITY 0x004 -+#define FLOAT_CLASS_NEGATIVE_NORMAL 0x008 -+#define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010 -+#define FLOAT_CLASS_NEGATIVE_ZERO 0x020 -+#define FLOAT_CLASS_POSITIVE_INFINITY 0x040 -+#define FLOAT_CLASS_POSITIVE_NORMAL 0x080 -+#define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100 -+#define FLOAT_CLASS_POSITIVE_ZERO 0x200 -+ -+target_ulong helper_movfcsr2gr(CPULOONGARCHState *env, uint32_t reg) -+{ -+ target_ulong r = 0; -+ -+ switch (reg) { -+ case 0: -+ r = (uint32_t)env->active_fpu.fcsr0; -+ break; -+ case 1: -+ r = (env->active_fpu.fcsr0 & FCSR0_M1); -+ break; -+ case 2: -+ r = (env->active_fpu.fcsr0 & FCSR0_M2); -+ break; -+ case 3: -+ r = (env->active_fpu.fcsr0 & FCSR0_M3); -+ break; -+ case 16: -+ r = (uint32_t)env->active_fpu.vcsr16; -+ break; -+ default: -+ printf("%s: warning, fcsr '%d' not supported\n", __func__, reg); -+ assert(0); -+ break; -+ } -+ -+ return r; -+} -+ -+void helper_movgr2fcsr(CPULOONGARCHState *env, target_ulong arg1, -+ uint32_t fcsr, uint32_t rj) -+{ -+ switch (fcsr) { -+ case 0: -+ env->active_fpu.fcsr0 = arg1; -+ break; -+ case 1: -+ env->active_fpu.fcsr0 = (arg1 & FCSR0_M1) | -+ (env->active_fpu.fcsr0 & ~FCSR0_M1); -+ break; -+ case 2: -+ env->active_fpu.fcsr0 = (arg1 & FCSR0_M2) | -+ (env->active_fpu.fcsr0 & ~FCSR0_M2); -+ break; -+ case 3: -+ env->active_fpu.fcsr0 = (arg1 & FCSR0_M3) | -+ (env->active_fpu.fcsr0 & ~FCSR0_M3); -+ break; -+ case 16: -+ env->active_fpu.vcsr16 = arg1; -+ break; -+ default: -+ printf("%s: warning, fcsr '%d' not supported\n", __func__, fcsr); -+ assert(0); -+ break; -+ } -+ restore_fp_status(env); -+ set_float_exception_flags(0, &env->active_fpu.fp_status); -+} -+ -+void helper_movreg2cf(CPULOONGARCHState *env, uint32_t cd, target_ulong src) -+{ -+ env->active_fpu.cf[cd & 0x7] = src & 0x1; -+} -+ -+void helper_movreg2cf_i32(CPULOONGARCHState *env, uint32_t cd, uint32_t src) -+{ -+ env->active_fpu.cf[cd & 0x7] = src & 0x1; -+} -+ -+void helper_movreg2cf_i64(CPULOONGARCHState *env, uint32_t cd, uint64_t src) -+{ -+ env->active_fpu.cf[cd & 0x7] = src & 0x1; -+} -+ -+target_ulong helper_movcf2reg(CPULOONGARCHState *env, uint32_t cj) -+{ -+ return (target_ulong)env->active_fpu.cf[cj & 0x7]; -+} -+ -+int ieee_ex_to_loongarch(int xcpt) -+{ -+ int ret = 0; -+ if (xcpt) { -+ if (xcpt & float_flag_invalid) { -+ ret |= FP_INVALID; -+ } -+ if (xcpt & float_flag_overflow) { -+ ret |= FP_OVERFLOW; -+ } -+ if (xcpt & float_flag_underflow) { -+ ret |= FP_UNDERFLOW; -+ } -+ if (xcpt & float_flag_divbyzero) { -+ ret |= FP_DIV0; -+ } -+ if (xcpt & float_flag_inexact) { -+ ret |= FP_INEXACT; -+ } -+ } -+ return ret; -+} -+ -+static inline void update_fcsr0(CPULOONGARCHState *env, uintptr_t pc) -+{ -+ int tmp = ieee_ex_to_loongarch(get_float_exception_flags( -+ &env->active_fpu.fp_status)); -+ -+ SET_FP_CAUSE(env->active_fpu.fcsr0, tmp); -+ if (tmp) { -+ set_float_exception_flags(0, &env->active_fpu.fp_status); -+ -+ if (GET_FP_ENABLE(env->active_fpu.fcsr0) & tmp) { -+ do_raise_exception(env, EXCP_FPE, pc); -+ } else { -+ UPDATE_FP_FLAGS(env->active_fpu.fcsr0, tmp); -+ } -+ } -+} -+ -+/* unary operations, modifying fp status */ -+uint64_t helper_float_sqrt_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdt0; -+} -+ -+uint32_t helper_float_sqrt_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fst0; -+} -+ -+uint64_t helper_float_cvtd_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint64_t fdt2; -+ -+ fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdt2; -+} -+ -+uint64_t helper_float_cvtd_w(CPULOONGARCHState *env, uint32_t wt0) -+{ -+ uint64_t fdt2; -+ -+ fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdt2; -+} -+ -+uint64_t helper_float_cvtd_l(CPULOONGARCHState *env, uint64_t dt0) -+{ -+ uint64_t fdt2; -+ -+ fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdt2; -+} -+ -+uint64_t helper_float_cvt_l_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t dt2; -+ -+ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint64_t helper_float_cvt_l_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint64_t dt2; -+ -+ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint32_t helper_float_cvts_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint32_t fst2; -+ -+ fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fst2; -+} -+ -+uint32_t helper_float_cvts_w(CPULOONGARCHState *env, uint32_t wt0) -+{ -+ uint32_t fst2; -+ -+ fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fst2; -+} -+ -+uint32_t helper_float_cvts_l(CPULOONGARCHState *env, uint64_t dt0) -+{ -+ uint32_t fst2; -+ -+ fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fst2; -+} -+ -+uint32_t helper_float_cvt_w_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t wt2; -+ -+ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint32_t helper_float_cvt_w_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint32_t wt2; -+ -+ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint64_t helper_float_round_l_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t dt2; -+ -+ set_float_rounding_mode(float_round_nearest_even, -+ &env->active_fpu.fp_status); -+ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint64_t helper_float_round_l_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint64_t dt2; -+ -+ set_float_rounding_mode(float_round_nearest_even, -+ &env->active_fpu.fp_status); -+ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint32_t helper_float_round_w_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint32_t wt2; -+ -+ set_float_rounding_mode(float_round_nearest_even, -+ &env->active_fpu.fp_status); -+ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint32_t helper_float_round_w_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t wt2; -+ -+ set_float_rounding_mode(float_round_nearest_even, -+ &env->active_fpu.fp_status); -+ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint64_t helper_float_trunc_l_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t dt2; -+ -+ dt2 = float64_to_int64_round_to_zero(fdt0, -+ &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint64_t helper_float_trunc_l_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint64_t dt2; -+ -+ dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint32_t helper_float_trunc_w_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint32_t wt2; -+ -+ wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint32_t helper_float_trunc_w_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t wt2; -+ -+ wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint64_t helper_float_ceil_l_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t dt2; -+ -+ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); -+ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint64_t helper_float_ceil_l_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint64_t dt2; -+ -+ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); -+ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint32_t helper_float_ceil_w_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint32_t wt2; -+ -+ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); -+ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint32_t helper_float_ceil_w_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t wt2; -+ -+ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); -+ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint64_t helper_float_floor_l_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t dt2; -+ -+ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); -+ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint64_t helper_float_floor_l_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint64_t dt2; -+ -+ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); -+ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint32_t helper_float_floor_w_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint32_t wt2; -+ -+ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); -+ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint32_t helper_float_floor_w_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t wt2; -+ -+ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); -+ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) -+ & (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+/* unary operations, not modifying fp status */ -+#define FLOAT_UNOP(name) \ -+uint64_t helper_float_ ## name ## _d(uint64_t fdt0) \ -+{ \ -+ return float64_ ## name(fdt0); \ -+} \ -+uint32_t helper_float_ ## name ## _s(uint32_t fst0) \ -+{ \ -+ return float32_ ## name(fst0); \ -+} -+ -+FLOAT_UNOP(abs) -+FLOAT_UNOP(chs) -+#undef FLOAT_UNOP -+ -+uint64_t helper_float_recip_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t fdt2; -+ -+ fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdt2; -+} -+ -+uint32_t helper_float_recip_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t fst2; -+ -+ fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fst2; -+} -+ -+uint64_t helper_float_rsqrt_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t fdt2; -+ -+ fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status); -+ fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdt2; -+} -+ -+uint32_t helper_float_rsqrt_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t fst2; -+ -+ fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status); -+ fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fst2; -+} -+ -+uint32_t helper_float_rint_s(CPULOONGARCHState *env, uint32_t fs) -+{ -+ uint32_t fdret; -+ -+ fdret = float32_round_to_int(fs, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdret; -+} -+ -+uint64_t helper_float_rint_d(CPULOONGARCHState *env, uint64_t fs) -+{ -+ uint64_t fdret; -+ -+ fdret = float64_round_to_int(fs, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdret; -+} -+ -+#define FLOAT_CLASS(name, bits) \ -+uint ## bits ## _t float_ ## name(uint ## bits ## _t arg, \ -+ float_status *status) \ -+{ \ -+ if (float ## bits ## _is_signaling_nan(arg, status)) { \ -+ return FLOAT_CLASS_SIGNALING_NAN; \ -+ } else if (float ## bits ## _is_quiet_nan(arg, status)) { \ -+ return FLOAT_CLASS_QUIET_NAN; \ -+ } else if (float ## bits ## _is_neg(arg)) { \ -+ if (float ## bits ## _is_infinity(arg)) { \ -+ return FLOAT_CLASS_NEGATIVE_INFINITY; \ -+ } else if (float ## bits ## _is_zero(arg)) { \ -+ return FLOAT_CLASS_NEGATIVE_ZERO; \ -+ } else if (float ## bits ## _is_zero_or_denormal(arg)) { \ -+ return FLOAT_CLASS_NEGATIVE_SUBNORMAL; \ -+ } else { \ -+ return FLOAT_CLASS_NEGATIVE_NORMAL; \ -+ } \ -+ } else { \ -+ if (float ## bits ## _is_infinity(arg)) { \ -+ return FLOAT_CLASS_POSITIVE_INFINITY; \ -+ } else if (float ## bits ## _is_zero(arg)) { \ -+ return FLOAT_CLASS_POSITIVE_ZERO; \ -+ } else if (float ## bits ## _is_zero_or_denormal(arg)) { \ -+ return FLOAT_CLASS_POSITIVE_SUBNORMAL; \ -+ } else { \ -+ return FLOAT_CLASS_POSITIVE_NORMAL; \ -+ } \ -+ } \ -+} \ -+ \ -+uint ## bits ## _t helper_float_ ## name(CPULOONGARCHState *env, \ -+ uint ## bits ## _t arg) \ -+{ \ -+ return float_ ## name(arg, &env->active_fpu.fp_status); \ -+} -+ -+FLOAT_CLASS(class_s, 32) -+FLOAT_CLASS(class_d, 64) -+#undef FLOAT_CLASS -+ -+/* binary operations */ -+#define FLOAT_BINOP(name) \ -+uint64_t helper_float_ ## name ## _d(CPULOONGARCHState *env, \ -+ uint64_t fdt0, uint64_t fdt1) \ -+{ \ -+ uint64_t dt2; \ -+ \ -+ dt2 = float64_ ## name(fdt0, fdt1, &env->active_fpu.fp_status);\ -+ update_fcsr0(env, GETPC()); \ -+ return dt2; \ -+} \ -+ \ -+uint32_t helper_float_ ## name ## _s(CPULOONGARCHState *env, \ -+ uint32_t fst0, uint32_t fst1) \ -+{ \ -+ uint32_t wt2; \ -+ \ -+ wt2 = float32_ ## name(fst0, fst1, &env->active_fpu.fp_status);\ -+ update_fcsr0(env, GETPC()); \ -+ return wt2; \ -+} -+ -+FLOAT_BINOP(add) -+FLOAT_BINOP(sub) -+FLOAT_BINOP(mul) -+FLOAT_BINOP(div) -+#undef FLOAT_BINOP -+ -+uint64_t helper_float_exp2_d(CPULOONGARCHState *env, -+ uint64_t fdt0, uint64_t fdt1) -+{ -+ uint64_t dt2; -+ int64_t n = (int64_t)fdt1; -+ -+ dt2 = float64_scalbn(fdt0, -+ n > 0x1000 ? 0x1000 : -+ n < -0x1000 ? -0x1000 : n, -+ &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint32_t helper_float_exp2_s(CPULOONGARCHState *env, -+ uint32_t fst0, uint32_t fst1) -+{ -+ uint32_t wt2; -+ int32_t n = (int32_t)fst1; -+ -+ wt2 = float32_scalbn(fst0, -+ n > 0x200 ? 0x200 : -+ n < -0x200 ? -0x200 : n, -+ &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+#define FLOAT_MINMAX(name, bits, minmaxfunc) \ -+uint ## bits ## _t helper_float_ ## name(CPULOONGARCHState *env, \ -+ uint ## bits ## _t fs, \ -+ uint ## bits ## _t ft) \ -+{ \ -+ uint ## bits ## _t fdret; \ -+ \ -+ fdret = float ## bits ## _ ## minmaxfunc(fs, ft, \ -+ &env->active_fpu.fp_status); \ -+ update_fcsr0(env, GETPC()); \ -+ return fdret; \ -+} -+ -+FLOAT_MINMAX(max_s, 32, maxnum) -+FLOAT_MINMAX(max_d, 64, maxnum) -+FLOAT_MINMAX(maxa_s, 32, maxnummag) -+FLOAT_MINMAX(maxa_d, 64, maxnummag) -+ -+FLOAT_MINMAX(min_s, 32, minnum) -+FLOAT_MINMAX(min_d, 64, minnum) -+FLOAT_MINMAX(mina_s, 32, minnummag) -+FLOAT_MINMAX(mina_d, 64, minnummag) -+#undef FLOAT_MINMAX -+ -+#define FLOAT_FMADDSUB(name, bits, muladd_arg) \ -+uint ## bits ## _t helper_float_ ## name(CPULOONGARCHState *env, \ -+ uint ## bits ## _t fs, \ -+ uint ## bits ## _t ft, \ -+ uint ## bits ## _t fd) \ -+{ \ -+ uint ## bits ## _t fdret; \ -+ \ -+ fdret = float ## bits ## _muladd(fs, ft, fd, muladd_arg, \ -+ &env->active_fpu.fp_status); \ -+ update_fcsr0(env, GETPC()); \ -+ return fdret; \ -+} -+ -+FLOAT_FMADDSUB(maddf_s, 32, 0) -+FLOAT_FMADDSUB(maddf_d, 64, 0) -+FLOAT_FMADDSUB(msubf_s, 32, float_muladd_negate_c) -+FLOAT_FMADDSUB(msubf_d, 64, float_muladd_negate_c) -+FLOAT_FMADDSUB(nmaddf_s, 32, float_muladd_negate_result) -+FLOAT_FMADDSUB(nmaddf_d, 64, float_muladd_negate_result) -+FLOAT_FMADDSUB(nmsubf_s, 32, float_muladd_negate_result | float_muladd_negate_c) -+FLOAT_FMADDSUB(nmsubf_d, 64, float_muladd_negate_result | float_muladd_negate_c) -+#undef FLOAT_FMADDSUB -+ -+/* compare operations */ -+#define FOP_CONDN_D(op, cond) \ -+uint64_t helper_cmp_d_ ## op(CPULOONGARCHState *env, uint64_t fdt0, \ -+ uint64_t fdt1) \ -+{ \ -+ uint64_t c; \ -+ c = cond; \ -+ update_fcsr0(env, GETPC()); \ -+ if (c) { \ -+ return -1; \ -+ } else { \ -+ return 0; \ -+ } \ -+} -+ -+/* -+ * NOTE: the comma operator will make "cond" to eval to false, -+ * but float64_unordered_quiet() is still called. -+ */ -+FOP_CONDN_D(af, (float64_unordered_quiet(fdt1, fdt0, -+ &env->active_fpu.fp_status), 0)) -+FOP_CONDN_D(un, (float64_unordered_quiet(fdt1, fdt0, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(eq, (float64_eq_quiet(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_eq_quiet(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(lt, (float64_lt_quiet(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_lt_quiet(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(le, (float64_le_quiet(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_le_quiet(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+/* -+ * NOTE: the comma operator will make "cond" to eval to false, -+ * but float64_unordered() is still called. -+ */ -+FOP_CONDN_D(saf, (float64_unordered(fdt1, fdt0, -+ &env->active_fpu.fp_status), 0)) -+FOP_CONDN_D(sun, (float64_unordered(fdt1, fdt0, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(seq, (float64_eq(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_eq(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(slt, (float64_lt(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_lt(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(sle, (float64_le(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_le(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(or, (float64_le_quiet(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_le_quiet(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(une, (float64_unordered_quiet(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_lt_quiet(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_lt_quiet(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(ne, (float64_lt_quiet(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_lt_quiet(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(sor, (float64_le(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_le(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_lt(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_lt(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_D(sne, (float64_lt(fdt1, fdt0, -+ &env->active_fpu.fp_status) -+ || float64_lt(fdt0, fdt1, -+ &env->active_fpu.fp_status))) -+ -+#define FOP_CONDN_S(op, cond) \ -+uint32_t helper_cmp_s_ ## op(CPULOONGARCHState *env, uint32_t fst0, \ -+ uint32_t fst1) \ -+{ \ -+ uint64_t c; \ -+ c = cond; \ -+ update_fcsr0(env, GETPC()); \ -+ if (c) { \ -+ return -1; \ -+ } else { \ -+ return 0; \ -+ } \ -+} -+ -+/* -+ * NOTE: the comma operator will make "cond" to eval to false, -+ * but float32_unordered_quiet() is still called. -+ */ -+FOP_CONDN_S(af, (float32_unordered_quiet(fst1, fst0, -+ &env->active_fpu.fp_status), 0)) -+FOP_CONDN_S(un, (float32_unordered_quiet(fst1, fst0, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(eq, (float32_eq_quiet(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(ueq, (float32_unordered_quiet(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_eq_quiet(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(lt, (float32_lt_quiet(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(ult, (float32_unordered_quiet(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_lt_quiet(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(le, (float32_le_quiet(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(ule, (float32_unordered_quiet(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_le_quiet(fst0, fst1, -+ &env->active_fpu.fp_status))) -+/* -+ * NOTE: the comma operator will make "cond" to eval to false, -+ * but float32_unordered() is still called. -+ */ -+FOP_CONDN_S(saf, (float32_unordered(fst1, fst0, -+ &env->active_fpu.fp_status), 0)) -+FOP_CONDN_S(sun, (float32_unordered(fst1, fst0, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(seq, (float32_eq(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_eq(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(slt, (float32_lt(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(sult, (float32_unordered(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_lt(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(sle, (float32_le(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(sule, (float32_unordered(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_le(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(or, (float32_le_quiet(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_le_quiet(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(une, (float32_unordered_quiet(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_lt_quiet(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_lt_quiet(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(ne, (float32_lt_quiet(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_lt_quiet(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(sor, (float32_le(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_le(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(sune, (float32_unordered(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_lt(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_lt(fst0, fst1, -+ &env->active_fpu.fp_status))) -+FOP_CONDN_S(sne, (float32_lt(fst1, fst0, -+ &env->active_fpu.fp_status) -+ || float32_lt(fst0, fst1, -+ &env->active_fpu.fp_status))) -+ -+uint32_t helper_float_logb_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t wt2; -+ -+ wt2 = float32_log2(fst0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint64_t helper_float_logb_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t dt2; -+ -+ dt2 = float64_log2(fdt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+target_ulong helper_fsel(CPULOONGARCHState *env, target_ulong fj, -+ target_ulong fk, uint32_t ca) -+{ -+ if (env->active_fpu.cf[ca & 0x7]) { -+ return fk; -+ } else { -+ return fj; -+ } -+} -diff --git a/target/loongarch64/fpu_helper.h b/target/loongarch64/fpu_helper.h -new file mode 100644 -index 000000000..b6898c2e9 ---- /dev/null -+++ b/target/loongarch64/fpu_helper.h -@@ -0,0 +1,129 @@ -+/* loongarch internal definitions and helpers -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or later. -+ * See the COPYING file in the top-level directory. -+ */ -+ -+#ifndef LOONGARCH_FPU_H -+#define LOONGARCH_FPU_H -+ -+#include "cpu-csr.h" -+ -+ -+extern const struct loongarch_def_t loongarch_defs[]; -+extern const int loongarch_defs_number; -+ -+enum CPULSXDataFormat { -+ DF_BYTE = 0, -+ DF_HALF, -+ DF_WORD, -+ DF_DOUBLE, -+ DF_QUAD -+}; -+ -+void loongarch_cpu_do_interrupt(CPUState *cpu); -+bool loongarch_cpu_exec_interrupt(CPUState *cpu, int int_req); -+void loongarch_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, -+ MMUAccessType access_type, -+ int mmu_idx, uintptr_t retaddr) QEMU_NORETURN; -+ -+#if !defined(CONFIG_USER_ONLY) -+ -+typedef struct r4k_tlb_t r4k_tlb_t; -+struct r4k_tlb_t { -+ target_ulong VPN; -+ uint32_t PageMask; -+ uint16_t ASID; -+ unsigned int G:1; -+ unsigned int C0:3; -+ unsigned int C1:3; -+ unsigned int V0:1; -+ unsigned int V1:1; -+ unsigned int D0:1; -+ unsigned int D1:1; -+ unsigned int XI0:1; -+ unsigned int XI1:1; -+ unsigned int RI0:1; -+ unsigned int RI1:1; -+ unsigned int EHINV:1; -+ uint64_t PPN[2]; -+}; -+ -+int no_mmu_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, -+ target_ulong address, int rw, int access_type); -+int fixed_mmu_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, -+ target_ulong address, int rw, int access_type); -+int r4k_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, -+ target_ulong address, int rw, int access_type); -+ -+/* loongarch 3a5000 tlb helper function : lisa csr */ -+int ls3a5k_map_address(CPULOONGARCHState *env, hwaddr *physical, -+ int *prot, target_ulong address, -+ int rw, int access_type); -+void ls3a5k_helper_tlbwr(CPULOONGARCHState *env); -+void ls3a5k_helper_tlbfill(CPULOONGARCHState *env); -+void ls3a5k_helper_tlbsrch(CPULOONGARCHState *env); -+void ls3a5k_helper_tlbrd(CPULOONGARCHState *env); -+void ls3a5k_helper_tlbclr(CPULOONGARCHState *env); -+void ls3a5k_helper_tlbflush(CPULOONGARCHState *env); -+void ls3a5k_invalidate_tlb(CPULOONGARCHState *env, int idx); -+void ls3a5k_helper_invtlb(CPULOONGARCHState *env, target_ulong addr, -+ target_ulong info, int op); -+void ls3a5k_flush_vtlb(CPULOONGARCHState *env); -+void ls3a5k_flush_ftlb(CPULOONGARCHState *env); -+/*void loongarch_cpu_unassigned_access(CPUState *cpu, hwaddr addr, -+ bool is_write, bool is_exec, int unused, -+ unsigned size); -+*/ -+hwaddr cpu_loongarch_translate_address(CPULOONGARCHState *env, target_ulong address, -+ int rw); -+#endif -+ -+#define cpu_signal_handler cpu_loongarch_signal_handler -+ -+ -+static inline bool cpu_loongarch_hw_interrupts_enabled(CPULOONGARCHState *env) -+{ -+ bool ret = 0; -+ -+ ret = env->CSR_CRMD & (1 << CSR_CRMD_IE_SHIFT); -+ -+ return ret; -+} -+ -+ -+void loongarch_tcg_init(void); -+ -+ -+/* helper.c */ -+bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, -+ MMUAccessType access_type, int mmu_idx, -+ bool probe, uintptr_t retaddr); -+ -+/* op_helper.c */ -+uint32_t float_class_s(uint32_t arg, float_status *fst); -+uint64_t float_class_d(uint64_t arg, float_status *fst); -+ -+int ieee_ex_to_loongarch(int xcpt); -+void update_pagemask(CPULOONGARCHState *env, target_ulong arg1, int32_t *pagemask); -+ -+void cpu_loongarch_tlb_flush(CPULOONGARCHState *env); -+void sync_c0_status(CPULOONGARCHState *env, CPULOONGARCHState *cpu, int tc); -+ -+void QEMU_NORETURN do_raise_exception_err(CPULOONGARCHState *env, uint32_t exception, -+ int error_code, uintptr_t pc); -+int loongarch_read_qxfer(CPUState *cs, const char *annex, -+ uint8_t *read_buf, -+ unsigned long offset, unsigned long len); -+int loongarch_write_qxfer(CPUState *cs, const char *annex, -+ const uint8_t *write_buf, -+ unsigned long offset, unsigned long len); -+ -+static inline void QEMU_NORETURN do_raise_exception(CPULOONGARCHState *env, -+ uint32_t exception, -+ uintptr_t pc) -+{ -+ do_raise_exception_err(env, exception, 0, pc); -+} -+ -+#endif -diff --git a/target/loongarch64/gdbstub.c b/target/loongarch64/gdbstub.c -new file mode 100644 -index 000000000..4013178f4 ---- /dev/null -+++ b/target/loongarch64/gdbstub.c -@@ -0,0 +1,109 @@ -+/* -+ * LOONGARCH 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 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 . -+ */ -+#include "qemu/osdep.h" -+#include "qemu-common.h" -+#include "cpu.h" -+#include "internal.h" -+#include "exec/gdbstub.h" -+#ifdef CONFIG_TCG -+#include "exec/helper-proto.h" -+#endif -+int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ if (0 <= n && n < 32) { -+ return gdb_get_regl(mem_buf, env->active_tc.gpr[n]); -+ } else if (n == 32) { -+ return gdb_get_regl(mem_buf, env->active_tc.PC); -+ } -+ return 0; -+} -+ -+int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ target_ulong tmp = ldtul_p(mem_buf); -+ -+ if (0 <= n && n < 32) { -+ return env->active_tc.gpr[n] = tmp, sizeof(target_ulong); -+ } else if (n == 32) { -+ return env->active_tc.PC = tmp, sizeof(target_ulong); -+ } -+ return 0; -+} -+ -+static int loongarch_gdb_get_fpu(CPULOONGARCHState *env, GByteArray *mem_buf, int n) -+{ -+ if (0 <= n && n < 32) { -+ return gdb_get_reg64(mem_buf, env->active_fpu.fpr[n].d); -+ } else if (32 <= n && n < 40) { -+ return gdb_get_reg8(mem_buf, env->active_fpu.cf[n - 32]); -+ } else if (n == 40) { -+ return gdb_get_reg32(mem_buf, env->active_fpu.fcsr0); -+ } -+ return 0; -+} -+ -+static int loongarch_gdb_set_fpu(CPULOONGARCHState *env, uint8_t *mem_buf, int n) -+{ -+ if (0 <= n && n < 32) { -+ return env->active_fpu.fpr[n].d = ldq_p(mem_buf), 8; -+ } else if (32 <= n && n < 40) { -+ return env->active_fpu.cf[n - 32] = ldub_p(mem_buf), 1; -+ } else if (n == 40) { -+ return env->active_fpu.fcsr0 = ldl_p(mem_buf), 4; -+ } -+ return 0; -+} -+ -+void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs) -+{ -+ gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, -+ 41, "loongarch-fpu64.xml", 0); -+} -+ -+#ifdef CONFIG_TCG -+int loongarch_read_qxfer(CPUState *cs, const char *annex, uint8_t *read_buf, -+ unsigned long offset, unsigned long len) -+{ -+ if (strncmp(annex, "cpucfg", sizeof("cpucfg") - 1) == 0) { -+ if (offset % 4 != 0 || len % 4 != 0) { -+ return 0; -+ } -+ -+ size_t i; -+ for (i = offset; i < offset + len; i += 4) -+ ((uint32_t *)read_buf)[(i - offset) / 4] = -+ helper_cpucfg(&(LOONGARCH_CPU(cs)->env), i / 4); -+ return 32 * 4; -+ } -+ return 0; -+} -+ -+int loongarch_write_qxfer(CPUState *cs, const char *annex, -+ const uint8_t *write_buf, unsigned long offset, -+ unsigned long len) -+{ -+ return 0; -+} -+#endif -diff --git a/target/loongarch64/helper.c b/target/loongarch64/helper.c -new file mode 100644 -index 000000000..841240e57 ---- /dev/null -+++ b/target/loongarch64/helper.c -@@ -0,0 +1,727 @@ -+/* -+ * LOONGARCH emulation helpers for qemu. -+ * -+ * Copyright (c) 2004-2005 Jocelyn Mayer -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "internal.h" -+#include "exec/exec-all.h" -+#include "exec/cpu_ldst.h" -+#include "exec/log.h" -+#include "hw/loongarch/cpudevs.h" -+ -+ -+#if !defined(CONFIG_USER_ONLY) -+ -+static int ls3a5k_map_address_tlb_entry( -+ CPULOONGARCHState *env, -+ hwaddr *physical, -+ int *prot, -+ target_ulong address, -+ int rw, -+ int access_type, -+ ls3a5k_tlb_t *tlb) -+{ -+ uint64_t mask = tlb->PageMask; -+ int n = !!(address & mask & ~(mask >> 1)); -+ uint32_t plv = env->CSR_CRMD & CSR_CRMD_PLV; -+ -+ /* Check access rights */ -+ if (!(n ? tlb->V1 : tlb->V0)) { -+ return TLBRET_INVALID; -+ } -+ -+ if (rw == MMU_INST_FETCH && (n ? tlb->XI1 : tlb->XI0)) { -+ return TLBRET_XI; -+ } -+ -+ if (rw == MMU_DATA_LOAD && (n ? tlb->RI1 : tlb->RI0)) { -+ return TLBRET_RI; -+ } -+ -+ if (plv > (n ? tlb->PLV1 : tlb->PLV0)) { -+ return TLBRET_PE; -+ } -+ -+ if (rw != MMU_DATA_STORE || (n ? tlb->WE1 : tlb->WE0)) { -+ /* PPN address -+ * 4 KB: [47:13] [12;0] -+ * 16 KB: [47:15] [14:0] -+ */ -+ if (n) { -+ *physical = tlb->PPN1 | (address & (mask >> 1)); -+ } else { -+ *physical = tlb->PPN0 | (address & (mask >> 1)); -+ } -+ *prot = PAGE_READ; -+ if (n ? tlb->WE1 : tlb->WE0) { -+ *prot |= PAGE_WRITE; -+ } -+ if (!(n ? tlb->XI1 : tlb->XI0)) { -+ *prot |= PAGE_EXEC; -+ } -+ return TLBRET_MATCH; -+ } -+ -+ return TLBRET_DIRTY; -+} -+ -+/* Loongarch 3A5K -style MMU emulation */ -+int ls3a5k_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, -+ target_ulong address, int rw, int access_type) -+{ -+ uint16_t asid = env->CSR_ASID & 0x3ff; -+ int i; -+ ls3a5k_tlb_t *tlb; -+ -+ int ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; -+ int vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; -+ -+ int ftlb_idx; -+ -+ uint64_t mask; -+ uint64_t vpn; /* address to map */ -+ uint64_t tag; /* address in TLB entry */ -+ -+ /* search VTLB */ -+ for (i = ftlb_size; i < ftlb_size + vtlb_size; ++i) { -+ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ mask = tlb->PageMask; -+ -+ vpn = address & 0xffffffffe000 & ~mask; -+ tag = tlb->VPN & ~mask; -+ -+ if ((tlb->G == 1 || tlb->ASID == asid) -+ && vpn == tag -+ && tlb->EHINV != 1) -+ { -+ return ls3a5k_map_address_tlb_entry(env, physical, prot, -+ address, rw, access_type, tlb); -+ } -+ } -+ -+ if (ftlb_size == 0) { -+ return TLBRET_NOMATCH; -+ } -+ -+ /* search FTLB */ -+ mask = env->tlb->mmu.ls3a5k.ftlb_mask; -+ vpn = address & 0xffffffffe000 & ~mask; -+ -+ ftlb_idx = (address & 0xffffffffc000) >> 15; /* 16 KB */ -+ ftlb_idx = ftlb_idx & 0xff; /* [0,255] */ -+ -+ for (i = 0; i < 8; ++i) { -+ /* ---------- set 0 1 2 ... 7 -+ * ftlb_idx ----------------------------------- -+ * 0 | 0 1 2 ... 7 -+ * 1 | 8 9 10 ... 15 -+ * 2 | 16 17 18 ... 23 -+ * ... | -+ * 255 | 2040 2041 2042 ... 2047 -+ */ -+ tlb = &env->tlb->mmu.ls3a5k.tlb[ftlb_idx * 8 + i]; -+ tag = tlb->VPN & ~mask; -+ -+ if ((tlb->G == 1 || tlb->ASID == asid) -+ && vpn == tag -+ && tlb->EHINV != 1) -+ { -+ return ls3a5k_map_address_tlb_entry(env, physical, prot, -+ address, rw, access_type, tlb); -+ } -+ } -+ -+ return TLBRET_NOMATCH; -+} -+ -+static int get_physical_address(CPULOONGARCHState *env, hwaddr *physical, -+ int *prot, target_ulong real_address, -+ int rw, int access_type, int mmu_idx) -+{ -+ int user_mode = mmu_idx == LARCH_HFLAG_UM; -+ int kernel_mode = !user_mode; -+ unsigned plv, base_c, base_v, tmp; -+ -+ /* effective address (modified for KVM T&E kernel segments) */ -+ target_ulong address = real_address; -+ -+ /* Check PG */ -+ if (!(env->CSR_CRMD & CSR_CRMD_PG)) { -+ /* DA mode */ -+ *physical = address & 0xffffffffffffUL; -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ -+ plv = kernel_mode | (user_mode << 3); -+ base_v = address >> CSR_DMW_BASE_SH; -+ /* Check direct map window 0 */ -+ base_c = env->CSR_DMWIN0 >> CSR_DMW_BASE_SH; -+ if ((plv & env->CSR_DMWIN0) && (base_c == base_v)) { -+ *physical = dmwin_va2pa(address); -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ /* Check direct map window 1 */ -+ base_c = env->CSR_DMWIN1 >> CSR_DMW_BASE_SH; -+ if ((plv & env->CSR_DMWIN1) && (base_c == base_v)) { -+ *physical = dmwin_va2pa(address); -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ /* Check valid extension */ -+ tmp = address >> 47; -+ if (!(tmp == 0 || tmp == 0x1ffff)) { -+ return TLBRET_BADADDR; -+ } -+ /* mapped address */ -+ return env->tlb->map_address(env, physical, prot, real_address, rw, -+ access_type); -+} -+ -+void cpu_loongarch_tlb_flush(CPULOONGARCHState *env) -+{ -+ LOONGARCHCPU *cpu = loongarch_env_get_cpu(env); -+ -+ /* Flush qemu's TLB and discard all shadowed entries. */ -+ tlb_flush(CPU(cpu)); -+ env->tlb->tlb_in_use = env->tlb->nb_tlb; -+} -+#endif -+ -+static void raise_mmu_exception(CPULOONGARCHState *env, target_ulong address, -+ int rw, int tlb_error) -+{ -+ CPUState *cs = CPU(loongarch_env_get_cpu(env)); -+ int exception = 0, error_code = 0; -+ -+ if (rw == MMU_INST_FETCH) { -+ error_code |= EXCP_INST_NOTAVAIL; -+ } -+ -+ switch (tlb_error) { -+ default: -+ case TLBRET_BADADDR: -+ /* Reference to kernel address from user mode or supervisor mode */ -+ /* Reference to supervisor address from user mode */ -+ if (rw == MMU_DATA_STORE) { -+ exception = EXCP_AdES; -+ } else { -+ exception = EXCP_AdEL; -+ } -+ break; -+ case TLBRET_NOMATCH: -+ /* No TLB match for a mapped address */ -+ if (rw == MMU_DATA_STORE) { -+ exception = EXCP_TLBS; -+ } else { -+ exception = EXCP_TLBL; -+ } -+ error_code |= EXCP_TLB_NOMATCH; -+ break; -+ case TLBRET_INVALID: -+ /* TLB match with no valid bit */ -+ if (rw == MMU_DATA_STORE) { -+ exception = EXCP_TLBS; -+ } else { -+ exception = EXCP_TLBL; -+ } -+ break; -+ case TLBRET_DIRTY: -+ /* TLB match but 'D' bit is cleared */ -+ exception = EXCP_LTLBL; -+ break; -+ case TLBRET_XI: -+ /* Execute-Inhibit Exception */ -+ exception = EXCP_TLBXI; -+ break; -+ case TLBRET_RI: -+ /* Read-Inhibit Exception */ -+ exception = EXCP_TLBRI; -+ break; -+ case TLBRET_PE: -+ /* Privileged Exception */ -+ exception = EXCP_TLBPE; -+ break; -+ } -+ -+ if (env->insn_flags & INSN_LOONGARCH) { -+ if (tlb_error == TLBRET_NOMATCH) { -+ env->CSR_TLBRBADV = address; -+ env->CSR_TLBREHI = address & (TARGET_PAGE_MASK << 1); -+ cs->exception_index = exception; -+ env->error_code = error_code; -+ return; -+ } -+ } -+ -+ /* Raise exception */ -+ env->CSR_BADV = address; -+ cs->exception_index = exception; -+ env->error_code = error_code; -+ -+ if (env->insn_flags & INSN_LOONGARCH) { -+ env->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1); -+ } -+} -+ -+bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, -+ MMUAccessType access_type, int mmu_idx, -+ bool probe, uintptr_t retaddr) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+#if !defined(CONFIG_USER_ONLY) -+ hwaddr physical; -+ int prot; -+ int loongarch_access_type; -+#endif -+ int ret = TLBRET_BADADDR; -+ -+ qemu_log_mask(CPU_LOG_MMU, -+ "%s pc " TARGET_FMT_lx " ad %" VADDR_PRIx " mmu_idx %d\n", -+ __func__, env->active_tc.PC, address, mmu_idx); -+ -+ /* data access */ -+#if !defined(CONFIG_USER_ONLY) -+ /* XXX: put correct access by using cpu_restore_state() correctly */ -+ loongarch_access_type = ACCESS_INT; -+ ret = get_physical_address(env, &physical, &prot, address, -+ access_type, loongarch_access_type, mmu_idx); -+ switch (ret) { -+ case TLBRET_MATCH: -+ qemu_log_mask(CPU_LOG_MMU, -+ "%s address=%" VADDR_PRIx " physical " TARGET_FMT_plx -+ " prot %d asid %ld pc 0x%lx\n", -+ __func__, address, physical, prot, -+ env->CSR_ASID, env->active_tc.PC); -+ break; -+ default: -+ qemu_log_mask(CPU_LOG_MMU, -+ "%s address=%" VADDR_PRIx " ret %d asid %ld pc 0x%lx\n", -+ __func__, address, ret, env->CSR_ASID, env->active_tc.PC); -+ break; -+ } -+ if (ret == TLBRET_MATCH) { -+ tlb_set_page(cs, address & TARGET_PAGE_MASK, -+ physical & TARGET_PAGE_MASK, prot | PAGE_EXEC, -+ mmu_idx, TARGET_PAGE_SIZE); -+ ret = true; -+ } -+ if (probe) { -+ return false; -+ } -+#endif -+ -+ raise_mmu_exception(env, address, access_type, ret); -+ do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr); -+} -+ -+#if !defined(CONFIG_USER_ONLY) -+hwaddr cpu_loongarch_translate_address(CPULOONGARCHState *env, -+ target_ulong address, int rw) -+{ -+ hwaddr physical; -+ int prot; -+ int access_type; -+ int ret = 0; -+ -+ /* data access */ -+ access_type = ACCESS_INT; -+ ret = get_physical_address(env, &physical, &prot, address, rw, access_type, -+ cpu_mmu_index(env, false)); -+ if (ret != TLBRET_MATCH) { -+ raise_mmu_exception(env, address, rw, ret); -+ return -1LL; -+ } else { -+ return physical; -+ } -+} -+ -+static const char * const excp_names[EXCP_LAST + 1] = { -+ [EXCP_RESET] = "reset", -+ [EXCP_SRESET] = "soft reset", -+ [EXCP_NMI] = "non-maskable interrupt", -+ [EXCP_EXT_INTERRUPT] = "interrupt", -+ [EXCP_AdEL] = "address error load", -+ [EXCP_AdES] = "address error store", -+ [EXCP_TLBF] = "TLB refill", -+ [EXCP_IBE] = "instruction bus error", -+ [EXCP_SYSCALL] = "syscall", -+ [EXCP_BREAK] = "break", -+ [EXCP_FPDIS] = "float unit unusable", -+ [EXCP_LSXDIS] = "vector128 unusable", -+ [EXCP_LASXDIS] = "vector256 unusable", -+ [EXCP_RI] = "reserved instruction", -+ [EXCP_OVERFLOW] = "arithmetic overflow", -+ [EXCP_TRAP] = "trap", -+ [EXCP_FPE] = "floating point", -+ [EXCP_LTLBL] = "TLB modify", -+ [EXCP_TLBL] = "TLB load", -+ [EXCP_TLBS] = "TLB store", -+ [EXCP_DBE] = "data bus error", -+ [EXCP_TLBXI] = "TLB execute-inhibit", -+ [EXCP_TLBRI] = "TLB read-inhibit", -+ [EXCP_TLBPE] = "TLB priviledged error", -+}; -+#endif -+ -+target_ulong exception_resume_pc(CPULOONGARCHState *env) -+{ -+ target_ulong bad_pc; -+ -+ bad_pc = env->active_tc.PC; -+ if (env->hflags & LARCH_HFLAG_BMASK) { -+ /* If the exception was raised from a delay slot, come back to -+ the jump. */ -+ bad_pc -= 4; -+ } -+ -+ return bad_pc; -+} -+ -+#if !defined(CONFIG_USER_ONLY) -+static void set_hflags_for_handler (CPULOONGARCHState *env) -+{ -+ /* Exception handlers are entered in 32-bit mode. */ -+} -+ -+static inline void set_badinstr_registers(CPULOONGARCHState *env) -+{ -+ if ((env->insn_flags & INSN_LOONGARCH)) { -+ env->CSR_BADI = cpu_ldl_code(env, env->active_tc.PC); -+ return; -+ } -+} -+#endif -+ -+static inline unsigned int get_vint_size(CPULOONGARCHState *env) -+{ -+ unsigned int size = 0; -+ -+ switch ((env->CSR_ECFG >> 16) & 0x7) { -+ case 0: -+ break; -+ case 1: -+ size = 2 * 4; /* #Insts * inst_size */ -+ break; -+ case 2: -+ size = 4 * 4; -+ break; -+ case 3: -+ size = 8 * 4; -+ break; -+ case 4: -+ size = 16 * 4; -+ break; -+ case 5: -+ size = 32 * 4; -+ break; -+ case 6: -+ size = 64 * 4; -+ break; -+ case 7: -+ size = 128 * 4; -+ break; -+ default: -+ printf("%s: unexpected value", __func__); -+ assert(0); -+ } -+ -+ return size; -+} -+ -+#define is_refill(cs, env) (((cs->exception_index == EXCP_TLBL) \ -+ || (cs->exception_index == EXCP_TLBS)) \ -+ && (env->error_code & EXCP_TLB_NOMATCH)) -+ -+void loongarch_cpu_do_interrupt(CPUState *cs) -+{ -+#if !defined(CONFIG_USER_ONLY) -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ bool update_badinstr = 0; -+ int cause = -1; -+ const char *name; -+ -+ if (qemu_loglevel_mask(CPU_LOG_INT) -+ && cs->exception_index != EXCP_EXT_INTERRUPT) { -+ if (cs->exception_index < 0 || cs->exception_index > EXCP_LAST) { -+ name = "unknown"; -+ } else { -+ name = excp_names[cs->exception_index]; -+ } -+ -+ qemu_log("%s enter: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx -+ " TLBRERA 0x%016lx" " %s exception\n", __func__, -+ env->active_tc.PC, env->CSR_ERA, env->CSR_TLBRERA, name); -+ } -+ -+ switch (cs->exception_index) { -+ case EXCP_RESET: -+ cpu_reset(CPU(cpu)); -+ break; -+ case EXCP_NMI: -+ env->CSR_ERRERA = exception_resume_pc(env); -+ env->hflags &= ~LARCH_HFLAG_BMASK; -+ env->hflags |= LARCH_HFLAG_64; -+ env->hflags &= ~LARCH_HFLAG_AWRAP; -+ env->hflags &= ~(LARCH_HFLAG_KSU); -+ env->active_tc.PC = env->exception_base; -+ set_hflags_for_handler(env); -+ break; -+ case EXCP_EXT_INTERRUPT: -+ cause = 0; -+ goto set_ERA; -+ case EXCP_LTLBL: -+ cause = 1; -+ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); -+ goto set_ERA; -+ case EXCP_TLBL: -+ cause = 2; -+ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); -+ goto set_ERA; -+ case EXCP_TLBS: -+ cause = 3; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_AdEL: -+ cause = 4; -+ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); -+ goto set_ERA; -+ case EXCP_AdES: -+ cause = 5; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_IBE: -+ cause = 6; -+ goto set_ERA; -+ case EXCP_DBE: -+ cause = 7; -+ goto set_ERA; -+ case EXCP_SYSCALL: -+ cause = 8; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_BREAK: -+ cause = 9; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_RI: -+ cause = 10; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_FPDIS: -+ case EXCP_LSXDIS: -+ case EXCP_LASXDIS: -+ cause = 11; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_OVERFLOW: -+ cause = 12; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_TRAP: -+ cause = 13; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_FPE: -+ cause = 15; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_TLBRI: -+ cause = 19; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_TLBXI: -+ case EXCP_TLBPE: -+ cause = 20; -+ goto set_ERA; -+ set_ERA: -+ if (is_refill(cs, env)) { -+ env->CSR_TLBRERA = exception_resume_pc(env); -+ env->CSR_TLBRERA |= 1; -+ } else { -+ env->CSR_ERA = exception_resume_pc(env); -+ } -+ -+ if (update_badinstr) { -+ set_badinstr_registers(env); -+ } -+ env->hflags &= ~(LARCH_HFLAG_KSU); -+ -+ env->hflags &= ~LARCH_HFLAG_BMASK; -+ if (env->insn_flags & INSN_LOONGARCH) { -+ /* save PLV and IE */ -+ if (is_refill(cs, env)) { -+ env->CSR_TLBRPRMD &= (~0x7); -+ env->CSR_TLBRPRMD |= (env->CSR_CRMD & 0x7); -+ } else { -+ env->CSR_PRMD &= (~0x7); -+ env->CSR_PRMD |= (env->CSR_CRMD & 0x7); -+ } -+ -+ env->CSR_CRMD &= ~(0x7); -+ -+ switch (cs->exception_index) { -+ case EXCP_EXT_INTERRUPT: -+ break; -+ case EXCP_TLBL: -+ if (env->error_code & EXCP_INST_NOTAVAIL) { -+ cause = EXCCODE_TLBI; -+ } else { -+ cause = EXCCODE_TLBL; -+ } -+ break; -+ case EXCP_TLBS: -+ cause = EXCCODE_TLBS; -+ break; -+ case EXCP_LTLBL: -+ cause = EXCCODE_MOD; -+ break; -+ case EXCP_TLBRI: -+ cause = EXCCODE_TLBRI; -+ break; -+ case EXCP_TLBXI: -+ cause = EXCCODE_TLBXI; -+ break; -+ case EXCP_TLBPE: -+ cause = EXCCODE_TLBPE; -+ break; -+ case EXCP_AdEL: -+ case EXCP_AdES: -+ case EXCP_IBE: -+ case EXCP_DBE: -+ cause = EXCCODE_ADE; -+ break; -+ case EXCP_SYSCALL: -+ cause = EXCCODE_SYS; -+ break; -+ case EXCP_BREAK: -+ cause = EXCCODE_BP; -+ break; -+ case EXCP_RI: -+ cause = EXCCODE_RI; -+ break; -+ case EXCP_FPDIS: -+ cause = EXCCODE_FPDIS; -+ break; -+ case EXCP_LSXDIS: -+ cause = EXCCODE_LSXDIS; -+ break; -+ case EXCP_LASXDIS: -+ cause = EXCCODE_LASXDIS; -+ break; -+ case EXCP_FPE: -+ cause = EXCCODE_FPE; -+ break; -+ default: -+ printf("Error: exception(%d) '%s' has not been supported\n", -+ cs->exception_index, excp_names[cs->exception_index]); -+ abort(); -+ } -+ -+ uint32_t vec_size = get_vint_size(env); -+ env->active_tc.PC = env->CSR_EEPN; -+ env->active_tc.PC += cause * vec_size; -+ if (is_refill(cs, env)) { -+ /* TLB Refill */ -+ env->active_tc.PC = env->CSR_TLBRENT; -+ break; /* Do not modify excode */ -+ } -+ if (cs->exception_index == EXCP_EXT_INTERRUPT) { -+ /* Interrupt */ -+ uint32_t vector = 0; -+ uint32_t pending = env->CSR_ESTAT & CSR_ESTAT_IPMASK; -+ pending &= env->CSR_ECFG & CSR_ECFG_IPMASK; -+ -+ /* Find the highest-priority interrupt. */ -+ while (pending >>= 1) { -+ vector++; -+ } -+ env->active_tc.PC = env->CSR_EEPN + -+ (EXCODE_IP + vector) * vec_size; -+ if (qemu_loglevel_mask(CPU_LOG_INT)) { -+ qemu_log("%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx -+ " cause %d\n" " A " TARGET_FMT_lx " D " -+ TARGET_FMT_lx " vector = %d ExC %08lx ExS %08lx\n", -+ __func__, env->active_tc.PC, env->CSR_ERA, -+ cause, env->CSR_BADV, env->CSR_DERA, vector, -+ env->CSR_ECFG, env->CSR_ESTAT); -+ } -+ } -+ /* Excode */ -+ env->CSR_ESTAT = (env->CSR_ESTAT & ~(0x1f << CSR_ESTAT_EXC_SH)) | -+ (cause << CSR_ESTAT_EXC_SH); -+ } -+ set_hflags_for_handler(env); -+ break; -+ default: -+ abort(); -+ } -+ if (qemu_loglevel_mask(CPU_LOG_INT) -+ && cs->exception_index != EXCP_EXT_INTERRUPT) { -+ qemu_log("%s: PC " TARGET_FMT_lx " ERA 0x%08lx" " cause %d%s\n" -+ " ESTAT %08lx EXCFG 0x%08lx BADVA 0x%08lx BADI 0x%08lx \ -+ SYS_NUM %lu cpu %d asid 0x%lx" "\n", -+ __func__, env->active_tc.PC, -+ is_refill(cs, env) ? env->CSR_TLBRERA : env->CSR_ERA, -+ cause, -+ is_refill(cs, env) ? "(refill)" : "", -+ env->CSR_ESTAT, env->CSR_ECFG, -+ is_refill(cs, env) ? env->CSR_TLBRBADV : env->CSR_BADV, -+ env->CSR_BADI, env->active_tc.gpr[11], cs->cpu_index, -+ env->CSR_ASID -+ ); -+ } -+#endif -+ cs->exception_index = EXCP_NONE; -+} -+ -+bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request) -+{ -+ if (interrupt_request & CPU_INTERRUPT_HARD) { -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ if (cpu_loongarch_hw_interrupts_enabled(env) && -+ cpu_loongarch_hw_interrupts_pending(env)) { -+ /* Raise it */ -+ cs->exception_index = EXCP_EXT_INTERRUPT; -+ env->error_code = 0; -+ loongarch_cpu_do_interrupt(cs); -+ return true; -+ } -+ } -+ return false; -+} -+ -+void QEMU_NORETURN do_raise_exception_err(CPULOONGARCHState *env, -+ uint32_t exception, -+ int error_code, -+ uintptr_t pc) -+{ -+ CPUState *cs = CPU(loongarch_env_get_cpu(env)); -+ -+ qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n", -+ __func__, exception, error_code); -+ cs->exception_index = exception; -+ env->error_code = error_code; -+ -+ cpu_loop_exit_restore(cs, pc); -+} -diff --git a/target/loongarch64/helper.h b/target/loongarch64/helper.h -new file mode 100644 -index 000000000..ff2026ed8 ---- /dev/null -+++ b/target/loongarch64/helper.h -@@ -0,0 +1,168 @@ -+DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int) -+DEF_HELPER_2(raise_exception, noreturn, env, i32) -+DEF_HELPER_1(raise_exception_debug, noreturn, env) -+ -+#if 0 -+#ifndef CONFIG_USER_ONLY -+DEF_HELPER_3(ll, tl, env, tl, int) -+DEF_HELPER_3(lld, tl, env, tl, int) -+#endif -+#endif -+ -+DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl) -+DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl) -+ -+DEF_HELPER_3(crc32, tl, tl, tl, i32) -+DEF_HELPER_3(crc32c, tl, tl, tl, i32) -+ -+#ifndef CONFIG_USER_ONLY -+/* LoongISA CSR register */ -+DEF_HELPER_2(csr_rdq, tl, env, i64) -+DEF_HELPER_3(csr_wrq, tl, env, tl, i64) -+DEF_HELPER_4(csr_xchgq, tl, env, tl, tl, i64) -+ -+#endif /* !CONFIG_USER_ONLY */ -+ -+/* CP1 functions */ -+DEF_HELPER_2(movfcsr2gr, tl, env, i32) -+DEF_HELPER_4(movgr2fcsr, void, env, tl, i32, i32) -+ -+DEF_HELPER_2(float_cvtd_s, i64, env, i32) -+DEF_HELPER_2(float_cvtd_w, i64, env, i32) -+DEF_HELPER_2(float_cvtd_l, i64, env, i64) -+DEF_HELPER_2(float_cvts_d, i32, env, i64) -+DEF_HELPER_2(float_cvts_w, i32, env, i32) -+DEF_HELPER_2(float_cvts_l, i32, env, i64) -+ -+DEF_HELPER_FLAGS_2(float_class_s, TCG_CALL_NO_RWG_SE, i32, env, i32) -+DEF_HELPER_FLAGS_2(float_class_d, TCG_CALL_NO_RWG_SE, i64, env, i64) -+ -+#define FOP_PROTO(op) \ -+DEF_HELPER_4(float_ ## op ## _s, i32, env, i32, i32, i32) \ -+DEF_HELPER_4(float_ ## op ## _d, i64, env, i64, i64, i64) -+FOP_PROTO(maddf) -+FOP_PROTO(msubf) -+FOP_PROTO(nmaddf) -+FOP_PROTO(nmsubf) -+#undef FOP_PROTO -+ -+#define FOP_PROTO(op) \ -+DEF_HELPER_3(float_ ## op ## _s, i32, env, i32, i32) \ -+DEF_HELPER_3(float_ ## op ## _d, i64, env, i64, i64) -+FOP_PROTO(max) -+FOP_PROTO(maxa) -+FOP_PROTO(min) -+FOP_PROTO(mina) -+#undef FOP_PROTO -+ -+#define FOP_PROTO(op) \ -+DEF_HELPER_2(float_ ## op ## _l_s, i64, env, i32) \ -+DEF_HELPER_2(float_ ## op ## _l_d, i64, env, i64) \ -+DEF_HELPER_2(float_ ## op ## _w_s, i32, env, i32) \ -+DEF_HELPER_2(float_ ## op ## _w_d, i32, env, i64) -+FOP_PROTO(cvt) -+FOP_PROTO(round) -+FOP_PROTO(trunc) -+FOP_PROTO(ceil) -+FOP_PROTO(floor) -+#undef FOP_PROTO -+ -+#define FOP_PROTO(op) \ -+DEF_HELPER_2(float_ ## op ## _s, i32, env, i32) \ -+DEF_HELPER_2(float_ ## op ## _d, i64, env, i64) -+FOP_PROTO(sqrt) -+FOP_PROTO(rsqrt) -+FOP_PROTO(recip) -+FOP_PROTO(rint) -+#undef FOP_PROTO -+ -+#define FOP_PROTO(op) \ -+DEF_HELPER_1(float_ ## op ## _s, i32, i32) \ -+DEF_HELPER_1(float_ ## op ## _d, i64, i64) -+FOP_PROTO(abs) -+FOP_PROTO(chs) -+#undef FOP_PROTO -+ -+#define FOP_PROTO(op) \ -+DEF_HELPER_3(float_ ## op ## _s, i32, env, i32, i32) \ -+DEF_HELPER_3(float_ ## op ## _d, i64, env, i64, i64) -+FOP_PROTO(add) -+FOP_PROTO(sub) -+FOP_PROTO(mul) -+FOP_PROTO(div) -+#undef FOP_PROTO -+ -+#define FOP_PROTO(op) \ -+DEF_HELPER_3(cmp_d_ ## op, i64, env, i64, i64) \ -+DEF_HELPER_3(cmp_s_ ## op, i32, env, i32, i32) -+FOP_PROTO(af) -+FOP_PROTO(un) -+FOP_PROTO(eq) -+FOP_PROTO(ueq) -+FOP_PROTO(lt) -+FOP_PROTO(ult) -+FOP_PROTO(le) -+FOP_PROTO(ule) -+FOP_PROTO(saf) -+FOP_PROTO(sun) -+FOP_PROTO(seq) -+FOP_PROTO(sueq) -+FOP_PROTO(slt) -+FOP_PROTO(sult) -+FOP_PROTO(sle) -+FOP_PROTO(sule) -+FOP_PROTO(or) -+FOP_PROTO(une) -+FOP_PROTO(ne) -+FOP_PROTO(sor) -+FOP_PROTO(sune) -+FOP_PROTO(sne) -+#undef FOP_PROTO -+ -+/* Special functions */ -+#ifndef CONFIG_USER_ONLY -+DEF_HELPER_1(tlbwr, void, env) -+DEF_HELPER_1(tlbfill, void, env) -+DEF_HELPER_1(tlbsrch, void, env) -+DEF_HELPER_1(tlbrd, void, env) -+DEF_HELPER_1(tlbclr, void, env) -+DEF_HELPER_1(tlbflush, void, env) -+DEF_HELPER_4(invtlb, void, env, tl, tl, tl) -+DEF_HELPER_1(ertn, void, env) -+DEF_HELPER_5(lddir, void, env, tl, tl, tl, i32) -+DEF_HELPER_4(ldpte, void, env, tl, tl, i32) -+DEF_HELPER_3(drdtime, void, env, tl, tl) -+DEF_HELPER_1(read_pgd, tl, env) -+#endif /* !CONFIG_USER_ONLY */ -+DEF_HELPER_2(cpucfg, tl, env, tl) -+DEF_HELPER_1(idle, void, env) -+ -+DEF_HELPER_3(float_exp2_s, i32, env, i32, i32) -+DEF_HELPER_3(float_exp2_d, i64, env, i64, i64) -+DEF_HELPER_2(float_logb_s, i32, env, i32) -+DEF_HELPER_2(float_logb_d, i64, env, i64) -+DEF_HELPER_3(movreg2cf, void, env, i32, tl) -+DEF_HELPER_2(movcf2reg, tl, env, i32) -+DEF_HELPER_3(movreg2cf_i32, void, env, i32, i32) -+DEF_HELPER_3(movreg2cf_i64, void, env, i32, i64) -+ -+DEF_HELPER_2(cto_w, tl, env, tl) -+DEF_HELPER_2(ctz_w, tl, env, tl) -+DEF_HELPER_2(cto_d, tl, env, tl) -+DEF_HELPER_2(ctz_d, tl, env, tl) -+DEF_HELPER_2(bitrev_w, tl, env, tl) -+DEF_HELPER_2(bitrev_d, tl, env, tl) -+ -+DEF_HELPER_2(load_scr, i64, env, i32) -+DEF_HELPER_3(store_scr, void, env, i32, i64) -+ -+DEF_HELPER_3(asrtle_d, void, env, tl, tl) -+DEF_HELPER_3(asrtgt_d, void, env, tl, tl) -+ -+DEF_HELPER_4(fsel, i64, env, i64, i64, i32) -+ -+#ifndef CONFIG_USER_ONLY -+DEF_HELPER_4(iocsr, void, env, tl, tl, i32) -+#endif -+DEF_HELPER_3(memtrace_addr, void, env, tl, i32) -+DEF_HELPER_2(memtrace_val, void, env, tl) -diff --git a/target/loongarch64/insn.decode b/target/loongarch64/insn.decode -new file mode 100644 -index 000000000..f194f7011 ---- /dev/null -+++ b/target/loongarch64/insn.decode -@@ -0,0 +1,514 @@ -+# Fields -+%sd 0:2 -+%rj 5:5 -+%rd 0:5 -+%sj 5:2 -+%ptr 5:3 -+%rk 10:5 -+%sa2 15:2 -+%sa3 15:3 -+%si5 10:s5 -+%code 0:15 -+%cond 10:4 -+%cond2 0:4 -+%ui5 10:5 -+%ui6 10:6 -+%ui3 10:3 -+%ui4 10:4 -+%op 5:5 -+%ui8 10:8 -+%msbw 16:5 -+%lsbw 10:5 -+%msbd 16:6 -+%lsbd 10:6 -+%fd 0:5 -+%fj 5:5 -+%fk 10:5 -+%fcsrd 0:5 -+%fcsrs 5:5 -+%cd 0:3 -+%cj 5:3 -+%si12 10:s12 -+%ui12 10:12 -+%csr 10:14 -+%cop 0:5 -+%level 10:8 -+%seq 10:8 -+%whint 0:15 -+%addr 10:5 -+%info 5:5 -+%invop 0:5 -+%fa 15:5 -+%vd 0:5 -+%vj 5:5 -+%vk 10:5 -+%va 15:5 -+%xd 0:5 -+%xj 5:5 -+%xk 10:5 -+%xa 15:5 -+%fcond 15:5 -+%ca 15:3 -+%vui5 15:5 -+%si16 10:s16 -+%si20 5:s20 -+%si14 10:s14 -+%hint 0:5 -+%si9 10:s9 -+%si10 10:s10 -+%si11 10:s11 -+%si8 10:s8 -+%idx1 18:1 -+%idx2 18:2 -+%idx3 18:3 -+%idx4 18:4 -+%idx 18:5 -+%offs21 0:s5 10:16 -+%offs16 10:s16 -+%offs 0:s10 10:16 -+%mode 5:5 -+%ui2 10:2 -+%ui1 10:1 -+%ui7 10:7 -+%i13 5:13 -+ -+# Argument sets -+&fmt_sdrj sd rj -+&fmt_rdsj rd sj -+&fmt_rdrj rd rj -+&fmt_empty -+&fmt_rjrk rj rk -+&fmt_rdrjrksa2 rd rj rk sa2 -+&fmt_rdrjrksa3 rd rj rk sa3 -+&fmt_rdrjrk rd rj rk -+&fmt_code code -+&fmt_rdrjui5 rd rj ui5 -+&fmt_rdrjui6 rd rj ui6 -+&fmt_rdrjmsbwlsbw rd rj msbw lsbw -+&fmt_rdrjmsbdlsbd rd rj msbd lsbd -+&fmt_fdfjfk fd fj fk -+&fmt_fdfj fd fj -+&fmt_fdrj fd rj -+&fmt_rdfj rd fj -+&fmt_fcsrdrj fcsrd rj -+&fmt_rdfcsrs rd fcsrs -+&fmt_cdfj cd fj -+&fmt_fdcj fd cj -+&fmt_cdrj cd rj -+&fmt_rdcj rd cj -+&fmt_rdrjsi12 rd rj si12 -+&fmt_rdrjui12 rd rj ui12 -+&fmt_rdrjcsr rd rj csr -+&fmt_coprjsi12 cop rj si12 -+&fmt_rdrjlevel rd rj level -+&fmt_rjseq rj seq -+&fmt_whint whint -+&fmt_invtlb addr info invop -+&fmt_fdfjfkfa fd fj fk fa -+&fmt_cdfjfkfcond cd fj fk fcond -+&fmt_fdfjfkca fd fj fk ca -+&fmt_rdrjsi16 rd rj si16 -+&fmt_rdsi20 rd si20 -+&fmt_rdrjsi14 rd rj si14 -+&fmt_hintrjsi12 hint rj si12 -+&fmt_fdrjsi12 fd rj si12 -+&fmt_fdrjrk fd rj rk -+&fmt_rjoffs21 rj offs21 -+&fmt_cjoffs21 cj offs21 -+&fmt_rdrjoffs16 rd rj offs16 -+&fmt_offs offs -+&fmt_rjrdoffs16 rj rd offs16 -+ -+# Formats -+@fmt_sdrj .... ........ ..... ..... ..... ... .. &fmt_sdrj %sd %rj -+@fmt_rdsj .... ........ ..... ..... ... .. ..... &fmt_rdsj %rd %sj -+@fmt_rdrj .... ........ ..... ..... ..... ..... &fmt_rdrj %rd %rj -+@fmt_empty .... ........ ..... ..... ..... ..... &fmt_empty -+@fmt_rjrk .... ........ ..... ..... ..... ..... &fmt_rjrk %rj %rk -+@fmt_rdrjrksa2 .... ........ ... .. ..... ..... ..... &fmt_rdrjrksa2 %rd %rj %rk %sa2 -+@fmt_rdrjrksa3 .... ........ .. ... ..... ..... ..... &fmt_rdrjrksa3 %rd %rj %rk %sa3 -+@fmt_rdrjrk .... ........ ..... ..... ..... ..... &fmt_rdrjrk %rd %rj %rk -+@fmt_code .... ........ ..... ............... &fmt_code %code -+@fmt_rdrjui5 .... ........ ..... ..... ..... ..... &fmt_rdrjui5 %rd %rj %ui5 -+@fmt_rdrjui6 .... ........ .... ...... ..... ..... &fmt_rdrjui6 %rd %rj %ui6 -+@fmt_rdrjmsbwlsbw .... ....... ..... . ..... ..... ..... &fmt_rdrjmsbwlsbw %rd %rj %msbw %lsbw -+@fmt_rdrjmsbdlsbd .... ...... ...... ...... ..... ..... &fmt_rdrjmsbdlsbd %rd %rj %msbd %lsbd -+@fmt_fdfjfk .... ........ ..... ..... ..... ..... &fmt_fdfjfk %fd %fj %fk -+@fmt_fdfj .... ........ ..... ..... ..... ..... &fmt_fdfj %fd %fj -+@fmt_fdrj .... ........ ..... ..... ..... ..... &fmt_fdrj %fd %rj -+@fmt_rdfj .... ........ ..... ..... ..... ..... &fmt_rdfj %rd %fj -+@fmt_fcsrdrj .... ........ ..... ..... ..... ..... &fmt_fcsrdrj %fcsrd %rj -+@fmt_rdfcsrs .... ........ ..... ..... ..... ..... &fmt_rdfcsrs %rd %fcsrs -+@fmt_cdfj .... ........ ..... ..... ..... .. ... &fmt_cdfj %cd %fj -+@fmt_fdcj .... ........ ..... ..... .. ... ..... &fmt_fdcj %fd %cj -+@fmt_cdrj .... ........ ..... ..... ..... .. ... &fmt_cdrj %cd %rj -+@fmt_rdcj .... ........ ..... ..... .. ... ..... &fmt_rdcj %rd %cj -+@fmt_rdrjsi12 .... ...... ............ ..... ..... &fmt_rdrjsi12 %rd %rj %si12 -+@fmt_rdrjui12 .... ...... ............ ..... ..... &fmt_rdrjui12 %rd %rj %ui12 -+@fmt_rdrjcsr .... .... .............. ..... ..... &fmt_rdrjcsr %rd %rj %csr -+@fmt_coprjsi12 .... ...... ............ ..... ..... &fmt_coprjsi12 %cop %rj %si12 -+@fmt_rdrjlevel .... ........ .. ........ ..... ..... &fmt_rdrjlevel %rd %rj %level -+@fmt_rjseq .... ........ .. ........ ..... ..... &fmt_rjseq %rj %seq -+@fmt_whint .... ........ ..... ............... &fmt_whint %whint -+@fmt_invtlb ...... ...... ..... ..... ..... ..... &fmt_invtlb %addr %info %invop -+@fmt_fdfjfkfa .... ........ ..... ..... ..... ..... &fmt_fdfjfkfa %fd %fj %fk %fa -+@fmt_cdfjfkfcond .... ........ ..... ..... ..... .. ... &fmt_cdfjfkfcond %cd %fj %fk %fcond -+@fmt_fdfjfkca .... ........ .. ... ..... ..... ..... &fmt_fdfjfkca %fd %fj %fk %ca -+@fmt_rdrjsi16 .... .. ................ ..... ..... &fmt_rdrjsi16 %rd %rj %si16 -+@fmt_rdsi20 .... ... .................... ..... &fmt_rdsi20 %rd %si20 -+@fmt_rdrjsi14 .... .... .............. ..... ..... &fmt_rdrjsi14 %rd %rj %si14 -+@fmt_hintrjsi12 .... ...... ............ ..... ..... &fmt_hintrjsi12 %hint %rj %si12 -+@fmt_fdrjsi12 .... ...... ............ ..... ..... &fmt_fdrjsi12 %fd %rj %si12 -+@fmt_fdrjrk .... ........ ..... ..... ..... ..... &fmt_fdrjrk %fd %rj %rk -+@fmt_rjoffs21 .... .. ................ ..... ..... &fmt_rjoffs21 %rj %offs21 -+@fmt_cjoffs21 .... .. ................ .. ... ..... &fmt_cjoffs21 %cj %offs21 -+@fmt_rdrjoffs16 .... .. ................ ..... ..... &fmt_rdrjoffs16 %rd %rj %offs16 -+@fmt_offs .... .. .......................... &fmt_offs %offs -+@fmt_rjrdoffs16 .... .. ................ ..... ..... &fmt_rjrdoffs16 %rj %rd %offs16 -+ -+# Instructions -+ -+# Fiexd point arithmetic Instructions -+gr2scr 0000 00000000 00000 00010 ..... 000 .. @fmt_sdrj -+scr2gr 0000 00000000 00000 00011 000 .. ..... @fmt_rdsj -+clo_w 0000 00000000 00000 00100 ..... ..... @fmt_rdrj -+clz_w 0000 00000000 00000 00101 ..... ..... @fmt_rdrj -+cto_w 0000 00000000 00000 00110 ..... ..... @fmt_rdrj -+ctz_w 0000 00000000 00000 00111 ..... ..... @fmt_rdrj -+clo_d 0000 00000000 00000 01000 ..... ..... @fmt_rdrj -+clz_d 0000 00000000 00000 01001 ..... ..... @fmt_rdrj -+cto_d 0000 00000000 00000 01010 ..... ..... @fmt_rdrj -+ctz_d 0000 00000000 00000 01011 ..... ..... @fmt_rdrj -+revb_2h 0000 00000000 00000 01100 ..... ..... @fmt_rdrj -+revb_4h 0000 00000000 00000 01101 ..... ..... @fmt_rdrj -+revb_2w 0000 00000000 00000 01110 ..... ..... @fmt_rdrj -+revb_d 0000 00000000 00000 01111 ..... ..... @fmt_rdrj -+revh_2w 0000 00000000 00000 10000 ..... ..... @fmt_rdrj -+revh_d 0000 00000000 00000 10001 ..... ..... @fmt_rdrj -+bitrev_4b 0000 00000000 00000 10010 ..... ..... @fmt_rdrj -+bitrev_8b 0000 00000000 00000 10011 ..... ..... @fmt_rdrj -+bitrev_w 0000 00000000 00000 10100 ..... ..... @fmt_rdrj -+bitrev_d 0000 00000000 00000 10101 ..... ..... @fmt_rdrj -+ext_w_h 0000 00000000 00000 10110 ..... ..... @fmt_rdrj -+ext_w_b 0000 00000000 00000 10111 ..... ..... @fmt_rdrj -+rdtime_d 0000 00000000 00000 11010 ..... ..... @fmt_rdrj -+cpucfg 0000 00000000 00000 11011 ..... ..... @fmt_rdrj -+asrtle_d 0000 00000000 00010 ..... ..... 00000 @fmt_rjrk -+asrtgt_d 0000 00000000 00011 ..... ..... 00000 @fmt_rjrk -+alsl_w 0000 00000000 010 .. ..... ..... ..... @fmt_rdrjrksa2 -+alsl_wu 0000 00000000 011 .. ..... ..... ..... @fmt_rdrjrksa2 -+bytepick_w 0000 00000000 100 .. ..... ..... ..... @fmt_rdrjrksa2 -+bytepick_d 0000 00000000 11 ... ..... ..... ..... @fmt_rdrjrksa3 -+add_w 0000 00000001 00000 ..... ..... ..... @fmt_rdrjrk -+add_d 0000 00000001 00001 ..... ..... ..... @fmt_rdrjrk -+sub_w 0000 00000001 00010 ..... ..... ..... @fmt_rdrjrk -+sub_d 0000 00000001 00011 ..... ..... ..... @fmt_rdrjrk -+slt 0000 00000001 00100 ..... ..... ..... @fmt_rdrjrk -+sltu 0000 00000001 00101 ..... ..... ..... @fmt_rdrjrk -+maskeqz 0000 00000001 00110 ..... ..... ..... @fmt_rdrjrk -+masknez 0000 00000001 00111 ..... ..... ..... @fmt_rdrjrk -+nor 0000 00000001 01000 ..... ..... ..... @fmt_rdrjrk -+and 0000 00000001 01001 ..... ..... ..... @fmt_rdrjrk -+or 0000 00000001 01010 ..... ..... ..... @fmt_rdrjrk -+xor 0000 00000001 01011 ..... ..... ..... @fmt_rdrjrk -+orn 0000 00000001 01100 ..... ..... ..... @fmt_rdrjrk -+andn 0000 00000001 01101 ..... ..... ..... @fmt_rdrjrk -+sll_w 0000 00000001 01110 ..... ..... ..... @fmt_rdrjrk -+srl_w 0000 00000001 01111 ..... ..... ..... @fmt_rdrjrk -+sra_w 0000 00000001 10000 ..... ..... ..... @fmt_rdrjrk -+sll_d 0000 00000001 10001 ..... ..... ..... @fmt_rdrjrk -+srl_d 0000 00000001 10010 ..... ..... ..... @fmt_rdrjrk -+sra_d 0000 00000001 10011 ..... ..... ..... @fmt_rdrjrk -+rotr_w 0000 00000001 10110 ..... ..... ..... @fmt_rdrjrk -+rotr_d 0000 00000001 10111 ..... ..... ..... @fmt_rdrjrk -+mul_w 0000 00000001 11000 ..... ..... ..... @fmt_rdrjrk -+mulh_w 0000 00000001 11001 ..... ..... ..... @fmt_rdrjrk -+mulh_wu 0000 00000001 11010 ..... ..... ..... @fmt_rdrjrk -+mul_d 0000 00000001 11011 ..... ..... ..... @fmt_rdrjrk -+mulh_d 0000 00000001 11100 ..... ..... ..... @fmt_rdrjrk -+mulh_du 0000 00000001 11101 ..... ..... ..... @fmt_rdrjrk -+mulw_d_w 0000 00000001 11110 ..... ..... ..... @fmt_rdrjrk -+mulw_d_wu 0000 00000001 11111 ..... ..... ..... @fmt_rdrjrk -+div_w 0000 00000010 00000 ..... ..... ..... @fmt_rdrjrk -+mod_w 0000 00000010 00001 ..... ..... ..... @fmt_rdrjrk -+div_wu 0000 00000010 00010 ..... ..... ..... @fmt_rdrjrk -+mod_wu 0000 00000010 00011 ..... ..... ..... @fmt_rdrjrk -+div_d 0000 00000010 00100 ..... ..... ..... @fmt_rdrjrk -+mod_d 0000 00000010 00101 ..... ..... ..... @fmt_rdrjrk -+div_du 0000 00000010 00110 ..... ..... ..... @fmt_rdrjrk -+mod_du 0000 00000010 00111 ..... ..... ..... @fmt_rdrjrk -+crc_w_b_w 0000 00000010 01000 ..... ..... ..... @fmt_rdrjrk -+crc_w_h_w 0000 00000010 01001 ..... ..... ..... @fmt_rdrjrk -+crc_w_w_w 0000 00000010 01010 ..... ..... ..... @fmt_rdrjrk -+crc_w_d_w 0000 00000010 01011 ..... ..... ..... @fmt_rdrjrk -+crcc_w_b_w 0000 00000010 01100 ..... ..... ..... @fmt_rdrjrk -+crcc_w_h_w 0000 00000010 01101 ..... ..... ..... @fmt_rdrjrk -+crcc_w_w_w 0000 00000010 01110 ..... ..... ..... @fmt_rdrjrk -+crcc_w_d_w 0000 00000010 01111 ..... ..... ..... @fmt_rdrjrk -+break 0000 00000010 10100 ............... @fmt_code -+dbcl 0000 00000010 10101 ............... @fmt_code -+syscall 0000 00000010 10110 ............... @fmt_code -+alsl_d 0000 00000010 110 .. ..... ..... ..... @fmt_rdrjrksa2 -+slli_w 0000 00000100 00001 ..... ..... ..... @fmt_rdrjui5 -+slli_d 0000 00000100 0001 ...... ..... ..... @fmt_rdrjui6 -+srli_w 0000 00000100 01001 ..... ..... ..... @fmt_rdrjui5 -+srli_d 0000 00000100 0101 ...... ..... ..... @fmt_rdrjui6 -+srai_w 0000 00000100 10001 ..... ..... ..... @fmt_rdrjui5 -+srai_d 0000 00000100 1001 ...... ..... ..... @fmt_rdrjui6 -+rotri_w 0000 00000100 11001 ..... ..... ..... @fmt_rdrjui5 -+rotri_d 0000 00000100 1101 ...... ..... ..... @fmt_rdrjui6 -+bstrins_w 0000 0000011 ..... 0 ..... ..... ..... @fmt_rdrjmsbwlsbw -+bstrpick_w 0000 0000011 ..... 1 ..... ..... ..... @fmt_rdrjmsbwlsbw -+bstrins_d 0000 000010 ...... ...... ..... ..... @fmt_rdrjmsbdlsbd -+bstrpick_d 0000 000011 ...... ...... ..... ..... @fmt_rdrjmsbdlsbd -+ -+# float Instructions -+fadd_s 0000 00010000 00001 ..... ..... ..... @fmt_fdfjfk -+fadd_d 0000 00010000 00010 ..... ..... ..... @fmt_fdfjfk -+fsub_s 0000 00010000 00101 ..... ..... ..... @fmt_fdfjfk -+fsub_d 0000 00010000 00110 ..... ..... ..... @fmt_fdfjfk -+fmul_s 0000 00010000 01001 ..... ..... ..... @fmt_fdfjfk -+fmul_d 0000 00010000 01010 ..... ..... ..... @fmt_fdfjfk -+fdiv_s 0000 00010000 01101 ..... ..... ..... @fmt_fdfjfk -+fdiv_d 0000 00010000 01110 ..... ..... ..... @fmt_fdfjfk -+fmax_s 0000 00010000 10001 ..... ..... ..... @fmt_fdfjfk -+fmax_d 0000 00010000 10010 ..... ..... ..... @fmt_fdfjfk -+fmin_s 0000 00010000 10101 ..... ..... ..... @fmt_fdfjfk -+fmin_d 0000 00010000 10110 ..... ..... ..... @fmt_fdfjfk -+fmaxa_s 0000 00010000 11001 ..... ..... ..... @fmt_fdfjfk -+fmaxa_d 0000 00010000 11010 ..... ..... ..... @fmt_fdfjfk -+fmina_s 0000 00010000 11101 ..... ..... ..... @fmt_fdfjfk -+fmina_d 0000 00010000 11110 ..... ..... ..... @fmt_fdfjfk -+fscaleb_s 0000 00010001 00001 ..... ..... ..... @fmt_fdfjfk -+fscaleb_d 0000 00010001 00010 ..... ..... ..... @fmt_fdfjfk -+fcopysign_s 0000 00010001 00101 ..... ..... ..... @fmt_fdfjfk -+fcopysign_d 0000 00010001 00110 ..... ..... ..... @fmt_fdfjfk -+fabs_s 0000 00010001 01000 00001 ..... ..... @fmt_fdfj -+fabs_d 0000 00010001 01000 00010 ..... ..... @fmt_fdfj -+fneg_s 0000 00010001 01000 00101 ..... ..... @fmt_fdfj -+fneg_d 0000 00010001 01000 00110 ..... ..... @fmt_fdfj -+flogb_s 0000 00010001 01000 01001 ..... ..... @fmt_fdfj -+flogb_d 0000 00010001 01000 01010 ..... ..... @fmt_fdfj -+fclass_s 0000 00010001 01000 01101 ..... ..... @fmt_fdfj -+fclass_d 0000 00010001 01000 01110 ..... ..... @fmt_fdfj -+fsqrt_s 0000 00010001 01000 10001 ..... ..... @fmt_fdfj -+fsqrt_d 0000 00010001 01000 10010 ..... ..... @fmt_fdfj -+frecip_s 0000 00010001 01000 10101 ..... ..... @fmt_fdfj -+frecip_d 0000 00010001 01000 10110 ..... ..... @fmt_fdfj -+frsqrt_s 0000 00010001 01000 11001 ..... ..... @fmt_fdfj -+frsqrt_d 0000 00010001 01000 11010 ..... ..... @fmt_fdfj -+fmov_s 0000 00010001 01001 00101 ..... ..... @fmt_fdfj -+fmov_d 0000 00010001 01001 00110 ..... ..... @fmt_fdfj -+movgr2fr_w 0000 00010001 01001 01001 ..... ..... @fmt_fdrj -+movgr2fr_d 0000 00010001 01001 01010 ..... ..... @fmt_fdrj -+movgr2frh_w 0000 00010001 01001 01011 ..... ..... @fmt_fdrj -+movfr2gr_s 0000 00010001 01001 01101 ..... ..... @fmt_rdfj -+movfr2gr_d 0000 00010001 01001 01110 ..... ..... @fmt_rdfj -+movfrh2gr_s 0000 00010001 01001 01111 ..... ..... @fmt_rdfj -+movgr2fcsr 0000 00010001 01001 10000 ..... ..... @fmt_fcsrdrj -+movfcsr2gr 0000 00010001 01001 10010 ..... ..... @fmt_rdfcsrs -+movfr2cf 0000 00010001 01001 10100 ..... 00 ... @fmt_cdfj -+movcf2fr 0000 00010001 01001 10101 00 ... ..... @fmt_fdcj -+movgr2cf 0000 00010001 01001 10110 ..... 00 ... @fmt_cdrj -+movcf2gr 0000 00010001 01001 10111 00 ... ..... @fmt_rdcj -+fcvt_s_d 0000 00010001 10010 00110 ..... ..... @fmt_fdfj -+fcvt_d_s 0000 00010001 10010 01001 ..... ..... @fmt_fdfj -+ftintrm_w_s 0000 00010001 10100 00001 ..... ..... @fmt_fdfj -+ftintrm_w_d 0000 00010001 10100 00010 ..... ..... @fmt_fdfj -+ftintrm_l_s 0000 00010001 10100 01001 ..... ..... @fmt_fdfj -+ftintrm_l_d 0000 00010001 10100 01010 ..... ..... @fmt_fdfj -+ftintrp_w_s 0000 00010001 10100 10001 ..... ..... @fmt_fdfj -+ftintrp_w_d 0000 00010001 10100 10010 ..... ..... @fmt_fdfj -+ftintrp_l_s 0000 00010001 10100 11001 ..... ..... @fmt_fdfj -+ftintrp_l_d 0000 00010001 10100 11010 ..... ..... @fmt_fdfj -+ftintrz_w_s 0000 00010001 10101 00001 ..... ..... @fmt_fdfj -+ftintrz_w_d 0000 00010001 10101 00010 ..... ..... @fmt_fdfj -+ftintrz_l_s 0000 00010001 10101 01001 ..... ..... @fmt_fdfj -+ftintrz_l_d 0000 00010001 10101 01010 ..... ..... @fmt_fdfj -+ftintrne_w_s 0000 00010001 10101 10001 ..... ..... @fmt_fdfj -+ftintrne_w_d 0000 00010001 10101 10010 ..... ..... @fmt_fdfj -+ftintrne_l_s 0000 00010001 10101 11001 ..... ..... @fmt_fdfj -+ftintrne_l_d 0000 00010001 10101 11010 ..... ..... @fmt_fdfj -+ftint_w_s 0000 00010001 10110 00001 ..... ..... @fmt_fdfj -+ftint_w_d 0000 00010001 10110 00010 ..... ..... @fmt_fdfj -+ftint_l_s 0000 00010001 10110 01001 ..... ..... @fmt_fdfj -+ftint_l_d 0000 00010001 10110 01010 ..... ..... @fmt_fdfj -+ffint_s_w 0000 00010001 11010 00100 ..... ..... @fmt_fdfj -+ffint_s_l 0000 00010001 11010 00110 ..... ..... @fmt_fdfj -+ffint_d_w 0000 00010001 11010 01000 ..... ..... @fmt_fdfj -+ffint_d_l 0000 00010001 11010 01010 ..... ..... @fmt_fdfj -+frint_s 0000 00010001 11100 10001 ..... ..... @fmt_fdfj -+frint_d 0000 00010001 11100 10010 ..... ..... @fmt_fdfj -+ -+# 12 bit immediate Instructions -+slti 0000 001000 ............ ..... ..... @fmt_rdrjsi12 -+sltui 0000 001001 ............ ..... ..... @fmt_rdrjsi12 -+addi_w 0000 001010 ............ ..... ..... @fmt_rdrjsi12 -+addi_d 0000 001011 ............ ..... ..... @fmt_rdrjsi12 -+lu52i_d 0000 001100 ............ ..... ..... @fmt_rdrjsi12 -+andi 0000 001101 ............ ..... ..... @fmt_rdrjui12 -+ori 0000 001110 ............ ..... ..... @fmt_rdrjui12 -+xori 0000 001111 ............ ..... ..... @fmt_rdrjui12 -+ -+# core Instructions -+csrxchg 0000 0100 .............. ..... ..... @fmt_rdrjcsr -+cacop 0000 011000 ............ ..... ..... @fmt_coprjsi12 -+lddir 0000 01100100 00 ........ ..... ..... @fmt_rdrjlevel -+ldpte 0000 01100100 01 ........ ..... 00000 @fmt_rjseq -+iocsrrd_b 0000 01100100 10000 00000 ..... ..... @fmt_rdrj -+iocsrrd_h 0000 01100100 10000 00001 ..... ..... @fmt_rdrj -+iocsrrd_w 0000 01100100 10000 00010 ..... ..... @fmt_rdrj -+iocsrrd_d 0000 01100100 10000 00011 ..... ..... @fmt_rdrj -+iocsrwr_b 0000 01100100 10000 00100 ..... ..... @fmt_rdrj -+iocsrwr_h 0000 01100100 10000 00101 ..... ..... @fmt_rdrj -+iocsrwr_w 0000 01100100 10000 00110 ..... ..... @fmt_rdrj -+iocsrwr_d 0000 01100100 10000 00111 ..... ..... @fmt_rdrj -+tlbclr 0000 01100100 10000 01000 00000 00000 @fmt_empty -+tlbflush 0000 01100100 10000 01001 00000 00000 @fmt_empty -+tlbsrch 0000 01100100 10000 01010 00000 00000 @fmt_empty -+tlbrd 0000 01100100 10000 01011 00000 00000 @fmt_empty -+tlbwr 0000 01100100 10000 01100 00000 00000 @fmt_empty -+tlbfill 0000 01100100 10000 01101 00000 00000 @fmt_empty -+ertn 0000 01100100 10000 01110 00000 00000 @fmt_empty -+idle 0000 01100100 10001 ............... @fmt_whint -+invtlb 0000 01100100 10011 ..... ..... ..... @fmt_invtlb -+ -+# foure Op Instructions -+fmadd_s 0000 10000001 ..... ..... ..... ..... @fmt_fdfjfkfa -+fmadd_d 0000 10000010 ..... ..... ..... ..... @fmt_fdfjfkfa -+fmsub_s 0000 10000101 ..... ..... ..... ..... @fmt_fdfjfkfa -+fmsub_d 0000 10000110 ..... ..... ..... ..... @fmt_fdfjfkfa -+fnmadd_s 0000 10001001 ..... ..... ..... ..... @fmt_fdfjfkfa -+fnmadd_d 0000 10001010 ..... ..... ..... ..... @fmt_fdfjfkfa -+fnmsub_s 0000 10001101 ..... ..... ..... ..... @fmt_fdfjfkfa -+fnmsub_d 0000 10001110 ..... ..... ..... ..... @fmt_fdfjfkfa -+fcmp_cond_s 0000 11000001 ..... ..... ..... 00 ... @fmt_cdfjfkfcond -+fcmp_cond_d 0000 11000010 ..... ..... ..... 00 ... @fmt_cdfjfkfcond -+fsel 0000 11010000 00 ... ..... ..... ..... @fmt_fdfjfkca -+ -+# loog immediate Instructions -+addu16i_d 0001 00 ................ ..... ..... @fmt_rdrjsi16 -+lu12i_w 0001 010 .................... ..... @fmt_rdsi20 -+lu32i_d 0001 011 .................... ..... @fmt_rdsi20 -+pcaddi 0001 100 .................... ..... @fmt_rdsi20 -+pcalau12i 0001 101 .................... ..... @fmt_rdsi20 -+pcaddu12i 0001 110 .................... ..... @fmt_rdsi20 -+pcaddu18i 0001 111 .................... ..... @fmt_rdsi20 -+ -+# load/store Instructions -+ll_w 0010 0000 .............. ..... ..... @fmt_rdrjsi14 -+sc_w 0010 0001 .............. ..... ..... @fmt_rdrjsi14 -+ll_d 0010 0010 .............. ..... ..... @fmt_rdrjsi14 -+sc_d 0010 0011 .............. ..... ..... @fmt_rdrjsi14 -+ldptr_w 0010 0100 .............. ..... ..... @fmt_rdrjsi14 -+stptr_w 0010 0101 .............. ..... ..... @fmt_rdrjsi14 -+ldptr_d 0010 0110 .............. ..... ..... @fmt_rdrjsi14 -+stptr_d 0010 0111 .............. ..... ..... @fmt_rdrjsi14 -+ld_b 0010 100000 ............ ..... ..... @fmt_rdrjsi12 -+ld_h 0010 100001 ............ ..... ..... @fmt_rdrjsi12 -+ld_w 0010 100010 ............ ..... ..... @fmt_rdrjsi12 -+ld_d 0010 100011 ............ ..... ..... @fmt_rdrjsi12 -+st_b 0010 100100 ............ ..... ..... @fmt_rdrjsi12 -+st_h 0010 100101 ............ ..... ..... @fmt_rdrjsi12 -+st_w 0010 100110 ............ ..... ..... @fmt_rdrjsi12 -+st_d 0010 100111 ............ ..... ..... @fmt_rdrjsi12 -+ld_bu 0010 101000 ............ ..... ..... @fmt_rdrjsi12 -+ld_hu 0010 101001 ............ ..... ..... @fmt_rdrjsi12 -+ld_wu 0010 101010 ............ ..... ..... @fmt_rdrjsi12 -+preld 0010 101011 ............ ..... ..... @fmt_hintrjsi12 -+fld_s 0010 101100 ............ ..... ..... @fmt_fdrjsi12 -+fst_s 0010 101101 ............ ..... ..... @fmt_fdrjsi12 -+fld_d 0010 101110 ............ ..... ..... @fmt_fdrjsi12 -+fst_d 0010 101111 ............ ..... ..... @fmt_fdrjsi12 -+ldx_b 0011 10000000 00000 ..... ..... ..... @fmt_rdrjrk -+ldx_h 0011 10000000 01000 ..... ..... ..... @fmt_rdrjrk -+ldx_w 0011 10000000 10000 ..... ..... ..... @fmt_rdrjrk -+ldx_d 0011 10000000 11000 ..... ..... ..... @fmt_rdrjrk -+stx_b 0011 10000001 00000 ..... ..... ..... @fmt_rdrjrk -+stx_h 0011 10000001 01000 ..... ..... ..... @fmt_rdrjrk -+stx_w 0011 10000001 10000 ..... ..... ..... @fmt_rdrjrk -+stx_d 0011 10000001 11000 ..... ..... ..... @fmt_rdrjrk -+ldx_bu 0011 10000010 00000 ..... ..... ..... @fmt_rdrjrk -+ldx_hu 0011 10000010 01000 ..... ..... ..... @fmt_rdrjrk -+ldx_wu 0011 10000010 10000 ..... ..... ..... @fmt_rdrjrk -+fldx_s 0011 10000011 00000 ..... ..... ..... @fmt_fdrjrk -+fldx_d 0011 10000011 01000 ..... ..... ..... @fmt_fdrjrk -+fstx_s 0011 10000011 10000 ..... ..... ..... @fmt_fdrjrk -+fstx_d 0011 10000011 11000 ..... ..... ..... @fmt_fdrjrk -+amswap_w 0011 10000110 00000 ..... ..... ..... @fmt_rdrjrk -+amswap_d 0011 10000110 00001 ..... ..... ..... @fmt_rdrjrk -+amadd_w 0011 10000110 00010 ..... ..... ..... @fmt_rdrjrk -+amadd_d 0011 10000110 00011 ..... ..... ..... @fmt_rdrjrk -+amand_w 0011 10000110 00100 ..... ..... ..... @fmt_rdrjrk -+amand_d 0011 10000110 00101 ..... ..... ..... @fmt_rdrjrk -+amor_w 0011 10000110 00110 ..... ..... ..... @fmt_rdrjrk -+amor_d 0011 10000110 00111 ..... ..... ..... @fmt_rdrjrk -+amxor_w 0011 10000110 01000 ..... ..... ..... @fmt_rdrjrk -+amxor_d 0011 10000110 01001 ..... ..... ..... @fmt_rdrjrk -+ammax_w 0011 10000110 01010 ..... ..... ..... @fmt_rdrjrk -+ammax_d 0011 10000110 01011 ..... ..... ..... @fmt_rdrjrk -+ammin_w 0011 10000110 01100 ..... ..... ..... @fmt_rdrjrk -+ammin_d 0011 10000110 01101 ..... ..... ..... @fmt_rdrjrk -+ammax_wu 0011 10000110 01110 ..... ..... ..... @fmt_rdrjrk -+ammax_du 0011 10000110 01111 ..... ..... ..... @fmt_rdrjrk -+ammin_wu 0011 10000110 10000 ..... ..... ..... @fmt_rdrjrk -+ammin_du 0011 10000110 10001 ..... ..... ..... @fmt_rdrjrk -+amswap_db_w 0011 10000110 10010 ..... ..... ..... @fmt_rdrjrk -+amswap_db_d 0011 10000110 10011 ..... ..... ..... @fmt_rdrjrk -+amadd_db_w 0011 10000110 10100 ..... ..... ..... @fmt_rdrjrk -+amadd_db_d 0011 10000110 10101 ..... ..... ..... @fmt_rdrjrk -+amand_db_w 0011 10000110 10110 ..... ..... ..... @fmt_rdrjrk -+amand_db_d 0011 10000110 10111 ..... ..... ..... @fmt_rdrjrk -+amor_db_w 0011 10000110 11000 ..... ..... ..... @fmt_rdrjrk -+amor_db_d 0011 10000110 11001 ..... ..... ..... @fmt_rdrjrk -+amxor_db_w 0011 10000110 11010 ..... ..... ..... @fmt_rdrjrk -+amxor_db_d 0011 10000110 11011 ..... ..... ..... @fmt_rdrjrk -+ammax_db_w 0011 10000110 11100 ..... ..... ..... @fmt_rdrjrk -+ammax_db_d 0011 10000110 11101 ..... ..... ..... @fmt_rdrjrk -+ammin_db_w 0011 10000110 11110 ..... ..... ..... @fmt_rdrjrk -+ammin_db_d 0011 10000110 11111 ..... ..... ..... @fmt_rdrjrk -+ammax_db_wu 0011 10000111 00000 ..... ..... ..... @fmt_rdrjrk -+ammax_db_du 0011 10000111 00001 ..... ..... ..... @fmt_rdrjrk -+ammin_db_wu 0011 10000111 00010 ..... ..... ..... @fmt_rdrjrk -+ammin_db_du 0011 10000111 00011 ..... ..... ..... @fmt_rdrjrk -+dbar 0011 10000111 00100 ............... @fmt_whint -+ibar 0011 10000111 00101 ............... @fmt_whint -+fldgt_s 0011 10000111 01000 ..... ..... ..... @fmt_fdrjrk -+fldgt_d 0011 10000111 01001 ..... ..... ..... @fmt_fdrjrk -+fldle_s 0011 10000111 01010 ..... ..... ..... @fmt_fdrjrk -+fldle_d 0011 10000111 01011 ..... ..... ..... @fmt_fdrjrk -+fstgt_s 0011 10000111 01100 ..... ..... ..... @fmt_fdrjrk -+fstgt_d 0011 10000111 01101 ..... ..... ..... @fmt_fdrjrk -+fstle_s 0011 10000111 01110 ..... ..... ..... @fmt_fdrjrk -+fstle_d 0011 10000111 01111 ..... ..... ..... @fmt_fdrjrk -+ldgt_b 0011 10000111 10000 ..... ..... ..... @fmt_rdrjrk -+ldgt_h 0011 10000111 10001 ..... ..... ..... @fmt_rdrjrk -+ldgt_w 0011 10000111 10010 ..... ..... ..... @fmt_rdrjrk -+ldgt_d 0011 10000111 10011 ..... ..... ..... @fmt_rdrjrk -+ldle_b 0011 10000111 10100 ..... ..... ..... @fmt_rdrjrk -+ldle_h 0011 10000111 10101 ..... ..... ..... @fmt_rdrjrk -+ldle_w 0011 10000111 10110 ..... ..... ..... @fmt_rdrjrk -+ldle_d 0011 10000111 10111 ..... ..... ..... @fmt_rdrjrk -+stgt_b 0011 10000111 11000 ..... ..... ..... @fmt_rdrjrk -+stgt_h 0011 10000111 11001 ..... ..... ..... @fmt_rdrjrk -+stgt_w 0011 10000111 11010 ..... ..... ..... @fmt_rdrjrk -+stgt_d 0011 10000111 11011 ..... ..... ..... @fmt_rdrjrk -+stle_b 0011 10000111 11100 ..... ..... ..... @fmt_rdrjrk -+stle_h 0011 10000111 11101 ..... ..... ..... @fmt_rdrjrk -+stle_w 0011 10000111 11110 ..... ..... ..... @fmt_rdrjrk -+stle_d 0011 10000111 11111 ..... ..... ..... @fmt_rdrjrk -+ -+# jump Instructions -+beqz 0100 00 ................ ..... ..... @fmt_rjoffs21 -+bnez 0100 01 ................ ..... ..... @fmt_rjoffs21 -+bceqz 0100 10 ................ 00 ... ..... @fmt_cjoffs21 -+bcnez 0100 10 ................ 01 ... ..... @fmt_cjoffs21 -+jirl 0100 11 ................ ..... ..... @fmt_rdrjoffs16 -+b 0101 00 .......................... @fmt_offs -+bl 0101 01 .......................... @fmt_offs -+beq 0101 10 ................ ..... ..... @fmt_rjrdoffs16 -+bne 0101 11 ................ ..... ..... @fmt_rjrdoffs16 -+blt 0110 00 ................ ..... ..... @fmt_rjrdoffs16 -+bge 0110 01 ................ ..... ..... @fmt_rjrdoffs16 -+bltu 0110 10 ................ ..... ..... @fmt_rjrdoffs16 -+bgeu 0110 11 ................ ..... ..... @fmt_rjrdoffs16 -diff --git a/target/loongarch64/instmap.h b/target/loongarch64/instmap.h -new file mode 100644 -index 000000000..6e85847f8 ---- /dev/null -+++ b/target/loongarch64/instmap.h -@@ -0,0 +1,216 @@ -+/* -+ * Loongarch emulation for qemu: instruction opcode -+ * -+ * Copyright (c) 2020-2021 -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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 . -+ */ -+ -+#ifndef TARGET_LARCH_INSTMAP_H -+#define TARGET_LARCH_INSTMAP_H -+ -+enum { -+ /* fix opcodes */ -+ OPC_LARCH_CLO_W = (0x000004 << 10), -+ OPC_LARCH_CLZ_W = (0x000005 << 10), -+ OPC_LARCH_CLO_D = (0x000008 << 10), -+ OPC_LARCH_CLZ_D = (0x000009 << 10), -+ OPC_LARCH_REVB_2H = (0x00000C << 10), -+ OPC_LARCH_REVB_4H = (0x00000D << 10), -+ OPC_LARCH_REVH_D = (0x000011 << 10), -+ OPC_LARCH_BREV_4B = (0x000012 << 10), -+ OPC_LARCH_BREV_8B = (0x000013 << 10), -+ OPC_LARCH_EXT_WH = (0x000016 << 10), -+ OPC_LARCH_EXT_WB = (0x000017 << 10), -+ -+ OPC_LARCH_ADD_W = (0x00020 << 15), -+ OPC_LARCH_ADD_D = (0x00021 << 15), -+ OPC_LARCH_SUB_W = (0x00022 << 15), -+ OPC_LARCH_SUB_D = (0x00023 << 15), -+ OPC_LARCH_SLT = (0x00024 << 15), -+ OPC_LARCH_SLTU = (0x00025 << 15), -+ OPC_LARCH_MASKEQZ = (0x00026 << 15), -+ OPC_LARCH_MASKNEZ = (0x00027 << 15), -+ OPC_LARCH_NOR = (0x00028 << 15), -+ OPC_LARCH_AND = (0x00029 << 15), -+ OPC_LARCH_OR = (0x0002A << 15), -+ OPC_LARCH_XOR = (0x0002B << 15), -+ OPC_LARCH_SLL_W = (0x0002E << 15), -+ OPC_LARCH_SRL_W = (0x0002F << 15), -+ OPC_LARCH_SRA_W = (0x00030 << 15), -+ OPC_LARCH_SLL_D = (0x00031 << 15), -+ OPC_LARCH_SRL_D = (0x00032 << 15), -+ OPC_LARCH_SRA_D = (0x00033 << 15), -+ OPC_LARCH_ROTR_W = (0x00036 << 15), -+ OPC_LARCH_ROTR_D = (0x00037 << 15), -+ OPC_LARCH_MUL_W = (0x00038 << 15), -+ OPC_LARCH_MULH_W = (0x00039 << 15), -+ OPC_LARCH_MULH_WU = (0x0003A << 15), -+ OPC_LARCH_MUL_D = (0x0003B << 15), -+ OPC_LARCH_MULH_D = (0x0003C << 15), -+ OPC_LARCH_MULH_DU = (0x0003D << 15), -+ OPC_LARCH_DIV_W = (0x00040 << 15), -+ OPC_LARCH_MOD_W = (0x00041 << 15), -+ OPC_LARCH_DIV_WU = (0x00042 << 15), -+ OPC_LARCH_MOD_WU = (0x00043 << 15), -+ OPC_LARCH_DIV_D = (0x00044 << 15), -+ OPC_LARCH_MOD_D = (0x00045 << 15), -+ OPC_LARCH_DIV_DU = (0x00046 << 15), -+ OPC_LARCH_MOD_DU = (0x00047 << 15), -+ OPC_LARCH_SRLI_W = (0x00089 << 15), -+ OPC_LARCH_SRAI_W = (0x00091 << 15), -+ OPC_LARCH_ROTRI_W = (0x00099 << 15), -+ -+ OPC_LARCH_ALSL_W = (0x0002 << 17), -+ OPC_LARCH_ALSL_D = (0x0016 << 17), -+ -+ OPC_LARCH_TRINS_W = (0x003 << 21) | (0x0 << 15), -+ OPC_LARCH_TRPICK_W = (0x003 << 21) | (0x1 << 15), -+}; -+ -+enum { -+ /* float opcodes */ -+ OPC_LARCH_FABS_S = (0x004501 << 10), -+ OPC_LARCH_FABS_D = (0x004502 << 10), -+ OPC_LARCH_FNEG_S = (0x004505 << 10), -+ OPC_LARCH_FNEG_D = (0x004506 << 10), -+ OPC_LARCH_FCLASS_S = (0x00450D << 10), -+ OPC_LARCH_FCLASS_D = (0x00450E << 10), -+ OPC_LARCH_FSQRT_S = (0x004511 << 10), -+ OPC_LARCH_FSQRT_D = (0x004512 << 10), -+ OPC_LARCH_FRECIP_S = (0x004515 << 10), -+ OPC_LARCH_FRECIP_D = (0x004516 << 10), -+ OPC_LARCH_FRSQRT_S = (0x004519 << 10), -+ OPC_LARCH_FRSQRT_D = (0x00451A << 10), -+ OPC_LARCH_FMOV_S = (0x004525 << 10), -+ OPC_LARCH_FMOV_D = (0x004526 << 10), -+ OPC_LARCH_GR2FR_W = (0x004529 << 10), -+ OPC_LARCH_GR2FR_D = (0x00452A << 10), -+ OPC_LARCH_GR2FRH_W = (0x00452B << 10), -+ OPC_LARCH_FR2GR_S = (0x00452D << 10), -+ OPC_LARCH_FR2GR_D = (0x00452E << 10), -+ OPC_LARCH_FRH2GR_S = (0x00452F << 10), -+ -+ OPC_LARCH_FCVT_S_D = (0x004646 << 10), -+ OPC_LARCH_FCVT_D_S = (0x004649 << 10), -+ OPC_LARCH_FTINTRM_W_S = (0x004681 << 10), -+ OPC_LARCH_FTINTRM_W_D = (0x004682 << 10), -+ OPC_LARCH_FTINTRM_L_S = (0x004689 << 10), -+ OPC_LARCH_FTINTRM_L_D = (0x00468A << 10), -+ OPC_LARCH_FTINTRP_W_S = (0x004691 << 10), -+ OPC_LARCH_FTINTRP_W_D = (0x004692 << 10), -+ OPC_LARCH_FTINTRP_L_S = (0x004699 << 10), -+ OPC_LARCH_FTINTRP_L_D = (0x00469A << 10), -+ OPC_LARCH_FTINTRZ_W_S = (0x0046A1 << 10), -+ OPC_LARCH_FTINTRZ_W_D = (0x0046A2 << 10), -+ OPC_LARCH_FTINTRZ_L_S = (0x0046A9 << 10), -+ OPC_LARCH_FTINTRZ_L_D = (0x0046AA << 10), -+ OPC_LARCH_FTINTRNE_W_S = (0x0046B1 << 10), -+ OPC_LARCH_FTINTRNE_W_D = (0x0046B2 << 10), -+ OPC_LARCH_FTINTRNE_L_S = (0x0046B9 << 10), -+ OPC_LARCH_FTINTRNE_L_D = (0x0046BA << 10), -+ OPC_LARCH_FTINT_W_S = (0x0046C1 << 10), -+ OPC_LARCH_FTINT_W_D = (0x0046C2 << 10), -+ OPC_LARCH_FTINT_L_S = (0x0046C9 << 10), -+ OPC_LARCH_FTINT_L_D = (0x0046CA << 10), -+ OPC_LARCH_FFINT_S_W = (0x004744 << 10), -+ OPC_LARCH_FFINT_S_L = (0x004746 << 10), -+ OPC_LARCH_FFINT_D_W = (0x004748 << 10), -+ OPC_LARCH_FFINT_D_L = (0x00474A << 10), -+ OPC_LARCH_FRINT_S = (0x004791 << 10), -+ OPC_LARCH_FRINT_D = (0x004792 << 10), -+ -+ OPC_LARCH_FADD_S = (0x00201 << 15), -+ OPC_LARCH_FADD_D = (0x00202 << 15), -+ OPC_LARCH_FSUB_S = (0x00205 << 15), -+ OPC_LARCH_FSUB_D = (0x00206 << 15), -+ OPC_LARCH_FMUL_S = (0x00209 << 15), -+ OPC_LARCH_FMUL_D = (0x0020A << 15), -+ OPC_LARCH_FDIV_S = (0x0020D << 15), -+ OPC_LARCH_FDIV_D = (0x0020E << 15), -+ OPC_LARCH_FMAX_S = (0x00211 << 15), -+ OPC_LARCH_FMAX_D = (0x00212 << 15), -+ OPC_LARCH_FMIN_S = (0x00215 << 15), -+ OPC_LARCH_FMIN_D = (0x00216 << 15), -+ OPC_LARCH_FMAXA_S = (0x00219 << 15), -+ OPC_LARCH_FMAXA_D = (0x0021A << 15), -+ OPC_LARCH_FMINA_S = (0x0021D << 15), -+ OPC_LARCH_FMINA_D = (0x0021E << 15), -+}; -+ -+enum { -+ /* 12 bit immediate opcodes */ -+ OPC_LARCH_SLTI = (0x008 << 22), -+ OPC_LARCH_SLTIU = (0x009 << 22), -+ OPC_LARCH_ADDI_W = (0x00A << 22), -+ OPC_LARCH_ADDI_D = (0x00B << 22), -+ OPC_LARCH_ANDI = (0x00D << 22), -+ OPC_LARCH_ORI = (0x00E << 22), -+ OPC_LARCH_XORI = (0x00F << 22), -+}; -+ -+enum { -+ /* load/store opcodes */ -+ OPC_LARCH_FLDX_S = (0x07060 << 15), -+ OPC_LARCH_FLDX_D = (0x07068 << 15), -+ OPC_LARCH_FSTX_S = (0x07070 << 15), -+ OPC_LARCH_FSTX_D = (0x07078 << 15), -+ OPC_LARCH_FLDGT_S = (0x070E8 << 15), -+ OPC_LARCH_FLDGT_D = (0x070E9 << 15), -+ OPC_LARCH_FLDLE_S = (0x070EA << 15), -+ OPC_LARCH_FLDLE_D = (0x070EB << 15), -+ OPC_LARCH_FSTGT_S = (0x070EC << 15), -+ OPC_LARCH_FSTGT_D = (0x070ED << 15), -+ OPC_LARCH_FSTLE_S = (0x070EE << 15), -+ OPC_LARCH_FSTLE_D = (0x070EF << 15), -+ -+ OPC_LARCH_LD_B = (0x0A0 << 22), -+ OPC_LARCH_LD_H = (0x0A1 << 22), -+ OPC_LARCH_LD_W = (0x0A2 << 22), -+ OPC_LARCH_LD_D = (0x0A3 << 22), -+ OPC_LARCH_ST_B = (0x0A4 << 22), -+ OPC_LARCH_ST_H = (0x0A5 << 22), -+ OPC_LARCH_ST_W = (0x0A6 << 22), -+ OPC_LARCH_ST_D = (0x0A7 << 22), -+ OPC_LARCH_LD_BU = (0x0A8 << 22), -+ OPC_LARCH_LD_HU = (0x0A9 << 22), -+ OPC_LARCH_LD_WU = (0x0AA << 22), -+ OPC_LARCH_FLD_S = (0x0AC << 22), -+ OPC_LARCH_FST_S = (0x0AD << 22), -+ OPC_LARCH_FLD_D = (0x0AE << 22), -+ OPC_LARCH_FST_D = (0x0AF << 22), -+ -+ OPC_LARCH_LL_W = (0x20 << 24), -+ OPC_LARCH_SC_W = (0x21 << 24), -+ OPC_LARCH_LL_D = (0x22 << 24), -+ OPC_LARCH_SC_D = (0x23 << 24), -+ OPC_LARCH_LDPTR_W = (0x24 << 24), -+ OPC_LARCH_STPTR_W = (0x25 << 24), -+ OPC_LARCH_LDPTR_D = (0x26 << 24), -+ OPC_LARCH_STPTR_D = (0x27 << 24), -+}; -+ -+enum { -+ /* jump opcodes */ -+ OPC_LARCH_BEQZ = (0x10 << 26), -+ OPC_LARCH_BNEZ = (0x11 << 26), -+ OPC_LARCH_B = (0x14 << 26), -+ OPC_LARCH_BEQ = (0x16 << 26), -+ OPC_LARCH_BNE = (0x17 << 26), -+ OPC_LARCH_BLT = (0x18 << 26), -+ OPC_LARCH_BGE = (0x19 << 26), -+ OPC_LARCH_BLTU = (0x1A << 26), -+ OPC_LARCH_BGEU = (0x1B << 26), -+}; -+ -+#endif -diff --git a/target/loongarch64/internal.h b/target/loongarch64/internal.h -new file mode 100644 -index 000000000..43594c5ac ---- /dev/null -+++ b/target/loongarch64/internal.h -@@ -0,0 +1,184 @@ -+#ifndef LOONGARCH_INTERNAL_H -+#define LOONGARCH_INTERNAL_H -+ -+#include "cpu-csr.h" -+ -+/* MMU types, the first four entries have the same layout as the -+ CP0C0_MT field. */ -+enum loongarch_mmu_types { -+ MMU_TYPE_NONE, -+ MMU_TYPE_LS3A5K, /* LISA CSR */ -+}; -+ -+ -+ -+struct loongarch_def_t { -+ const char *name; -+ int32_t CSR_PRid; -+ int32_t FCSR0; -+ int32_t FCSR0_rw_bitmask; -+ int32_t PABITS; -+ CPU_LOONGARCH_CSR -+ uint64_t insn_flags; -+ enum loongarch_mmu_types mmu_type; -+ int cpu_cfg[64]; -+}; -+ -+/* loongarch 3a5000 TLB entry */ -+struct ls3a5k_tlb_t { -+ target_ulong VPN; -+ uint64_t PageMask; /* CSR_TLBIDX[29:24] */ -+ uint32_t PageSize; -+ uint16_t ASID; -+ unsigned int G:1; /* CSR_TLBLO[6] */ -+ -+ unsigned int C0:3; /* CSR_TLBLO[5:4] */ -+ unsigned int C1:3; -+ -+ unsigned int V0:1; /* CSR_TLBLO[0] */ -+ unsigned int V1:1; -+ -+ unsigned int WE0:1; /* CSR_TLBLO[1] */ -+ unsigned int WE1:1; -+ -+ unsigned int XI0:1; /* CSR_TLBLO[62] */ -+ unsigned int XI1:1; -+ -+ unsigned int RI0:1; /* CSR_TLBLO[61] */ -+ unsigned int RI1:1; -+ -+ unsigned int EHINV:1;/* CSR_TLBIDX[31] */ -+ -+ unsigned int PLV0:2; /* CSR_TLBLO[3:2] */ -+ unsigned int PLV1:2; -+ -+ unsigned int RPLV0:1; -+ unsigned int RPLV1:1; /* CSR_TLBLO[63] */ -+ -+ uint64_t PPN0; /* CSR_TLBLO[47:12] */ -+ uint64_t PPN1; /* CSR_TLBLO[47:12] */ -+}; -+typedef struct ls3a5k_tlb_t ls3a5k_tlb_t; -+ -+ -+struct CPULOONGARCHTLBContext { -+ uint32_t nb_tlb; -+ uint32_t tlb_in_use; -+ int (*map_address)(struct CPULOONGARCHState *env, hwaddr *physical, int *prot, -+ target_ulong address, int rw, int access_type); -+ void (*helper_tlbwr)(struct CPULOONGARCHState *env); -+ void (*helper_tlbfill)(struct CPULOONGARCHState *env); -+ void (*helper_tlbsrch)(struct CPULOONGARCHState *env); -+ void (*helper_tlbrd)(struct CPULOONGARCHState *env); -+ void (*helper_tlbclr)(struct CPULOONGARCHState *env); -+ void (*helper_tlbflush)(struct CPULOONGARCHState *env); -+ void (*helper_invtlb)(struct CPULOONGARCHState *env, target_ulong addr, -+ target_ulong info, int op); -+ union { -+ struct { -+ uint64_t ftlb_mask; -+ uint32_t ftlb_size; /* at most : 8 * 256 = 2048 */ -+ uint32_t vtlb_size; /* at most : 64 */ -+ ls3a5k_tlb_t tlb[2048 + 64]; /* at most : 2048 FTLB + 64 VTLB */ -+ } ls3a5k; -+ } mmu; -+}; -+ -+enum { -+ TLBRET_PE = -7, -+ TLBRET_XI = -6, -+ TLBRET_RI = -5, -+ TLBRET_DIRTY = -4, -+ TLBRET_INVALID = -3, -+ TLBRET_NOMATCH = -2, -+ TLBRET_BADADDR = -1, -+ TLBRET_MATCH = 0 -+}; -+ -+ -+extern unsigned int ieee_rm[]; -+ -+static inline void restore_rounding_mode(CPULOONGARCHState *env) -+{ -+ set_float_rounding_mode(ieee_rm[(env->active_fpu.fcsr0 >> FCSR0_RM) & 0x3], -+ &env->active_fpu.fp_status); -+} -+ -+static inline void restore_flush_mode(CPULOONGARCHState *env) -+{ -+ set_flush_to_zero(0, &env->active_fpu.fp_status); -+} -+ -+static inline void restore_fp_status(CPULOONGARCHState *env) -+{ -+ restore_rounding_mode(env); -+ restore_flush_mode(env); -+} -+static inline void compute_hflags(CPULOONGARCHState *env) -+{ -+ env->hflags &= ~(LARCH_HFLAG_64 | LARCH_HFLAG_FPU | LARCH_HFLAG_KSU | -+ LARCH_HFLAG_AWRAP | LARCH_HFLAG_LSX | LARCH_HFLAG_LASX); -+ -+ env->hflags |= (env->CSR_CRMD & CSR_CRMD_PLV); -+ env->hflags |= LARCH_HFLAG_64; -+ -+ if (env->CSR_EUEN & CSR_EUEN_FPEN) { -+ env->hflags |= LARCH_HFLAG_FPU; -+ } -+ if (env->CSR_EUEN & CSR_EUEN_LSXEN) { -+ env->hflags |= LARCH_HFLAG_LSX; -+ } -+ if (env->CSR_EUEN & CSR_EUEN_LASXEN) { -+ env->hflags |= LARCH_HFLAG_LASX; -+ } -+ if (env->CSR_EUEN & CSR_EUEN_LBTEN) { -+ env->hflags |= LARCH_HFLAG_LBT; -+ } -+} -+ -+/* Check if there is pending and not masked out interrupt */ -+static inline bool cpu_loongarch_hw_interrupts_pending(CPULOONGARCHState *env) -+{ -+ int32_t pending; -+ int32_t status; -+ bool r; -+ -+ pending = env->CSR_ESTAT & CSR_ESTAT_IPMASK; -+ status = env->CSR_ECFG & CSR_ECFG_IPMASK; -+ -+ /* Configured with compatibility or VInt (Vectored Interrupts) -+ treats the pending lines as individual interrupt lines, the status -+ lines are individual masks. */ -+ r = (pending & status) != 0; -+ -+ return r; -+} -+ -+ -+/* stabletimer.c */ -+uint32_t cpu_loongarch_get_random_ls3a5k_tlb(uint32_t low, uint32_t high); -+uint64_t cpu_loongarch_get_stable_counter(CPULOONGARCHState *env); -+uint64_t cpu_loongarch_get_stable_timer_ticks(CPULOONGARCHState *env); -+void cpu_loongarch_store_stable_timer_config(CPULOONGARCHState *env, uint64_t value); -+int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, -+ int cpuid, DumpState *s); -+ -+void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags); -+ -+/* TODO QOM'ify CPU reset and remove */ -+void cpu_state_reset(CPULOONGARCHState *s); -+void cpu_loongarch_realize_env(CPULOONGARCHState *env); -+ -+int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n); -+int loongarch_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); -+ -+#ifdef CONFIG_TCG -+#include "fpu_helper.h" -+#endif -+ -+#ifndef CONFIG_USER_ONLY -+extern const struct VMStateDescription vmstate_loongarch_cpu; -+hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -+#endif -+ -+#endif -diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c -new file mode 100644 -index 000000000..404a605eb ---- /dev/null -+++ b/target/loongarch64/kvm.c -@@ -0,0 +1,1622 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * KVM/LOONGARCH: LOONGARCH specific KVM APIs -+ * -+ * Copyright (C) 2012-2014 Imagination Technologies Ltd. -+ * Authors: Sanjay Lal -+*/ -+ -+#include "qemu/osdep.h" -+#include -+ -+#include -+ -+#include "qemu-common.h" -+#include "cpu.h" -+#include "internal.h" -+#include "qemu/error-report.h" -+#include "qemu/timer.h" -+#include "qemu/main-loop.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/kvm.h" -+#include "sysemu/runstate.h" -+#include "sysemu/cpus.h" -+#include "kvm_larch.h" -+#include "exec/memattrs.h" -+#include "exec/gdbstub.h" -+ -+#define DEBUG_KVM 0 -+/* A 16384-byte buffer can hold the 8-byte kvm_msrs header, plus -+ * 2047 kvm_msr_entry structs */ -+#define MSR_BUF_SIZE 16384 -+ -+#define DPRINTF(fmt, ...) \ -+ do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0) -+ -+/* -+ * Define loongarch kvm version. -+ * Add version number when -+ * qemu/kvm interface changed -+ */ -+#define KVM_LOONGARCH_VERSION 1 -+ -+static struct { -+ target_ulong addr; -+ int len; -+ int type; -+} inst_breakpoint[8], data_breakpoint[8]; -+ -+int nb_data_breakpoint = 0, nb_inst_breakpoint = 0; -+static int kvm_loongarch_version_cap; -+ -+/* Hardware breakpoint control register -+ * 4:1 plv0-plv3 enable -+ * 6:5 config virtualization mode -+ * 9:8 load store */ -+static const int type_code[] = { -+ [GDB_BREAKPOINT_HW] = 0x5e, -+ [GDB_WATCHPOINT_READ] = (0x5e | 1 << 8), -+ [GDB_WATCHPOINT_WRITE] = (0x5e | 1 << 9), -+ [GDB_WATCHPOINT_ACCESS] = (0x5e | 1 << 8 | 1 << 9) -+}; -+ -+const KVMCapabilityInfo kvm_arch_required_capabilities[] = { -+ KVM_CAP_LAST_INFO -+}; -+ -+static void kvm_loongarch_update_state(void *opaque, bool running, RunState state); -+static inline int kvm_larch_putq(CPUState *cs, uint64_t reg_id, uint64_t *addr); -+ -+unsigned long kvm_arch_vcpu_id(CPUState *cs) -+{ -+ return cs->cpu_index; -+} -+ -+int kvm_arch_init(MachineState *ms, KVMState *s) -+{ -+ /* LOONGARCH has 128 signals */ -+ kvm_set_sigmask_len(s, 16); -+ -+ kvm_loongarch_version_cap = kvm_check_extension(s, KVM_CAP_LOONGARCH_VZ); -+ -+ if (kvm_loongarch_version_cap != KVM_LOONGARCH_VERSION) { -+ warn_report("QEMU/KVM version not match, qemu_la_version: lvz-%d,\ -+ kvm_la_version: lvz-%d \n", -+ KVM_LOONGARCH_VERSION, kvm_loongarch_version_cap); -+ } -+ return 0; -+} -+ -+int kvm_arch_irqchip_create(KVMState *s) -+{ -+ return 0; -+} -+ -+int kvm_arch_init_vcpu(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ int ret = 0; -+ -+ cpu->cpuStateEntry = qemu_add_vm_change_state_handler(kvm_loongarch_update_state, cs); -+ cpu->kvm_msr_buf = g_malloc0(MSR_BUF_SIZE); -+ DPRINTF("%s\n", __func__); -+ return ret; -+} -+ -+int kvm_arch_destroy_vcpu(CPUState *cs) -+{ -+ return 0; -+} -+ -+static void kvm_msr_buf_reset(LOONGARCHCPU *cpu) -+{ -+ memset(cpu->kvm_msr_buf, 0, MSR_BUF_SIZE); -+} -+ -+static void kvm_msr_entry_add(LOONGARCHCPU *cpu, uint32_t index, uint64_t value) -+{ -+ struct kvm_msrs *msrs = cpu->kvm_msr_buf; -+ void *limit = ((void *)msrs) + MSR_BUF_SIZE; -+ struct kvm_csr_entry *entry = &msrs->entries[msrs->ncsrs]; -+ -+ assert((void *)(entry + 1) <= limit); -+ -+ entry->index = index; -+ entry->reserved = 0; -+ entry->data = value; -+ msrs->ncsrs++; -+} -+ -+void kvm_loongarch_reset_vcpu(LOONGARCHCPU *cpu) -+{ -+ int ret = 0; -+ uint64_t reset = 1; -+ -+ if (CPU(cpu)->kvm_fd > 0) { -+ ret = kvm_larch_putq(CPU(cpu), KVM_REG_LOONGARCH_VCPU_RESET, &reset); -+ if (ret < 0) { -+ error_report("%s reset vcpu failed:%d", __func__, ret); -+ } -+ } -+ -+ DPRINTF("%s\n", __func__); -+} -+ -+void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg) -+{ -+ int n; -+ if (kvm_sw_breakpoints_active(cpu)) { -+ dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; -+ } -+ if (nb_data_breakpoint > 0) { -+ dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; -+ for (n = 0; n < nb_data_breakpoint; n++) { -+ dbg->arch.data_breakpoint[n].addr = data_breakpoint[n].addr; -+ dbg->arch.data_breakpoint[n].mask = 0; -+ dbg->arch.data_breakpoint[n].asid = 0; -+ dbg->arch.data_breakpoint[n].ctrl = type_code[data_breakpoint[n].type]; -+ } -+ dbg->arch.data_bp_nums = nb_data_breakpoint; -+ } else { -+ dbg->arch.data_bp_nums = 0; -+ } -+ if (nb_inst_breakpoint > 0) { -+ dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; -+ for (n = 0; n < nb_inst_breakpoint; n++) { -+ dbg->arch.inst_breakpoint[n].addr = inst_breakpoint[n].addr; -+ dbg->arch.inst_breakpoint[n].mask = 0; -+ dbg->arch.inst_breakpoint[n].asid = 0; -+ dbg->arch.inst_breakpoint[n].ctrl = type_code[inst_breakpoint[n].type]; -+ } -+ dbg->arch.inst_bp_nums = nb_inst_breakpoint; -+ } else { -+ dbg->arch.inst_bp_nums = 0; -+ } -+} -+ -+static const unsigned int brk_insn = 0x002b8005; -+ -+int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) -+{ -+ DPRINTF("%s\n", __func__); -+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) || -+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) { -+ error_report("%s failed", __func__); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) -+{ -+ static uint32_t brk; -+ -+ DPRINTF("%s\n", __func__); -+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) || -+ brk != brk_insn || -+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) { -+ error_report("%s failed", __func__); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static int find_hw_breakpoint(uint64_t addr, int len, int type) -+{ -+ int n; -+ switch (type) { -+ case GDB_BREAKPOINT_HW: -+ if (nb_inst_breakpoint == 0) { -+ return -1; -+ } -+ for (n = 0; n < nb_inst_breakpoint; n++) { -+ if (inst_breakpoint[n].addr == addr && inst_breakpoint[n].type == type) { -+ return n; -+ } -+ } -+ break; -+ case GDB_WATCHPOINT_WRITE: -+ case GDB_WATCHPOINT_READ: -+ case GDB_WATCHPOINT_ACCESS: -+ if (nb_data_breakpoint == 0) { -+ return -1; -+ } -+ for (n = 0; n < nb_data_breakpoint; n++) { -+ if (data_breakpoint[n].addr == addr && data_breakpoint[n].type == type && -+ data_breakpoint[n].len == len) { -+ return n; -+ } -+ } -+ break; -+ default: -+ return -1; -+ } -+ return -1; -+} -+ -+int kvm_arch_insert_hw_breakpoint(target_ulong addr, -+ target_ulong len, int type) -+{ -+ switch (type) { -+ case GDB_BREAKPOINT_HW: -+ len = 1; -+ if (nb_inst_breakpoint == 8) { -+ return -ENOBUFS; -+ } -+ if (find_hw_breakpoint(addr, len, type) >= 0) { -+ return -EEXIST; -+ } -+ inst_breakpoint[nb_inst_breakpoint].addr = addr; -+ inst_breakpoint[nb_inst_breakpoint].len = len; -+ inst_breakpoint[nb_inst_breakpoint].type = type; -+ nb_inst_breakpoint++; -+ break; -+ case GDB_WATCHPOINT_WRITE: -+ case GDB_WATCHPOINT_READ: -+ case GDB_WATCHPOINT_ACCESS: -+ switch (len) { -+ case 1: -+ case 2: -+ case 4: -+ case 8: -+ if (addr & (len - 1)) { -+ return -EINVAL; -+ } -+ if (nb_data_breakpoint == 8) { -+ return -ENOBUFS; -+ } -+ if (find_hw_breakpoint(addr, len, type) >= 0) { -+ return -EEXIST; -+ } -+ data_breakpoint[nb_data_breakpoint].addr = addr; -+ data_breakpoint[nb_data_breakpoint].len = len; -+ data_breakpoint[nb_data_breakpoint].type = type; -+ nb_data_breakpoint++; -+ break; -+ default: -+ return -EINVAL; -+ } -+ break; -+ default: -+ return -ENOSYS; -+ } -+ return 0; -+} -+ -+int kvm_arch_remove_hw_breakpoint(target_ulong addr, -+ target_ulong len, int type) -+{ -+ int n; -+ n = find_hw_breakpoint(addr, (type == GDB_BREAKPOINT_HW) ? 1 : len, type); -+ if (n < 0) { -+ printf("err not find remove target\n"); -+ return -ENOENT; -+ } -+ switch (type) { -+ case GDB_BREAKPOINT_HW: -+ nb_inst_breakpoint--; -+ inst_breakpoint[n] = inst_breakpoint[nb_inst_breakpoint]; -+ break; -+ case GDB_WATCHPOINT_WRITE: -+ case GDB_WATCHPOINT_READ: -+ case GDB_WATCHPOINT_ACCESS: -+ nb_data_breakpoint--; -+ data_breakpoint[n] = data_breakpoint[nb_data_breakpoint]; -+ break; -+ default: -+ return -1; -+ } -+ return 0; -+} -+ -+void kvm_arch_remove_all_hw_breakpoints(void) -+{ -+ DPRINTF("%s\n", __func__); -+ nb_data_breakpoint = 0; -+ nb_inst_breakpoint = 0; -+} -+ -+static inline int cpu_loongarch_io_interrupts_pending(LOONGARCHCPU *cpu) -+{ -+ CPULOONGARCHState *env = &cpu->env; -+ -+ return env->CSR_ESTAT & (0x1 << 2); -+} -+ -+void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ int r; -+ struct kvm_loongarch_interrupt intr; -+ -+ qemu_mutex_lock_iothread(); -+ -+ if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && -+ cpu_loongarch_io_interrupts_pending(cpu)) { -+ intr.cpu = -1; -+ intr.irq = 2; -+ r = kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); -+ if (r < 0) { -+ error_report("%s: cpu %d: failed to inject IRQ %x", -+ __func__, cs->cpu_index, intr.irq); -+ } -+ } -+ -+ qemu_mutex_unlock_iothread(); -+} -+ -+MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) -+{ -+ return MEMTXATTRS_UNSPECIFIED; -+} -+ -+int kvm_arch_process_async_events(CPUState *cs) -+{ -+ return cs->halted; -+} -+ -+static CPUWatchpoint hw_watchpoint; -+ -+static bool kvm_loongarch_handle_debug(CPUState *cs, struct kvm_run *run) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int i; -+ bool ret = false; -+ kvm_cpu_synchronize_state(cs); -+ if (cs->singlestep_enabled) { -+ return true; -+ } -+ if (kvm_find_sw_breakpoint(cs, env->active_tc.PC)) { -+ return true; -+ } -+ /* hw breakpoint */ -+ if (run->debug.arch.exception == EXCCODE_WATCH) { -+ for (i = 0; i < 8; i++) { -+ if (run->debug.arch.fwps & (1 << i)) { -+ ret = true; -+ break; -+ } -+ } -+ for (i = 0; i < 8; i++) { -+ if (run->debug.arch.mwps & (1 << i)) { -+ cs->watchpoint_hit = &hw_watchpoint; -+ hw_watchpoint.vaddr = data_breakpoint[i].addr; -+ switch (data_breakpoint[i].type) { -+ case GDB_WATCHPOINT_READ: -+ ret = true; -+ hw_watchpoint.flags = BP_MEM_READ; -+ break; -+ case GDB_WATCHPOINT_WRITE: -+ ret = true; -+ hw_watchpoint.flags = BP_MEM_WRITE; -+ break; -+ case GDB_WATCHPOINT_ACCESS: -+ ret = true; -+ hw_watchpoint.flags = BP_MEM_ACCESS; -+ break; -+ } -+ } -+ } -+ run->debug.arch.exception = 0; -+ run->debug.arch.fwps = 0; -+ run->debug.arch.mwps = 0; -+ } -+ return ret; -+} -+ -+int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) -+{ -+ int ret; -+ -+ DPRINTF("%s\n", __func__); -+ switch (run->exit_reason) { -+ case KVM_EXIT_HYPERCALL: -+ DPRINTF("handle LOONGARCH hypercall\n"); -+ ret = 0; -+ run->hypercall.ret = ret; -+ break; -+ -+ case KVM_EXIT_DEBUG: -+ ret = 0; -+ if (kvm_loongarch_handle_debug(cs, run)) { -+ ret = EXCP_DEBUG; -+ } -+ break; -+ default: -+ error_report("%s: unknown exit reason %d", -+ __func__, run->exit_reason); -+ ret = -1; -+ break; -+ } -+ -+ return ret; -+} -+ -+bool kvm_arch_stop_on_emulation_error(CPUState *cs) -+{ -+ DPRINTF("%s\n", __func__); -+ return true; -+} -+/* -+#if 0 -+int kvmloongarch_load_kernel(CPUState *env, void *ram_base) -+{ -+ int ret; -+ -+ ret = kvm_vcpu_ioctl(env, KVM_LOAD_KERNEL, ram_base); -+ -+ return ret; -+} -+#endif -+*/ -+void kvm_arch_init_irq_routing(KVMState *s) -+{ -+} -+ -+int kvm_loongarch_set_interrupt(LOONGARCHCPU *cpu, int irq, int level) -+{ -+ CPUState *cs = CPU(cpu); -+ struct kvm_loongarch_interrupt intr; -+ -+ if (!kvm_enabled()) { -+ return 0; -+ } -+ -+ intr.cpu = -1; -+ -+ if (level) { -+ intr.irq = irq; -+ } else { -+ intr.irq = -irq; -+ } -+ -+ kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); -+ -+ return 0; -+} -+ -+int kvm_loongarch_set_ipi_interrupt(LOONGARCHCPU *cpu, int irq, int level) -+{ -+ CPUState *cs = current_cpu; -+ CPUState *dest_cs = CPU(cpu); -+ struct kvm_loongarch_interrupt intr; -+ -+ if (!kvm_enabled()) { -+ return 0; -+ } -+ -+ intr.cpu = dest_cs->cpu_index; -+ -+ if (level) { -+ intr.irq = irq; -+ } else { -+ intr.irq = -irq; -+ } -+ -+ DPRINTF("%s: IRQ: %d\n", __func__, intr.irq); -+ if (!current_cpu) { -+ cs = dest_cs; -+ } -+ kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); -+ -+ return 0; -+} -+ -+static inline int kvm_loongarch_put_one_reg(CPUState *cs, uint64_t reg_id, -+ int32_t *addr) -+{ -+ struct kvm_one_reg csrreg = { -+ .id = reg_id, -+ .addr = (uintptr_t)addr -+ }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_put_one_ureg(CPUState *cs, uint64_t reg_id, -+ uint32_t *addr) -+{ -+ struct kvm_one_reg csrreg = { -+ .id = reg_id, -+ .addr = (uintptr_t)addr -+ }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_put_one_ulreg(CPUState *cs, uint64_t reg_id, -+ target_ulong *addr) -+{ -+ uint64_t val64 = *addr; -+ struct kvm_one_reg csrreg = { -+ .id = reg_id, -+ .addr = (uintptr_t)&val64 -+ }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_put_one_reg64(CPUState *cs, int64_t reg_id, -+ int64_t *addr) -+{ -+ struct kvm_one_reg csrreg = { -+ .id = reg_id, -+ .addr = (uintptr_t)addr -+ }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_larch_putq(CPUState *cs, uint64_t reg_id, -+ uint64_t *addr) -+{ -+ struct kvm_one_reg csrreg = { -+ .id = reg_id, -+ .addr = (uintptr_t)addr -+ }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_get_one_reg(CPUState *cs, uint64_t reg_id, -+ int32_t *addr) -+{ -+ struct kvm_one_reg csrreg = { -+ .id = reg_id, -+ .addr = (uintptr_t)addr -+ }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_get_one_ureg(CPUState *cs, uint64_t reg_id, -+ uint32_t *addr) -+{ -+ struct kvm_one_reg csrreg = { -+ .id = reg_id, -+ .addr = (uintptr_t)addr -+ }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_get_one_ulreg(CPUState *cs, uint64_t reg_id, -+ target_ulong *addr) -+{ -+ int ret; -+ uint64_t val64 = 0; -+ struct kvm_one_reg csrreg = { -+ .id = reg_id, -+ .addr = (uintptr_t)&val64 -+ }; -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); -+ if (ret >= 0) { -+ *addr = val64; -+ } -+ return ret; -+} -+ -+static inline int kvm_loongarch_get_one_reg64(CPUState *cs, int64_t reg_id, -+ int64_t *addr) -+{ -+ struct kvm_one_reg csrreg = { -+ .id = reg_id, -+ .addr = (uintptr_t)addr -+ }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_larch_getq(CPUState *cs, uint64_t reg_id, -+ uint64_t *addr) -+{ -+ struct kvm_one_reg csrreg = { -+ .id = reg_id, -+ .addr = (uintptr_t)addr -+ }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_change_one_reg(CPUState *cs, uint64_t reg_id, -+ int32_t *addr, int32_t mask) -+{ -+ int err; -+ int32_t tmp, change; -+ -+ err = kvm_loongarch_get_one_reg(cs, reg_id, &tmp); -+ if (err < 0) { -+ return err; -+ } -+ -+ /* only change bits in mask */ -+ change = (*addr ^ tmp) & mask; -+ if (!change) { -+ return 0; -+ } -+ -+ tmp = tmp ^ change; -+ return kvm_loongarch_put_one_reg(cs, reg_id, &tmp); -+} -+ -+static inline int kvm_loongarch_change_one_reg64(CPUState *cs, uint64_t reg_id, -+ int64_t *addr, int64_t mask) -+{ -+ int err; -+ int64_t tmp, change; -+ -+ err = kvm_loongarch_get_one_reg64(cs, reg_id, &tmp); -+ if (err < 0) { -+ DPRINTF("%s: Failed to get CSR_CONFIG7 (%d)\n", __func__, err); -+ return err; -+ } -+ -+ /* only change bits in mask */ -+ change = (*addr ^ tmp) & mask; -+ if (!change) { -+ return 0; -+ } -+ -+ tmp = tmp ^ change; -+ return kvm_loongarch_put_one_reg64(cs, reg_id, &tmp); -+} -+/* -+ * Handle the VM clock being started or stopped -+ */ -+static void kvm_loongarch_update_state(void *opaque, bool running, RunState state) -+{ -+ CPUState *cs = opaque; -+ int ret; -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ -+ /* -+ * If state is already dirty (synced to QEMU) then the KVM timer state is -+ * already saved and can be restored when it is synced back to KVM. -+ */ -+ if (!running) { -+ ret = kvm_larch_getq(cs, -+ KVM_REG_LOONGARCH_COUNTER, &cpu->counter_value); -+ if (ret < 0) { -+ printf("%s: Failed to get counter_value (%d)\n", __func__, ret); -+ } -+ -+ } else { -+ ret = kvm_larch_putq(cs, KVM_REG_LOONGARCH_COUNTER, -+ &(LOONGARCH_CPU(cs))->counter_value); -+ if (ret < 0) { -+ printf("%s: Failed to put counter_value (%d)\n", __func__, ret); -+ } -+ } -+} -+ -+static int kvm_loongarch_put_fpu_registers(CPUState *cs, int level) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int err, ret = 0; -+ unsigned int i; -+ struct kvm_fpu fpu; -+ -+ fpu.fcsr = env->active_fpu.fcsr0; -+ for (i = 0; i < 32; i++) { -+ memcpy(&fpu.fpr[i], &env->active_fpu.fpr[i], sizeof(struct kvm_fpureg)); -+ } -+ for (i = 0; i < 8; i++) { -+ ((char *)&fpu.fcc)[i] = env->active_fpu.cf[i]; -+ } -+ fpu.vcsr = env->active_fpu.vcsr16; -+ -+ err = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu); -+ if (err < 0) { -+ DPRINTF("%s: Failed to get FPU (%d)\n", __func__, err); -+ ret = err; -+ } -+ -+ return ret; -+} -+ -+static int kvm_loongarch_get_fpu_registers(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int err, ret = 0; -+ unsigned int i; -+ struct kvm_fpu fpu; -+ -+ err = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu); -+ if (err < 0) { -+ DPRINTF("%s: Failed to get FPU (%d)\n", __func__, err); -+ ret = err; -+ } else { -+ env->active_fpu.fcsr0 = fpu.fcsr; -+ for (i = 0; i < 32; i++) { -+ memcpy(&env->active_fpu.fpr[i], &fpu.fpr[i], sizeof(struct kvm_fpureg)); -+ } -+ for (i = 0; i < 8; i++) { -+ env->active_fpu.cf[i] = ((char *)&fpu.fcc)[i]; -+ } -+ env->active_fpu.vcsr16 = fpu.vcsr; -+ } -+ -+ return ret; -+} -+ -+#define KVM_PUT_ONE_UREG64(cs, regidx, addr) \ -+ ({ \ -+ int err; \ -+ uint64_t csrid = 0; \ -+ csrid = (KVM_IOC_CSRID(regidx)); \ -+ err = kvm_larch_putq(cs, csrid, addr); \ -+ if (err < 0) { \ -+ DPRINTF("%s: Failed to put regidx 0x%x err:%d\n", __func__, regidx, err); \ -+ } \ -+ err; \ -+ }) -+ -+ -+static int kvm_loongarch_put_csr_registers(CPUState *cs, int level) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int ret = 0; -+ -+ (void)level; -+ -+ kvm_msr_buf_reset(cpu); -+ -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CRMD, env->CSR_CRMD); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRMD, env->CSR_PRMD); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_EUEN, env->CSR_EUEN); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_MISC, env->CSR_MISC); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ECFG, env->CSR_ECFG); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ESTAT, env->CSR_ESTAT); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERA, env->CSR_ERA); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADV, env->CSR_BADV); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADI, env->CSR_BADI); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_EEPN, env->CSR_EEPN); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, env->CSR_TLBIDX); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, env->CSR_TLBEHI); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, env->CSR_TLBELO0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, env->CSR_TLBELO1); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GTLBC, env->CSR_GTLBC); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TRGP, env->CSR_TRGP); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ASID, env->CSR_ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDL, env->CSR_PGDL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDH, env->CSR_PGDH); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGD, env->CSR_PGD); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, env->CSR_PWCTL0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, env->CSR_PWCTL1); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, env->CSR_STLBPGSIZE); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_RVACFG, env->CSR_RVACFG); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CPUID, env->CSR_CPUID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, env->CSR_PRCFG1); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, env->CSR_PRCFG2); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, env->CSR_PRCFG3); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS0, env->CSR_KS0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS1, env->CSR_KS1); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS2, env->CSR_KS2); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS3, env->CSR_KS3); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS4, env->CSR_KS4); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS5, env->CSR_KS5); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS6, env->CSR_KS6); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS7, env->CSR_KS7); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TMID, env->CSR_TMID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CNTC, env->CSR_CNTC); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, env->CSR_TINTCLR); -+ -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GSTAT, env->CSR_GSTAT); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCFG, env->CSR_GCFG); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GINTC, env->CSR_GINTC); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCNTC, env->CSR_GCNTC); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, env->CSR_LLBCTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, env->CSR_IMPCTL1); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, env->CSR_IMPCTL2); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GNMI, env->CSR_GNMI); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, env->CSR_TLBRENT); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, env->CSR_TLBRBADV); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, env->CSR_TLBRERA); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, env->CSR_TLBRSAVE); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, env->CSR_TLBRELO0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, env->CSR_TLBRELO1); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, env->CSR_TLBREHI); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, env->CSR_TLBRPRMD); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, env->CSR_ERRCTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, env->CSR_ERRINFO); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, env->CSR_ERRINFO1); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRENT, env->CSR_ERRENT); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRERA, env->CSR_ERRERA); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, env->CSR_ERRSAVE); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CTAG, env->CSR_CTAG); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, env->CSR_DMWIN0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, env->CSR_DMWIN1); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, env->CSR_DMWIN2); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, env->CSR_DMWIN3); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, env->CSR_PERFCTRL0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, env->CSR_PERFCNTR0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, env->CSR_PERFCTRL1); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, env->CSR_PERFCNTR1); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, env->CSR_PERFCTRL2); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, env->CSR_PERFCNTR2); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, env->CSR_PERFCTRL3); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, env->CSR_PERFCNTR3); -+ -+ /* debug */ -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPC, env->CSR_MWPC); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPS, env->CSR_MWPS); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, env->CSR_DB0ADDR); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, env->CSR_DB0MASK); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, env->CSR_DB0CTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, env->CSR_DB0ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, env->CSR_DB1ADDR); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, env->CSR_DB1MASK); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, env->CSR_DB1CTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, env->CSR_DB1ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, env->CSR_DB2ADDR); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, env->CSR_DB2MASK); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, env->CSR_DB2CTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, env->CSR_DB2ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, env->CSR_DB3ADDR); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, env->CSR_DB3MASK); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, env->CSR_DB3CTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, env->CSR_DB3ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPC, env->CSR_FWPC); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPS, env->CSR_FWPS); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, env->CSR_IB0ADDR); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, env->CSR_IB0MASK); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, env->CSR_IB0CTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, env->CSR_IB0ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, env->CSR_IB1ADDR); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, env->CSR_IB1MASK); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, env->CSR_IB1CTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, env->CSR_IB1ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, env->CSR_IB2ADDR); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, env->CSR_IB2MASK); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, env->CSR_IB2CTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, env->CSR_IB2ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, env->CSR_IB3ADDR); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, env->CSR_IB3MASK); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, env->CSR_IB3CTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, env->CSR_IB3ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, env->CSR_IB4ADDR); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, env->CSR_IB4MASK); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, env->CSR_IB4CTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, env->CSR_IB4ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, env->CSR_IB5ADDR); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, env->CSR_IB5MASK); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, env->CSR_IB5CTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, env->CSR_IB5ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, env->CSR_IB6ADDR); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, env->CSR_IB6MASK); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, env->CSR_IB6CTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, env->CSR_IB6ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, env->CSR_IB7ADDR); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, env->CSR_IB7MASK); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, env->CSR_IB7CTL); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, env->CSR_IB7ASID); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DEBUG, env->CSR_DEBUG); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DERA, env->CSR_DERA); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DESAVE, env->CSR_DESAVE); -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_SET_MSRS, cpu->kvm_msr_buf); -+ if (ret < cpu->kvm_msr_buf->ncsrs) { -+ struct kvm_csr_entry *e = &cpu->kvm_msr_buf->entries[ret]; -+ printf("error: failed to set CSR 0x%" PRIx32 " to 0x%" PRIx64"\n", -+ (uint32_t)e->index, (uint64_t)e->data); -+ } -+ -+ /* -+ * timer cfg must be put at last since it is used to enable -+ * guest timer -+ */ -+ ret |= KVM_PUT_ONE_UREG64(cs, LOONGARCH_CSR_TVAL, &env->CSR_TVAL); -+ ret |= KVM_PUT_ONE_UREG64(cs, LOONGARCH_CSR_TCFG, &env->CSR_TCFG); -+ return ret; -+} -+ -+#define KVM_GET_ONE_UREG64(cs, regidx, addr) \ -+ ({ \ -+ int err; \ -+ uint64_t csrid = 0; \ -+ csrid = (KVM_IOC_CSRID(regidx)); \ -+ err = kvm_larch_getq(cs, csrid, addr); \ -+ if (err < 0) { \ -+ DPRINTF("%s: Failed to put regidx 0x%x err:%d\n", __func__, regidx, err); \ -+ } \ -+ err; \ -+ }) -+ -+static int kvm_loongarch_get_csr_registers(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int ret = 0, i; -+ struct kvm_csr_entry *csrs = cpu->kvm_msr_buf->entries; -+ -+ kvm_msr_buf_reset(cpu); -+ -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CRMD, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRMD, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_EUEN, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_MISC, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ECFG, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ESTAT, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERA, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADV, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADI, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_EEPN, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GTLBC, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TRGP, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDH, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGD, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_RVACFG, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CPUID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS0, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS1, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS2, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS3, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS4, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS5, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS6, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS7, 0); -+ -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TMID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CNTC, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GSTAT, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCFG, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GINTC, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCNTC, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GNMI, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRENT, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRERA, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CTAG, 0); -+ -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, 0); -+ -+ /* debug */ -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPC, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPS, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPC, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPS, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DEBUG, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DERA, 0); -+ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DESAVE, 0); -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_GET_MSRS, cpu->kvm_msr_buf); -+ if (ret < cpu->kvm_msr_buf->ncsrs) { -+ struct kvm_csr_entry *e = &cpu->kvm_msr_buf->entries[ret]; -+ printf("error: failed to get CSR 0x%" PRIx32"\n", -+ (uint32_t)e->index); -+ } -+ -+ for (i = 0; i < ret; i++) { -+ uint32_t index = csrs[i].index; -+ -+ switch (index) { -+ case LOONGARCH_CSR_CRMD: -+ env->CSR_CRMD = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PRMD: -+ env->CSR_PRMD = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_EUEN: -+ env->CSR_EUEN = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_MISC: -+ env->CSR_MISC = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_ECFG: -+ env->CSR_ECFG = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_ESTAT: -+ env->CSR_ESTAT = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_ERA: -+ env->CSR_ERA = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_BADV: -+ env->CSR_BADV = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_BADI: -+ env->CSR_BADI = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_EEPN: -+ env->CSR_EEPN = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TLBIDX: -+ env->CSR_TLBIDX = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TLBEHI: -+ env->CSR_TLBEHI = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TLBELO0: -+ env->CSR_TLBELO0 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TLBELO1: -+ env->CSR_TLBELO1 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_GTLBC: -+ env->CSR_GTLBC = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TRGP: -+ env->CSR_TRGP = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_ASID: -+ env->CSR_ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PGDL: -+ env->CSR_PGDL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PGDH: -+ env->CSR_PGDH = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PGD: -+ env->CSR_PGD = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PWCTL0: -+ env->CSR_PWCTL0 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PWCTL1: -+ env->CSR_PWCTL1 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_STLBPGSIZE: -+ env->CSR_STLBPGSIZE = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_RVACFG: -+ env->CSR_RVACFG = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_CPUID: -+ env->CSR_CPUID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PRCFG1: -+ env->CSR_PRCFG1 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PRCFG2: -+ env->CSR_PRCFG2 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PRCFG3: -+ env->CSR_PRCFG3 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_KS0: -+ env->CSR_KS0 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_KS1: -+ env->CSR_KS1 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_KS2: -+ env->CSR_KS2 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_KS3: -+ env->CSR_KS3 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_KS4: -+ env->CSR_KS4 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_KS5: -+ env->CSR_KS5 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_KS6: -+ env->CSR_KS6 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_KS7: -+ env->CSR_KS7 = csrs[i].data; -+ break; -+ -+ case LOONGARCH_CSR_TMID: -+ env->CSR_TMID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_CNTC: -+ env->CSR_CNTC = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TINTCLR: -+ env->CSR_TINTCLR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_GSTAT: -+ env->CSR_GSTAT = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_GCFG: -+ env->CSR_GCFG = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_GINTC: -+ env->CSR_GINTC = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_GCNTC: -+ env->CSR_GCNTC = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_LLBCTL: -+ env->CSR_LLBCTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IMPCTL1: -+ env->CSR_IMPCTL1 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IMPCTL2: -+ env->CSR_IMPCTL2 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_GNMI: -+ env->CSR_GNMI = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TLBRENT: -+ env->CSR_TLBRENT = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TLBRBADV: -+ env->CSR_TLBRBADV = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TLBRERA: -+ env->CSR_TLBRERA = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TLBRSAVE: -+ env->CSR_TLBRSAVE = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TLBRELO0: -+ env->CSR_TLBRELO0 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TLBRELO1: -+ env->CSR_TLBRELO1 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TLBREHI: -+ env->CSR_TLBREHI = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_TLBRPRMD: -+ env->CSR_TLBRPRMD = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_ERRCTL: -+ env->CSR_ERRCTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_ERRINFO: -+ env->CSR_ERRINFO = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_ERRINFO1: -+ env->CSR_ERRINFO1 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_ERRENT: -+ env->CSR_ERRENT = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_ERRERA: -+ env->CSR_ERRERA = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_ERRSAVE: -+ env->CSR_ERRSAVE = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_CTAG: -+ env->CSR_CTAG = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DMWIN0: -+ env->CSR_DMWIN0 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DMWIN1: -+ env->CSR_DMWIN1 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DMWIN2: -+ env->CSR_DMWIN2 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DMWIN3: -+ env->CSR_DMWIN3 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PERFCTRL0: -+ env->CSR_PERFCTRL0 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PERFCNTR0: -+ env->CSR_PERFCNTR0 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PERFCTRL1: -+ env->CSR_PERFCTRL1 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PERFCNTR1: -+ env->CSR_PERFCNTR1 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PERFCTRL2: -+ env->CSR_PERFCTRL2 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PERFCNTR2: -+ env->CSR_PERFCNTR2 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PERFCTRL3: -+ env->CSR_PERFCTRL3 = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_PERFCNTR3: -+ env->CSR_PERFCNTR3 = csrs[i].data; -+ break; -+ -+ case LOONGARCH_CSR_MWPC: -+ env->CSR_MWPC = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_MWPS: -+ env->CSR_MWPS = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB0ADDR: -+ env->CSR_DB0ADDR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB0MASK: -+ env->CSR_DB0MASK = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB0CTL: -+ env->CSR_DB0CTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB0ASID: -+ env->CSR_DB0ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB1ADDR: -+ env->CSR_DB1ADDR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB1MASK: -+ env->CSR_DB1MASK = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB1CTL: -+ env->CSR_DB1CTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB1ASID: -+ env->CSR_DB1ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB2ADDR: -+ env->CSR_DB2ADDR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB2MASK: -+ env->CSR_DB2MASK = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB2CTL: -+ env->CSR_DB2CTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB2ASID: -+ env->CSR_DB2ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB3ADDR: -+ env->CSR_DB3ADDR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB3MASK: -+ env->CSR_DB3MASK = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB3CTL: -+ env->CSR_DB3CTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DB3ASID: -+ env->CSR_DB3ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_FWPC: -+ env->CSR_FWPC = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_FWPS: -+ env->CSR_FWPS = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB0ADDR: -+ env->CSR_IB0ADDR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB0MASK: -+ env->CSR_IB0MASK = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB0CTL: -+ env->CSR_IB0CTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB0ASID: -+ env->CSR_IB0ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB1ADDR: -+ env->CSR_IB1ADDR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB1MASK: -+ env->CSR_IB1MASK = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB1CTL: -+ env->CSR_IB1CTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB1ASID: -+ env->CSR_IB1ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB2ADDR: -+ env->CSR_IB2ADDR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB2MASK: -+ env->CSR_IB2MASK = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB2CTL: -+ env->CSR_IB2CTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB2ASID: -+ env->CSR_IB2ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB3ADDR: -+ env->CSR_IB3ADDR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB3MASK: -+ env->CSR_IB3MASK = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB3CTL: -+ env->CSR_IB3CTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB3ASID: -+ env->CSR_IB3ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB4ADDR: -+ env->CSR_IB4ADDR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB4MASK: -+ env->CSR_IB4MASK = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB4CTL: -+ env->CSR_IB4CTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB4ASID: -+ env->CSR_IB4ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB5ADDR: -+ env->CSR_IB5ADDR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB5MASK: -+ env->CSR_IB5MASK = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB5CTL: -+ env->CSR_IB5CTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB5ASID: -+ env->CSR_IB5ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB6ADDR: -+ env->CSR_IB6ADDR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB6MASK: -+ env->CSR_IB6MASK = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB6CTL: -+ env->CSR_IB6CTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB6ASID: -+ env->CSR_IB6ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB7ADDR: -+ env->CSR_IB7ADDR = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB7MASK: -+ env->CSR_IB7MASK = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB7CTL: -+ env->CSR_IB7CTL = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_IB7ASID: -+ env->CSR_IB7ASID = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DEBUG: -+ env->CSR_DEBUG = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DERA: -+ env->CSR_DERA = csrs[i].data; -+ break; -+ case LOONGARCH_CSR_DESAVE: -+ env->CSR_DESAVE = csrs[i].data; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ ret |= KVM_GET_ONE_UREG64(cs, LOONGARCH_CSR_TVAL, &env->CSR_TVAL); -+ ret |= KVM_GET_ONE_UREG64(cs, LOONGARCH_CSR_TCFG, &env->CSR_TCFG); -+ return ret; -+} -+ -+int kvm_loongarch_put_pvtime(LOONGARCHCPU *cpu) -+{ -+ CPULOONGARCHState *env = &cpu->env; -+ int err; -+ struct kvm_device_attr attr = { -+ .group = KVM_LARCH_VCPU_PVTIME_CTRL, -+ .attr = KVM_LARCH_VCPU_PVTIME_IPA, -+ .addr = (uint64_t)&env->st.guest_addr, -+ }; -+ -+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_HAS_DEVICE_ATTR, attr); -+ if (err != 0) { -+ /* It's ok even though kvm has not such attr */ -+ return 0; -+ } -+ -+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_DEVICE_ATTR, attr); -+ if (err != 0) { -+ error_report("PVTIME IPA: KVM_SET_DEVICE_ATTR: %s", strerror(-err)); -+ return err; -+ } -+ -+ return 0; -+} -+ -+int kvm_loongarch_get_pvtime(LOONGARCHCPU *cpu) -+{ -+ CPULOONGARCHState *env = &cpu->env; -+ int err; -+ struct kvm_device_attr attr = { -+ .group = KVM_LARCH_VCPU_PVTIME_CTRL, -+ .attr = KVM_LARCH_VCPU_PVTIME_IPA, -+ .addr = (uint64_t)&env->st.guest_addr, -+ }; -+ -+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_HAS_DEVICE_ATTR, attr); -+ if (err != 0) { -+ /* It's ok even though kvm has not such attr */ -+ return 0; -+ } -+ -+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_DEVICE_ATTR, attr); -+ if (err != 0) { -+ error_report("PVTIME IPA: KVM_GET_DEVICE_ATTR: %s", strerror(-err)); -+ return err; -+ } -+ -+ return 0; -+} -+ -+int kvm_arch_put_registers(CPUState *cs, int level) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ struct kvm_regs regs; -+ int ret; -+ int i; -+ -+ /* Set the registers based on QEMU's view of things */ -+ for (i = 0; i < 32; i++) { -+ regs.gpr[i] = (int64_t)(target_long)env->active_tc.gpr[i]; -+ } -+ -+ regs.pc = (int64_t)(target_long)env->active_tc.PC; -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s); -+ -+ if (ret < 0) { -+ return ret; -+ } -+ -+ ret = kvm_loongarch_put_csr_registers(cs, level); -+ if (ret < 0) { -+ return ret; -+ } -+ -+ ret = kvm_loongarch_put_fpu_registers(cs, level); -+ if (ret < 0) { -+ return ret; -+ } -+ -+ return ret; -+} -+ -+int kvm_arch_get_registers(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int ret = 0; -+ struct kvm_regs regs; -+ int i; -+ -+ /* Get the current register set as KVM seems it */ -+ ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, ®s); -+ -+ if (ret < 0) { -+ return ret; -+ } -+ -+ for (i = 0; i < 32; i++) { -+ env->active_tc.gpr[i] = regs.gpr[i]; -+ } -+ -+ env->active_tc.PC = regs.pc; -+ -+ kvm_loongarch_get_csr_registers(cs); -+ kvm_loongarch_get_fpu_registers(cs); -+ -+ return ret; -+} -+ -+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, -+ uint64_t address, uint32_t data, PCIDevice *dev) -+{ -+ return 0; -+} -+ -+int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, -+ int vector, PCIDevice *dev) -+{ -+ return 0; -+} -+ -+bool kvm_arch_cpu_check_are_resettable(void) -+{ -+ return true; -+} -+ -+int kvm_arch_release_virq_post(int virq) -+{ -+ return 0; -+} -+ -+int kvm_arch_msi_data_to_gsi(uint32_t data) -+{ -+ abort(); -+} -diff --git a/target/loongarch64/kvm_larch.h b/target/loongarch64/kvm_larch.h -new file mode 100644 -index 000000000..a56026d10 ---- /dev/null -+++ b/target/loongarch64/kvm_larch.h -@@ -0,0 +1,41 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * KVM/LOONGARCH: LOONGARCH specific KVM APIs -+ * -+ * Copyright (C) 2012-2014 Imagination Technologies Ltd. -+ * Authors: Sanjay Lal -+*/ -+ -+#ifndef KVM_LOONGARCH_H -+#define KVM_LOONGARCH_H -+ -+/** -+ * kvm_loongarch_reset_vcpu: -+ * @cpu: LOONGARCHCPU -+ * -+ * Called at reset time to set kernel registers to their initial values. -+ */ -+void kvm_loongarch_reset_vcpu(LOONGARCHCPU *cpu); -+ -+int kvm_loongarch_set_interrupt(LOONGARCHCPU *cpu, int irq, int level); -+int kvm_loongarch_set_ipi_interrupt(LOONGARCHCPU *cpu, int irq, int level); -+ -+int kvm_loongarch_put_pvtime(LOONGARCHCPU *cpu); -+int kvm_loongarch_get_pvtime(LOONGARCHCPU *cpu); -+ -+#ifndef KVM_INTERRUPT_SET -+#define KVM_INTERRUPT_SET -1 -+#endif -+ -+#ifndef KVM_INTERRUPT_UNSET -+#define KVM_INTERRUPT_UNSET -2 -+#endif -+ -+#ifndef KVM_INTERRUPT_SET_LEVEL -+#define KVM_INTERRUPT_SET_LEVEL -3 -+#endif -+ -+#endif /* KVM_LOONGARCH_H */ -diff --git a/target/loongarch64/larch-defs.h b/target/loongarch64/larch-defs.h -new file mode 100644 -index 000000000..d3a61cf25 ---- /dev/null -+++ b/target/loongarch64/larch-defs.h -@@ -0,0 +1,27 @@ -+#ifndef QEMU_LOONGARCH_DEFS_H -+#define QEMU_LOONGARCH_DEFS_H -+ -+/* If we want to use host float regs... */ -+/* #define USE_HOST_FLOAT_REGS */ -+ -+/* Real pages are variable size... */ -+#define TARGET_PAGE_BITS 14 -+ -+#define LOONGARCH_TLB_MAX 2112 -+ -+#define TARGET_LONG_BITS 64 -+#define TARGET_PHYS_ADDR_SPACE_BITS 48 -+#define TARGET_VIRT_ADDR_SPACE_BITS 48 -+ -+/* -+ * bit definitions for insn_flags (ISAs/ASEs flags) -+ * ------------------------------------------------ -+ */ -+#define ISA_LARCH32 0x00000001ULL -+#define ISA_LARCH64 0x00000002ULL -+#define INSN_LOONGARCH 0x00010000ULL -+ -+#define CPU_LARCH32 (ISA_LARCH32) -+#define CPU_LARCH64 (ISA_LARCH32 | ISA_LARCH64) -+ -+#endif /* QEMU_LOONGARCH_DEFS_H */ -diff --git a/target/loongarch64/machine.c b/target/loongarch64/machine.c -new file mode 100644 -index 000000000..b69bca6a9 ---- /dev/null -+++ b/target/loongarch64/machine.c -@@ -0,0 +1,416 @@ -+#include "qemu/osdep.h" -+#include "qemu-common.h" -+#include "cpu.h" -+#include "internal.h" -+#include "hw/hw.h" -+#include "kvm_larch.h" -+#include "migration/cpu.h" -+#include "linux/kvm.h" -+#include "sysemu/kvm.h" -+#include "qemu/error-report.h" -+ -+static int cpu_post_load(void *opaque, int version_id) -+{ -+ LOONGARCHCPU *cpu = opaque; -+ CPULOONGARCHState *env = &cpu->env; -+ int r = 0; -+ -+#ifdef CONFIG_KVM -+ struct kvm_loongarch_vcpu_state vcpu_state; -+ int i; -+ -+ vcpu_state.online_vcpus = cpu->online_vcpus; -+ vcpu_state.is_migrate = cpu->is_migrate; -+ vcpu_state.cpu_freq = cpu->cpu_freq; -+ vcpu_state.count_ctl = cpu->count_ctl; -+ vcpu_state.pending_exceptions = cpu->pending_exceptions; -+ vcpu_state.pending_exceptions_clr = cpu->pending_exceptions_clr; -+ for (i = 0; i < 4; i++) { -+ vcpu_state.core_ext_ioisr[i] = cpu->core_ext_ioisr[i]; -+ } -+ r = kvm_vcpu_ioctl(CPU(cpu), KVM_LARCH_SET_VCPU_STATE, &vcpu_state); -+ if (r) { -+ error_report("set vcpu state failed %d", r); -+ } -+ -+ kvm_loongarch_put_pvtime(cpu); -+#endif -+ -+ restore_fp_status(env); -+ compute_hflags(env); -+ -+ return r; -+} -+ -+static int cpu_pre_save(void *opaque) -+{ -+#ifdef CONFIG_KVM -+ LOONGARCHCPU *cpu = opaque; -+ struct kvm_loongarch_vcpu_state vcpu_state; -+ int i, r = 0; -+ -+ r = kvm_vcpu_ioctl(CPU(cpu), KVM_LARCH_GET_VCPU_STATE, &vcpu_state); -+ if (r < 0) { -+ error_report("get vcpu state failed %d", r); -+ return r; -+ } -+ -+ cpu->online_vcpus = vcpu_state.online_vcpus; -+ cpu->is_migrate = vcpu_state.is_migrate; -+ cpu->cpu_freq = vcpu_state.cpu_freq; -+ cpu->count_ctl = vcpu_state.count_ctl; -+ cpu->pending_exceptions = vcpu_state.pending_exceptions; -+ cpu->pending_exceptions_clr = vcpu_state.pending_exceptions_clr; -+ for (i = 0; i < 4; i++) { -+ cpu->core_ext_ioisr[i] = vcpu_state.core_ext_ioisr[i]; -+ } -+ -+ kvm_loongarch_get_pvtime(cpu); -+#endif -+ return 0; -+} -+ -+/* FPU state */ -+ -+static int get_fpr(QEMUFile *f, void *pv, size_t size, -+ const VMStateField *field) -+{ -+ fpr_t *v = pv; -+ qemu_get_be64s(f, &v->d); -+ return 0; -+} -+ -+static int put_fpr(QEMUFile *f, void *pv, size_t size, -+ const VMStateField *field, JSONWriter *vmdesc) -+{ -+ fpr_t *v = pv; -+ qemu_put_be64s(f, &v->d); -+ return 0; -+} -+ -+const VMStateInfo vmstate_info_fpr = { -+ .name = "fpr", -+ .get = get_fpr, -+ .put = put_fpr, -+}; -+ -+#define VMSTATE_FPR_ARRAY_V(_f, _s, _n, _v) \ -+ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_fpr, fpr_t) -+ -+#define VMSTATE_FPR_ARRAY(_f, _s, _n) \ -+ VMSTATE_FPR_ARRAY_V(_f, _s, _n, 0) -+ -+static VMStateField vmstate_fpu_fields[] = { -+ VMSTATE_FPR_ARRAY(fpr, CPULOONGARCHFPUContext, 32), -+ VMSTATE_UINT32(fcsr0, CPULOONGARCHFPUContext), -+ VMSTATE_END_OF_LIST() -+}; -+ -+const VMStateDescription vmstate_fpu = { -+ .name = "cpu/fpu", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = vmstate_fpu_fields -+}; -+ -+const VMStateDescription vmstate_inactive_fpu = { -+ .name = "cpu/inactive_fpu", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = vmstate_fpu_fields -+}; -+ -+/* TC state */ -+ -+static VMStateField vmstate_tc_fields[] = { -+ VMSTATE_UINTTL_ARRAY(gpr, TCState, 32), -+ VMSTATE_UINTTL(PC, TCState), -+ VMSTATE_END_OF_LIST() -+}; -+ -+const VMStateDescription vmstate_tc = { -+ .name = "cpu/tc", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = vmstate_tc_fields -+}; -+ -+const VMStateDescription vmstate_inactive_tc = { -+ .name = "cpu/inactive_tc", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = vmstate_tc_fields -+}; -+ -+/* TLB state */ -+ -+static int get_tlb(QEMUFile *f, void *pv, size_t size, -+ const VMStateField *field) -+{ -+ ls3a5k_tlb_t *v = pv; -+ uint32_t flags; -+ -+ qemu_get_betls(f, &v->VPN); -+ qemu_get_be64s(f, &v->PageMask); -+ qemu_get_be32s(f, &v->PageSize); -+ qemu_get_be16s(f, &v->ASID); -+ qemu_get_be32s(f, &flags); -+ v->RPLV1 = (flags >> 21) & 1; -+ v->RPLV0 = (flags >> 20) & 1; -+ v->PLV1 = (flags >> 18) & 3; -+ v->PLV0 = (flags >> 16) & 3; -+ v->EHINV = (flags >> 15) & 1; -+ v->RI1 = (flags >> 14) & 1; -+ v->RI0 = (flags >> 13) & 1; -+ v->XI1 = (flags >> 12) & 1; -+ v->XI0 = (flags >> 11) & 1; -+ v->WE1 = (flags >> 10) & 1; -+ v->WE0 = (flags >> 9) & 1; -+ v->V1 = (flags >> 8) & 1; -+ v->V0 = (flags >> 7) & 1; -+ v->C1 = (flags >> 4) & 7; -+ v->C0 = (flags >> 1) & 7; -+ v->G = (flags >> 0) & 1; -+ qemu_get_be64s(f, &v->PPN0); -+ qemu_get_be64s(f, &v->PPN1); -+ -+ return 0; -+} -+ -+static int put_tlb(QEMUFile *f, void *pv, size_t size, -+ const VMStateField *field, JSONWriter *vmdesc) -+{ -+ ls3a5k_tlb_t *v = pv; -+ -+ uint16_t asid = v->ASID; -+ uint32_t flags = ((v->RPLV1 << 21) | -+ (v->RPLV0 << 20) | -+ (v->PLV1 << 18) | -+ (v->PLV0 << 16) | -+ (v->EHINV << 15) | -+ (v->RI1 << 14) | -+ (v->RI0 << 13) | -+ (v->XI1 << 12) | -+ (v->XI0 << 11) | -+ (v->WE1 << 10) | -+ (v->WE0 << 9) | -+ (v->V1 << 8) | -+ (v->V0 << 7) | -+ (v->C1 << 4) | -+ (v->C0 << 1) | -+ (v->G << 0)); -+ -+ qemu_put_betls(f, &v->VPN); -+ qemu_put_be64s(f, &v->PageMask); -+ qemu_put_be32s(f, &v->PageSize); -+ qemu_put_be16s(f, &asid); -+ qemu_put_be32s(f, &flags); -+ qemu_put_be64s(f, &v->PPN0); -+ qemu_put_be64s(f, &v->PPN1); -+ -+ return 0; -+} -+ -+const VMStateInfo vmstate_info_tlb = { -+ .name = "tlb_entry", -+ .get = get_tlb, -+ .put = put_tlb, -+}; -+ -+#define VMSTATE_TLB_ARRAY_V(_f, _s, _n, _v) \ -+ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_tlb, ls3a5k_tlb_t) -+ -+#define VMSTATE_TLB_ARRAY(_f, _s, _n) \ -+ VMSTATE_TLB_ARRAY_V(_f, _s, _n, 0) -+ -+const VMStateDescription vmstate_tlb = { -+ .name = "cpu/tlb", -+ .version_id = 2, -+ .minimum_version_id = 2, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT32(nb_tlb, CPULOONGARCHTLBContext), -+ VMSTATE_UINT32(tlb_in_use, CPULOONGARCHTLBContext), -+ VMSTATE_TLB_ARRAY(mmu.ls3a5k.tlb, CPULOONGARCHTLBContext, LOONGARCH_TLB_MAX), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+/* LOONGARCH CPU state */ -+ -+const VMStateDescription vmstate_loongarch_cpu = { -+ .name = "cpu", -+ .version_id = 15, -+ .minimum_version_id = 15, -+ .post_load = cpu_post_load, -+ .pre_save = cpu_pre_save, -+ .fields = (VMStateField[]) { -+ /* Active TC */ -+ VMSTATE_STRUCT(env.active_tc, LOONGARCHCPU, 1, vmstate_tc, TCState), -+ -+ /* Active FPU */ -+ VMSTATE_STRUCT(env.active_fpu, LOONGARCHCPU, 1, vmstate_fpu, -+ CPULOONGARCHFPUContext), -+ -+ /* TLB */ -+ VMSTATE_STRUCT_POINTER(env.tlb, LOONGARCHCPU, vmstate_tlb, -+ CPULOONGARCHTLBContext), -+ /* CPU metastate */ -+ VMSTATE_UINT32(env.current_tc, LOONGARCHCPU), -+ VMSTATE_INT32(env.error_code, LOONGARCHCPU), -+ VMSTATE_UINTTL(env.btarget, LOONGARCHCPU), -+ VMSTATE_UINTTL(env.bcond, LOONGARCHCPU), -+ -+ VMSTATE_UINT64(env.lladdr, LOONGARCHCPU), -+ -+ /* PV time */ -+ VMSTATE_UINT64(env.st.guest_addr, LOONGARCHCPU), -+ -+ /* Remaining CSR registers */ -+ 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_EEPN, 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_TLBWIRED, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_GTLBC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TRGP, 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_PWCTL0, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PWCTL1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_STLBPGSIZE, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_RVACFG, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_CPUID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PRCFG1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PRCFG2, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PRCFG3, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS0, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS2, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS3, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS4, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS5, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS6, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS7, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TMID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TCFG, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TVAL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_CNTC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TINTCLR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_GSTAT, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_GCFG, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_GINTC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_GCNTC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_LLBCTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IMPCTL1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IMPCTL2, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_GNMI, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBRENT, 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_ERRCTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ERRINFO, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ERRINFO1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ERRENT, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ERRERA, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ERRSAVE, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_CTAG, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DMWIN0, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DMWIN1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DMWIN2, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DMWIN3, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCTRL0, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCNTR0, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCTRL1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCNTR1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCTRL2, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCNTR2, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCTRL3, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCNTR3, LOONGARCHCPU), -+ /* debug */ -+ VMSTATE_UINT64(env.CSR_MWPC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_MWPS, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB0ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB0MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB0CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB0ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB1ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB1MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB1CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB1ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB2ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB2MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB2CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB2ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB3ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB3MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB3CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB3ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_FWPC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_FWPS, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB0ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB0MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB0CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB0ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB1ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB1MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB1CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB1ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB2ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB2MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB2CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB2ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB3ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB3MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB3CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB3ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB4ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB4MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB4CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB4ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB5ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB5MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB5CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB5ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB6ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB6MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB6CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB6ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB7ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB7MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB7CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB7ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DEBUG, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DERA, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DESAVE, LOONGARCHCPU), -+ -+ VMSTATE_STRUCT_ARRAY(env.fpus, LOONGARCHCPU, LOONGARCH_FPU_MAX, 1, -+ vmstate_inactive_fpu, CPULOONGARCHFPUContext), -+ VMSTATE_UINT8(online_vcpus, LOONGARCHCPU), -+ VMSTATE_UINT8(is_migrate, LOONGARCHCPU), -+ VMSTATE_UINT64(counter_value, LOONGARCHCPU), -+ VMSTATE_UINT32(cpu_freq, LOONGARCHCPU), -+ VMSTATE_UINT32(count_ctl, LOONGARCHCPU), -+ VMSTATE_UINT64(pending_exceptions, LOONGARCHCPU), -+ VMSTATE_UINT64(pending_exceptions_clr, LOONGARCHCPU), -+ VMSTATE_UINT64_ARRAY(core_ext_ioisr, LOONGARCHCPU, 4), -+ -+ VMSTATE_END_OF_LIST() -+ }, -+}; -diff --git a/target/loongarch64/meson.build b/target/loongarch64/meson.build -new file mode 100644 -index 000000000..6badf4484 ---- /dev/null -+++ b/target/loongarch64/meson.build -@@ -0,0 +1,35 @@ -+loongarch_user_ss = ss.source_set() -+loongarch_softmmu_ss = ss.source_set() -+loongarch_ss = ss.source_set() -+loongarch_ss.add(files( -+ 'cpu.c', -+ 'fpu.c', -+ 'gdbstub.c', -+)) -+ -+gen = [ -+ decodetree.process('insn.decode', extra_args: [ '--decode', 'decode_insn', -+ '--insnwidth', '32' ]) -+] -+ -+loongarch_ss.add(gen) -+loongarch_ss.add(when: 'CONFIG_TCG', if_true: files( -+ 'helper.c', -+ 'translate.c', -+ 'op_helper.c', -+ 'fpu_helper.c', -+ 'tlb_helper.c', -+ 'csr_helper.c', -+)) -+ -+loongarch_softmmu_ss.add(when: 'CONFIG_SOFTMMU', if_true: files( -+ 'machine.c', -+ 'stabletimer.c', -+ 'arch_dump.c', -+)) -+ -+loongarch_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) -+ -+target_arch += {'loongarch64': loongarch_ss} -+target_softmmu_arch += {'loongarch64': loongarch_softmmu_ss} -+target_user_arch += {'loongarch64': loongarch_user_ss} -diff --git a/target/loongarch64/op_helper.c b/target/loongarch64/op_helper.c -new file mode 100644 -index 000000000..9a34c0d25 ---- /dev/null -+++ b/target/loongarch64/op_helper.c -@@ -0,0 +1,533 @@ -+/* -+ * LOONGARCH emulation helpers for qemu. -+ * -+ * Copyright (c) 2004-2005 Jocelyn Mayer -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+#include "qemu/osdep.h" -+#include "qemu/main-loop.h" -+#include "cpu.h" -+#include "internal.h" -+#include "qemu/host-utils.h" -+#include "exec/helper-proto.h" -+#include "exec/exec-all.h" -+#include "exec/cpu_ldst.h" -+#include "sysemu/kvm.h" -+#include "qemu/crc32c.h" -+#include -+#include "hw/irq.h" -+#include "hw/core/cpu.h" -+#include "instmap.h" -+ -+/*****************************************************************************/ -+/* Exceptions processing helpers */ -+ -+void helper_raise_exception_err(CPULOONGARCHState *env, uint32_t exception, -+ int error_code) -+{ -+ do_raise_exception_err(env, exception, error_code, 0); -+} -+ -+void helper_raise_exception(CPULOONGARCHState *env, uint32_t exception) -+{ -+ do_raise_exception(env, exception, GETPC()); -+} -+ -+void helper_raise_exception_debug(CPULOONGARCHState *env) -+{ -+ do_raise_exception(env, EXCP_DEBUG, 0); -+} -+ -+static void raise_exception(CPULOONGARCHState *env, uint32_t exception) -+{ -+ do_raise_exception(env, exception, 0); -+} -+ -+#if defined(CONFIG_USER_ONLY) -+#define HELPER_LD(name, insn, type) \ -+static inline type do_##name(CPULOONGARCHState *env, target_ulong addr, \ -+ int mem_idx, uintptr_t retaddr) \ -+{ \ -+ return (type) cpu_##insn##_data_ra(env, addr, retaddr); \ -+} -+#else -+ -+#define HF_SMAP_SHIFT 23 /* CR4.SMAP */ -+#define HF_SMAP_MASK (1 << HF_SMAP_SHIFT) -+#define MMU_KNOSMAP_IDX 2 -+#define HF_CPL_SHIFT 0 -+#define HF_CPL_MASK (3 << HF_CPL_SHIFT) -+#define AC_MASK 0x00040000 -+#define MMU_KSMAP_IDX 0 -+static inline int cpu_mmu_index_kernel(CPULOONGARCHState *env) -+{ -+ return !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP_IDX : -+ ((env->hflags & HF_CPL_MASK) < 3 && (env->hflags & AC_MASK)) -+ ? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX; -+} -+ -+#define cpu_ldl_kernel_ra(e, p, r) \ -+ cpu_ldl_mmuidx_ra(e, p, cpu_mmu_index_kernel(e), r) -+ -+#define HELPER_LD(name, insn, type) \ -+static inline type do_##name(CPULOONGARCHState *env, target_ulong addr, \ -+ int mem_idx, uintptr_t retaddr) \ -+{ \ -+/* \ -+ switch (mem_idx) { \ -+ case 0: return (type) cpu_##insn##_kernel_ra(env, addr, retaddr); \ -+ case 1: return (type) cpu_##insn##_super_ra(env, addr, retaddr); \ -+ default: \ -+ case 2: return (type) cpu_##insn##_user_ra(env, addr, retaddr); \ -+ case 3: return (type) cpu_##insn##_error_ra(env, addr, retaddr); \ -+ } \ -+*/ \ -+} -+#endif -+#if 0 -+HELPER_LD(lw, ldl, int32_t) -+HELPER_LD(ld, ldq, int64_t) -+#endif -+#undef HELPER_LD -+ -+#if defined(CONFIG_USER_ONLY) -+#define HELPER_ST(name, insn, type) \ -+static inline void do_##name(CPULOONGARCHState *env, target_ulong addr, \ -+ type val, int mem_idx, uintptr_t retaddr) \ -+{ \ -+/* \ -+ cpu_##insn##_data_ra(env, addr, val, retaddr); \ -+*/ \ -+} -+#else -+#define HELPER_ST(name, insn, type) \ -+static inline void do_##name(CPULOONGARCHState *env, target_ulong addr, \ -+ type val, int mem_idx, uintptr_t retaddr) \ -+{ \ -+/* \ -+ switch (mem_idx) { \ -+ case 0: \ -+ cpu_##insn##_kernel_ra(env, addr, val, retaddr); \ -+ break; \ -+ case 1: \ -+ cpu_##insn##_super_ra(env, addr, val, retaddr); \ -+ break; \ -+ default: \ -+ case 2: \ -+ cpu_##insn##_user_ra(env, addr, val, retaddr); \ -+ break; \ -+ case 3: \ -+ cpu_##insn##_error_ra(env, addr, val, retaddr); \ -+ break; \ -+ } \ -+*/ \ -+} -+#endif -+#if 0 -+HELPER_ST(sb, stb, uint8_t) -+HELPER_ST(sw, stl, uint32_t) -+HELPER_ST(sd, stq, uint64_t) -+#endif -+#undef HELPER_ST -+ -+static inline target_ulong bitswap(target_ulong v) -+{ -+ v = ((v >> 1) & (target_ulong)0x5555555555555555ULL) | -+ ((v & (target_ulong)0x5555555555555555ULL) << 1); -+ v = ((v >> 2) & (target_ulong)0x3333333333333333ULL) | -+ ((v & (target_ulong)0x3333333333333333ULL) << 2); -+ v = ((v >> 4) & (target_ulong)0x0F0F0F0F0F0F0F0FULL) | -+ ((v & (target_ulong)0x0F0F0F0F0F0F0F0FULL) << 4); -+ return v; -+} -+ -+target_ulong helper_dbitswap(target_ulong rt) -+{ -+ return bitswap(rt); -+} -+ -+target_ulong helper_bitswap(target_ulong rt) -+{ -+ return (int32_t)bitswap(rt); -+} -+ -+/* these crc32 functions are based on target/arm/helper-a64.c */ -+target_ulong helper_crc32(target_ulong val, target_ulong m, uint32_t sz) -+{ -+ uint8_t buf[8]; -+ target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1); -+ -+ m &= mask; -+ stq_le_p(buf, m); -+ return (int32_t) (crc32(val ^ 0xffffffff, buf, sz) ^ 0xffffffff); -+} -+ -+target_ulong helper_crc32c(target_ulong val, target_ulong m, uint32_t sz) -+{ -+ uint8_t buf[8]; -+ target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1); -+ m &= mask; -+ stq_le_p(buf, m); -+ return (int32_t) (crc32c(val, buf, sz) ^ 0xffffffff); -+} -+ -+#ifndef CONFIG_USER_ONLY -+ -+#define HELPER_LD_ATOMIC(name, insn, almask) \ -+target_ulong helper_##name(CPULOONGARCHState *env, target_ulong arg, int mem_idx) \ -+{ \ -+/* \ -+ if (arg & almask) { \ -+ env->CSR_BADV = arg; \ -+ do_raise_exception(env, EXCP_AdEL, GETPC()); \ -+ } \ -+ env->lladdr = arg; \ -+ env->llval = do_##insn(env, arg, mem_idx, GETPC()); \ -+ return env->llval; \ -+*/ \ -+} -+#if 0 -+HELPER_LD_ATOMIC(ll, lw, 0x3) -+HELPER_LD_ATOMIC(lld, ld, 0x7) -+#endif -+#undef HELPER_LD_ATOMIC -+#endif -+ -+#ifndef CONFIG_USER_ONLY -+void helper_drdtime(CPULOONGARCHState *env, target_ulong rd, target_ulong rs) -+{ -+ env->active_tc.gpr[rd] = cpu_loongarch_get_stable_counter(env); -+ env->active_tc.gpr[rs] = env->CSR_TMID; -+} -+#endif -+ -+#ifndef CONFIG_USER_ONLY -+static void debug_pre_ertn(CPULOONGARCHState *env) -+{ -+ if (qemu_loglevel_mask(CPU_LOG_EXEC)) { -+ qemu_log("ERTN: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx, -+ env->active_tc.PC, env->CSR_ERA); -+ qemu_log("\n"); -+ } -+} -+ -+static void debug_post_ertn(CPULOONGARCHState *env) -+{ -+ if (qemu_loglevel_mask(CPU_LOG_EXEC)) { -+ qemu_log("ERTN: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx, -+ env->active_tc.PC, env->CSR_ERA); -+ } -+} -+ -+static void set_pc(CPULOONGARCHState *env, target_ulong error_pc) -+{ -+ env->active_tc.PC = error_pc & ~(target_ulong)1; -+} -+ -+static inline void exception_return(CPULOONGARCHState *env) -+{ -+ debug_pre_ertn(env); -+ -+ if (cpu_refill_state(env)) { -+ env->CSR_CRMD &= (~0x7); -+ env->CSR_CRMD |= (env->CSR_TLBRPRMD & 0x7); -+ /* Clear Refill flag and set pc */ -+ env->CSR_TLBRERA &= (~0x1); -+ set_pc(env, env->CSR_TLBRERA); -+ if (qemu_loglevel_mask(CPU_LOG_INT)) { -+ qemu_log("%s: TLBRERA 0x%lx\n", __func__, env->CSR_TLBRERA); -+ } -+ } else { -+ env->CSR_CRMD &= (~0x7); -+ env->CSR_CRMD |= (env->CSR_PRMD & 0x7); -+ /* Clear Refill flag and set pc*/ -+ set_pc(env, env->CSR_ERA); -+ if (qemu_loglevel_mask(CPU_LOG_INT)) { -+ qemu_log("%s: ERA 0x%lx\n", __func__, env->CSR_ERA); -+ } -+ } -+ -+ compute_hflags(env); -+ debug_post_ertn(env); -+} -+ -+void helper_ertn(CPULOONGARCHState *env) -+{ -+ exception_return(env); -+ env->lladdr = 1; -+} -+ -+#endif /* !CONFIG_USER_ONLY */ -+ -+void helper_idle(CPULOONGARCHState *env) -+{ -+ CPUState *cs = CPU(loongarch_env_get_cpu(env)); -+ -+ cs->halted = 1; -+ cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE); -+ /* Last instruction in the block, PC was updated before -+ - no need to recover PC and icount */ -+ raise_exception(env, EXCP_HLT); -+} -+ -+#if !defined(CONFIG_USER_ONLY) -+ -+void loongarch_cpu_do_unaligned_access(CPUState *cs, vaddr addr, -+ MMUAccessType access_type, -+ int mmu_idx, uintptr_t retaddr) -+{ -+ while(1); -+} -+ -+#endif /* !CONFIG_USER_ONLY */ -+ -+void helper_store_scr(CPULOONGARCHState *env, uint32_t n, target_ulong val) -+{ -+ env->scr[n & 0x3] = val; -+} -+ -+target_ulong helper_load_scr(CPULOONGARCHState *env, uint32_t n) -+{ -+ return env->scr[n & 0x3]; -+} -+ -+/* loongarch assert op */ -+void helper_asrtle_d(CPULOONGARCHState *env, target_ulong rs, target_ulong rt) -+{ -+ if (rs > rt) { -+ do_raise_exception(env, EXCP_AdEL, GETPC()); -+ } -+} -+ -+void helper_asrtgt_d(CPULOONGARCHState *env, target_ulong rs, target_ulong rt) -+{ -+ if (rs <= rt) { -+ do_raise_exception(env, EXCP_AdEL, GETPC()); -+ } -+} -+ -+target_ulong helper_cto_w(CPULOONGARCHState *env, target_ulong a0) -+{ -+ uint32_t v = (uint32_t)a0; -+ int temp = 0; -+ -+ while ((v & 0x1) == 1) { -+ temp++; -+ v = v >> 1; -+ } -+ -+ return (target_ulong)temp; -+} -+ -+target_ulong helper_ctz_w(CPULOONGARCHState *env, target_ulong a0) -+{ -+ uint32_t v = (uint32_t)a0; -+ -+ if (v == 0) { -+ return 32; -+ } -+ -+ int temp = 0; -+ while ((v & 0x1) == 0) { -+ temp++; -+ v = v >> 1; -+ } -+ -+ return (target_ulong)temp; -+} -+ -+target_ulong helper_cto_d(CPULOONGARCHState *env, target_ulong a0) -+{ -+ uint64_t v = a0; -+ int temp = 0; -+ -+ while ((v & 0x1) == 1) { -+ temp++; -+ v = v >> 1; -+ } -+ -+ return (target_ulong)temp; -+} -+ -+target_ulong helper_ctz_d(CPULOONGARCHState *env, target_ulong a0) -+{ -+ uint64_t v = a0; -+ -+ if (v == 0) { -+ return 64; -+ } -+ -+ int temp = 0; -+ while ((v & 0x1) == 0) { -+ temp++; -+ v = v >> 1; -+ } -+ -+ return (target_ulong)temp; -+} -+ -+target_ulong helper_bitrev_w(CPULOONGARCHState *env, target_ulong a0) -+{ -+ int32_t v = (int32_t)a0; -+ const int SIZE = 32; -+ uint8_t bytes[SIZE]; -+ -+ int i; -+ for (i = 0; i < SIZE; i++) { -+ bytes[i] = v & 0x1; -+ v = v >> 1; -+ } -+ /* v == 0 */ -+ for (i = 0; i < SIZE; i++) { -+ v = v | ((uint32_t)bytes[i] << (SIZE - 1 - i)); -+ } -+ -+ return (target_ulong)(int32_t)v; -+} -+ -+target_ulong helper_bitrev_d(CPULOONGARCHState *env, target_ulong a0) -+{ -+ uint64_t v = a0; -+ const int SIZE = 64; -+ uint8_t bytes[SIZE]; -+ -+ int i; -+ for (i = 0; i < SIZE; i++) { -+ bytes[i] = v & 0x1; -+ v = v >> 1; -+ } -+ /* v == 0 */ -+ for (i = 0; i < SIZE; i++) { -+ v = v | ((uint64_t)bytes[i] << (SIZE - 1 - i)); -+ } -+ -+ return (target_ulong)v; -+} -+ -+void helper_memtrace_addr(CPULOONGARCHState *env, -+ target_ulong address, uint32_t op) -+{ -+ qemu_log("[cpu %d asid 0x%lx pc 0x%lx] addr 0x%lx op", -+ CPU(loongarch_env_get_cpu(env))->cpu_index, -+ env->CSR_ASID, env->active_tc.PC, address); -+ switch (op) { -+ case OPC_LARCH_LDPTR_D: -+ qemu_log("OPC_LARCH_LDPTR_D"); -+ break; -+ case OPC_LARCH_LD_D: -+ qemu_log("OPC_LARCH_LD_D"); -+ break; -+ case OPC_LARCH_LDPTR_W: -+ qemu_log("OPC_LARCH_LDPTR_W"); -+ break; -+ case OPC_LARCH_LD_W: -+ qemu_log("OPC_LARCH_LD_W"); -+ break; -+ case OPC_LARCH_LD_H: -+ qemu_log("OPC_LARCH_LD_H"); -+ break; -+ case OPC_LARCH_LD_B: -+ qemu_log("OPC_LARCH_LD_B"); -+ break; -+ case OPC_LARCH_LD_WU: -+ qemu_log("OPC_LARCH_LD_WU"); -+ break; -+ case OPC_LARCH_LD_HU: -+ qemu_log("OPC_LARCH_LD_HU"); -+ break; -+ case OPC_LARCH_LD_BU: -+ qemu_log("OPC_LARCH_LD_BU"); -+ break; -+ case OPC_LARCH_STPTR_D: -+ qemu_log("OPC_LARCH_STPTR_D"); -+ break; -+ case OPC_LARCH_ST_D: -+ qemu_log("OPC_LARCH_ST_D"); -+ break; -+ case OPC_LARCH_STPTR_W: -+ qemu_log("OPC_LARCH_STPTR_W"); -+ break; -+ case OPC_LARCH_ST_W: -+ qemu_log("OPC_LARCH_ST_W"); -+ break; -+ case OPC_LARCH_ST_H: -+ qemu_log("OPC_LARCH_ST_H"); -+ break; -+ case OPC_LARCH_ST_B: -+ qemu_log("OPC_LARCH_ST_B"); -+ break; -+ case OPC_LARCH_FLD_S: -+ qemu_log("OPC_LARCH_FLD_S"); -+ break; -+ case OPC_LARCH_FLD_D: -+ qemu_log("OPC_LARCH_FLD_D"); -+ break; -+ case OPC_LARCH_FST_S: -+ qemu_log("OPC_LARCH_FST_S"); -+ break; -+ case OPC_LARCH_FST_D: -+ qemu_log("OPC_LARCH_FST_D"); -+ break; -+ case OPC_LARCH_FLDX_S: -+ qemu_log("OPC_LARCH_FLDX_S"); -+ break; -+ case OPC_LARCH_FLDGT_S: -+ qemu_log("OPC_LARCH_FLDGT_S"); -+ break; -+ case OPC_LARCH_FLDLE_S: -+ qemu_log("OPC_LARCH_FLDLE_S"); -+ break;; -+ case OPC_LARCH_FSTX_S: -+ qemu_log("OPC_LARCH_FSTX_S"); -+ break; -+ case OPC_LARCH_FSTGT_S: -+ qemu_log("OPC_LARCH_FSTGT_S"); -+ break; -+ case OPC_LARCH_FSTLE_S: -+ qemu_log("OPC_LARCH_FSTLE_S"); -+ break; -+ case OPC_LARCH_FLDX_D: -+ qemu_log("OPC_LARCH_FLDX_D"); -+ break; -+ case OPC_LARCH_FLDGT_D: -+ qemu_log("OPC_LARCH_FLDGT_D"); -+ break; -+ case OPC_LARCH_FLDLE_D: -+ qemu_log("OPC_LARCH_FLDLE_D"); -+ break;; -+ case OPC_LARCH_FSTX_D: -+ qemu_log("OPC_LARCH_FSTX_D"); -+ break; -+ case OPC_LARCH_FSTGT_D: -+ qemu_log("OPC_LARCH_FSTGT_D"); -+ break; -+ case OPC_LARCH_FSTLE_D: -+ qemu_log("OPC_LARCH_FSTLE_D"); -+ break; -+ case OPC_LARCH_LL_W: -+ qemu_log("OPC_LARCH_LL_W"); -+ break; -+ case OPC_LARCH_LL_D: -+ qemu_log("OPC_LARCH_LL_D"); -+ break; -+ default: -+ qemu_log("0x%x", op); -+ } -+} -+ -+void helper_memtrace_val(CPULOONGARCHState *env, target_ulong val) -+{ -+ qemu_log("val 0x%lx\n", val); -+} -diff --git a/target/loongarch64/stabletimer.c b/target/loongarch64/stabletimer.c -new file mode 100644 -index 000000000..b86fecf89 ---- /dev/null -+++ b/target/loongarch64/stabletimer.c -@@ -0,0 +1,122 @@ -+/* -+ * QEMU LOONGARCH timer support -+ * -+ * 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 "hw/loongarch/cpudevs.h" -+#include "qemu/timer.h" -+#include "sysemu/kvm.h" -+#include "internal.h" -+#include "hw/irq.h" -+ -+ -+#ifdef DEBUG_TIMER -+#define debug_timer(fmt, args...) printf("%s(%d)-%s -> " #fmt "\n", \ -+ __FILE__, __LINE__, __func__, ##args); -+#else -+#define debug_timer(fmt, args...) -+#endif -+ -+#define TIMER_PERIOD 10 /* 10 ns period for 100 Mhz frequency */ -+#define STABLETIMER_TICK_MASK 0xfffffffffffcUL -+#define STABLETIMER_ENABLE 0x1UL -+#define STABLETIMER_PERIOD 0x2UL -+ -+/* return random value in [low, high] */ -+uint32_t cpu_loongarch_get_random_ls3a5k_tlb(uint32_t low, uint32_t high) -+{ -+ static uint32_t seed = 5; -+ static uint32_t prev_idx; -+ uint32_t idx; -+ uint32_t nb_rand_tlb = high - low + 1; -+ -+ do { -+ seed = 1103515245 * seed + 12345; -+ idx = (seed >> 16) % nb_rand_tlb + low; -+ } while (idx == prev_idx); -+ prev_idx = idx; -+ -+ return idx; -+} -+ -+/* LOONGARCH timer */ -+uint64_t cpu_loongarch_get_stable_counter(CPULOONGARCHState *env) -+{ -+ return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / TIMER_PERIOD; -+} -+ -+uint64_t cpu_loongarch_get_stable_timer_ticks(CPULOONGARCHState *env) -+{ -+ uint64_t now, expire; -+ -+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); -+ expire = timer_expire_time_ns(env->timer); -+ -+ return (expire - now) / TIMER_PERIOD; -+} -+ -+void cpu_loongarch_store_stable_timer_config(CPULOONGARCHState *env, -+ uint64_t value) -+{ -+ uint64_t now, next; -+ -+ env->CSR_TCFG = value; -+ if (value & STABLETIMER_ENABLE) { -+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); -+ next = now + (value & STABLETIMER_TICK_MASK) * TIMER_PERIOD; -+ timer_mod(env->timer, next); -+ } -+ debug_timer("0x%lx 0x%lx now 0x%lx, next 0x%lx", -+ value, env->CSR_TCFG, now, next); -+} -+ -+static void loongarch_stable_timer_cb(void *opaque) -+{ -+ CPULOONGARCHState *env; -+ uint64_t now, next; -+ -+ env = opaque; -+ debug_timer(); -+ if (env->CSR_TCFG & STABLETIMER_PERIOD) { -+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); -+ next = now + (env->CSR_TCFG & STABLETIMER_TICK_MASK) * TIMER_PERIOD; -+ timer_mod(env->timer, next); -+ } else { -+ env->CSR_TCFG &= ~STABLETIMER_ENABLE; -+ } -+ -+ qemu_irq_raise(env->irq[IRQ_TIMER]); -+ -+} -+ -+void cpu_loongarch_clock_init(LOONGARCHCPU *cpu) -+{ -+ CPULOONGARCHState *env = &cpu->env; -+ -+ /* -+ * If we're in KVM mode, don't create the periodic timer, that is handled in -+ * kernel. -+ */ -+ if (!kvm_enabled()) { -+ env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, -+ &loongarch_stable_timer_cb, env); -+ } -+} -diff --git a/target/loongarch64/tlb_helper.c b/target/loongarch64/tlb_helper.c -new file mode 100644 -index 000000000..f5e68349a ---- /dev/null -+++ b/target/loongarch64/tlb_helper.c -@@ -0,0 +1,729 @@ -+/* -+ * loongarch tlb emulation helpers for qemu. -+ * -+ * Copyright (c) 2020 -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+#include "qemu/osdep.h" -+#include "qemu/main-loop.h" -+#include "cpu.h" -+#include "internal.h" -+#include "qemu/host-utils.h" -+#include "exec/helper-proto.h" -+#include "exec/exec-all.h" -+#include "exec/cpu_ldst.h" -+ -+#ifndef CONFIG_USER_ONLY -+ -+#define HELPER_LD(name, insn, type) \ -+static inline type do_##name(CPULOONGARCHState *env, target_ulong addr, \ -+ int mem_idx, uintptr_t retaddr) \ -+{ \ -+/* \ -+ switch (mem_idx) { \ -+ case 0: return (type) cpu_##insn##_kernel_ra(env, addr, retaddr); \ -+ case 1: return (type) cpu_##insn##_super_ra(env, addr, retaddr); \ -+ default: \ -+ case 2: return (type) cpu_##insn##_user_ra(env, addr, retaddr); \ -+ case 3: return (type) cpu_##insn##_error_ra(env, addr, retaddr); \ -+ } \ -+*/ \ -+} -+#if 0 -+HELPER_LD(lw, ldl, int32_t) -+HELPER_LD(ld, ldq, int64_t) -+#endif -+ -+void helper_lddir(CPULOONGARCHState *env, target_ulong base, target_ulong rt, -+ target_ulong level, uint32_t mem_idx) -+{ -+#if 0 -+ target_ulong pointer = env->active_tc.gpr[base]; -+ target_ulong badvaddr; -+ target_ulong index; -+ target_ulong vaddr; -+ int shift; -+ -+ badvaddr = env->CSR_TLBRBADV; -+ -+ /* 0:8B, 1:16B, 2:32B, 3:64B */ -+ shift = (env->CSR_PWCTL0 >> 30) & 0x3; -+ shift = (shift + 1) * 3; -+ -+ switch (level) { -+ case 1: -+ index = (badvaddr >> ((env->CSR_PWCTL0 >> 10) & 0x1f)) & \ -+ ((1 << ((env->CSR_PWCTL0 >> 15) & 0x1f)) - 1); -+ break; -+ case 3: -+ index = (badvaddr >> ((env->CSR_PWCTL1 >> 0) & 0x3f)) & \ -+ ((1 << ((env->CSR_PWCTL1 >> 6) & 0x3f)) - 1); -+ break; -+ default: -+ do_raise_exception(env, EXCP_RI, GETPC()); -+ return; -+ } -+ -+ vaddr = pointer | index << shift; -+ env->active_tc.gpr[rt] = do_ld(env, vaddr, mem_idx, GETPC()); -+ return; -+#endif -+} -+ -+void helper_ldpte(CPULOONGARCHState *env, target_ulong base, target_ulong odd, -+ uint32_t mem_idx) -+{ -+#if 0 -+ target_ulong pointer = env->active_tc.gpr[base]; -+ target_ulong vaddr; -+ target_ulong tmp0 = 1; -+ target_ulong ptindex, ptoffset0, ptoffset1; -+ target_ulong pagesize; -+ target_ulong badv; -+ int shift; -+ bool huge = pointer & LOONGARCH_PAGE_HUGE; -+ -+ if (huge) { -+ /* Huge Page. pointer is paddr */ -+ tmp0 = pointer ^ LOONGARCH_PAGE_HUGE; -+ /* move Global bit */ -+ tmp0 |= ((tmp0 & LOONGARCH_HUGE_GLOBAL) -+ >> (LOONGARCH_HUGE_GLOBAL_SH - CSR_TLBLO0_GLOBAL_SHIFT)); -+ pagesize = (env->CSR_PWCTL0 & 0x1f) + -+ ((env->CSR_PWCTL0 >> 5) & 0x1f) - 1; -+ if (odd) { -+ tmp0 += (1 << pagesize); -+ } -+ } else { -+ /* 0:8B, 1:16B, 2:32B, 3:64B */ -+ shift = (env->CSR_PWCTL0 >> 30) & 0x3; -+ shift = (shift + 1) * 3; -+ badv = env->CSR_TLBRBADV; -+ -+ ptindex = (badv >> (env->CSR_PWCTL0 & 0x1f)) & -+ ((1 << ((env->CSR_PWCTL0 >> 5) & 0x1f)) - 1); -+ ptindex = ptindex & ~0x1; /* clear bit 0 */ -+ ptoffset0 = ptindex << shift; -+ ptoffset1 = (ptindex + 1) << shift; -+ -+ vaddr = pointer | (odd ? ptoffset1 : ptoffset0); -+ tmp0 = do_ld(env, vaddr, mem_idx, GETPC()); -+ pagesize = (env->CSR_PWCTL0 & 0x1f); -+ } -+ if (odd) { -+ env->CSR_TLBRELO1 = tmp0; -+ } else { -+ env->CSR_TLBRELO0 = tmp0; -+ } -+ env->CSR_TLBREHI = env->CSR_TLBREHI & (~0x3f); -+ env->CSR_TLBREHI = env->CSR_TLBREHI | pagesize; -+#endif -+ return; -+} -+ -+target_ulong helper_read_pgd(CPULOONGARCHState *env) -+{ -+ uint64_t badv; -+ -+ assert(env->CSR_TLBRERA & 0x1); -+ -+ if (env->CSR_TLBRERA & 0x1) { -+ badv = env->CSR_TLBRBADV; -+ } else { -+ badv = env->CSR_BADV; -+ } -+ -+ if ((badv >> 63) & 0x1) { -+ return env->CSR_PGDH; -+ } else { -+ return env->CSR_PGDL; -+ } -+} -+ -+/* TLB management */ -+static uint64_t ls3a5k_pagesize_to_mask(int pagesize) -+{ -+ /* 4KB - 1GB */ -+ if (pagesize < 12 && pagesize > 30) { -+ printf("[ERROR] unsupported page size %d\n", pagesize); -+ exit(-1); -+ } -+ -+ return (1 << (pagesize + 1)) - 1; -+} -+ -+static void ls3a5k_fill_tlb_entry(CPULOONGARCHState *env, -+ ls3a5k_tlb_t *tlb, int is_ftlb) -+{ -+ uint64_t page_mask; /* 0000...00001111...1111 */ -+ uint32_t page_size; -+ uint64_t entryhi; -+ uint64_t lo0, lo1; -+ -+ if (env->CSR_TLBRERA & 0x1) { -+ page_size = env->CSR_TLBREHI & 0x3f; -+ entryhi = env->CSR_TLBREHI; -+ lo0 = env->CSR_TLBRELO0; -+ lo1 = env->CSR_TLBRELO1; -+ } else { -+ page_size = (env->CSR_TLBIDX >> CSR_TLBIDX_PS_SHIFT) & 0x3f; -+ entryhi = env->CSR_TLBEHI; -+ lo0 = env->CSR_TLBELO0; -+ lo1 = env->CSR_TLBELO1; -+ } -+ -+ if (page_size == 0) { -+ printf("Warning: page_size is 0\n"); -+ } -+ -+ /* 15-12 11-8 7-4 3-0 -+ * 4KB: 0001 1111 1111 1111 // double 4KB mask [12:0] -+ * 16KB: 0111 1111 1111 1111 // double 16KB mask [14:0] -+ */ -+ if (is_ftlb) { -+ page_mask = env->tlb->mmu.ls3a5k.ftlb_mask; -+ } else { -+ page_mask = ls3a5k_pagesize_to_mask(page_size); -+ } -+ -+ tlb->VPN = entryhi & 0xffffffffe000 & ~page_mask; -+ -+ tlb->ASID = env->CSR_ASID & 0x3ff; /* CSR_ASID[9:0] */ -+ tlb->EHINV = 0; -+ tlb->G = (lo0 >> CSR_TLBLO0_GLOBAL_SHIFT) & /* CSR_TLBLO[6] */ -+ (lo1 >> CSR_TLBLO1_GLOBAL_SHIFT) & 1; -+ -+ tlb->PageMask = page_mask; -+ tlb->PageSize = page_size; -+ -+ tlb->V0 = (lo0 >> CSR_TLBLO0_V_SHIFT) & 0x1; /* [0] */ -+ tlb->WE0 = (lo0 >> CSR_TLBLO0_WE_SHIFT) & 0x1; /* [1] */ -+ tlb->PLV0 = (lo0 >> CSR_TLBLO0_PLV_SHIFT) & 0x3; /* [3:2] */ -+ tlb->C0 = (lo0 >> CSR_TLBLO0_CCA_SHIFT) & 0x3; /* [5:4] */ -+ tlb->PPN0 = (lo0 & 0xfffffffff000 & ~(page_mask >> 1)); -+ tlb->RI0 = (lo0 >> CSR_TLBLO0_RI_SHIFT) & 0x1; /* [61] */ -+ tlb->XI0 = (lo0 >> CSR_TLBLO0_XI_SHIFT) & 0x1; /* [62] */ -+ tlb->RPLV0 = (lo0 >> CSR_TLBLO0_RPLV_SHIFT) & 0x1; /* [63] */ -+ -+ tlb->V1 = (lo1 >> CSR_TLBLO1_V_SHIFT) & 0x1; /* [0] */ -+ tlb->WE1 = (lo1 >> CSR_TLBLO1_WE_SHIFT) & 0x1; /* [1] */ -+ tlb->PLV1 = (lo1 >> CSR_TLBLO1_PLV_SHIFT) & 0x3; /* [3:2] */ -+ tlb->C1 = (lo1 >> CSR_TLBLO1_CCA_SHIFT) & 0x3; /* [5:4] */ -+ tlb->PPN1 = (lo1 & 0xfffffffff000 & ~(page_mask >> 1)); -+ tlb->RI1 = (lo1 >> CSR_TLBLO1_RI_SHIFT) & 0x1; /* [61] */ -+ tlb->XI1 = (lo1 >> CSR_TLBLO1_XI_SHIFT) & 0x1; /* [62] */ -+ tlb->RPLV1 = (lo1 >> CSR_TLBLO1_RPLV_SHIFT) & 0x1; /* [63] */ -+} -+ -+static void ls3a5k_fill_tlb(CPULOONGARCHState *env, int idx, bool tlbwr) -+{ -+ ls3a5k_tlb_t *tlb; -+ -+ tlb = &env->tlb->mmu.ls3a5k.tlb[idx]; -+ if (tlbwr) { -+ if ((env->CSR_TLBIDX >> CSR_TLBIDX_EHINV_SHIFT) & 0x1) { -+ tlb->EHINV = 1; -+ return; -+ } -+ } -+ -+ if (idx < 2048) { -+ ls3a5k_fill_tlb_entry(env, tlb, 1); -+ } else { -+ ls3a5k_fill_tlb_entry(env, tlb, 0); -+ } -+} -+ -+void ls3a5k_flush_vtlb(CPULOONGARCHState *env) -+{ -+ uint32_t ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; -+ uint32_t vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; -+ int i; -+ -+ ls3a5k_tlb_t *tlb; -+ -+ for (i = ftlb_size; i < ftlb_size + vtlb_size; ++i) { -+ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ tlb->EHINV = 1; -+ } -+ -+ cpu_loongarch_tlb_flush(env); -+} -+ -+void ls3a5k_flush_ftlb(CPULOONGARCHState *env) -+{ -+ uint32_t ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; -+ int i; -+ -+ ls3a5k_tlb_t *tlb; -+ -+ for (i = 0; i < ftlb_size; ++i) { -+ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ tlb->EHINV = 1; -+ } -+ -+ cpu_loongarch_tlb_flush(env); -+} -+ -+void ls3a5k_helper_tlbclr(CPULOONGARCHState *env) -+{ -+ int i; -+ uint16_t asid; -+ int vsize, fsize, index; -+ int start = 0, end = -1; -+ -+ asid = env->CSR_ASID & 0x3ff; -+ vsize = env->tlb->mmu.ls3a5k.vtlb_size; -+ fsize = env->tlb->mmu.ls3a5k.ftlb_size; -+ index = env->CSR_TLBIDX & CSR_TLBIDX_IDX; -+ -+ if (index < fsize) { -+ /* FTLB. One line per operation */ -+ int set = index % 256; -+ start = set * 8; -+ end = start + 7; -+ } else if (index < (fsize + vsize)) { -+ /* VTLB. All entries */ -+ start = fsize; -+ end = fsize + vsize - 1; -+ } else { -+ /* Ignore */ -+ } -+ -+ for (i = start; i <= end; i++) { -+ ls3a5k_tlb_t *tlb; -+ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ if (!tlb->G && tlb->ASID == asid) { -+ tlb->EHINV = 1; -+ } -+ } -+ -+ cpu_loongarch_tlb_flush(env); -+} -+ -+void ls3a5k_helper_tlbflush(CPULOONGARCHState *env) -+{ -+ int i; -+ int vsize, fsize, index; -+ int start = 0, end = -1; -+ -+ vsize = env->tlb->mmu.ls3a5k.vtlb_size; -+ fsize = env->tlb->mmu.ls3a5k.ftlb_size; -+ index = env->CSR_TLBIDX & CSR_TLBIDX_IDX; -+ -+ if (index < fsize) { -+ /* FTLB. One line per operation */ -+ int set = index % 256; -+ start = set * 8; -+ end = start + 7; -+ } else if (index < (fsize + vsize)) { -+ /* VTLB. All entries */ -+ start = fsize; -+ end = fsize + vsize - 1; -+ } else { -+ /* Ignore */ -+ } -+ -+ for (i = start; i <= end; i++) { -+ env->tlb->mmu.ls3a5k.tlb[i].EHINV = 1; -+ } -+ -+ cpu_loongarch_tlb_flush(env); -+} -+ -+void ls3a5k_helper_invtlb(CPULOONGARCHState *env, target_ulong addr, -+ target_ulong info, int op) -+{ -+ uint32_t asid = info & 0x3ff; -+ int i; -+ -+ switch (op) { -+ case 0: -+ case 1: -+ for (i = 0; i < env->tlb->nb_tlb; i++) { -+ env->tlb->mmu.ls3a5k.tlb[i].EHINV = 1; -+ } -+ break; -+ case 4: { -+ int i; -+ for (i = 0; i < env->tlb->nb_tlb; i++) { -+ struct ls3a5k_tlb_t *tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ -+ if (!tlb->G && tlb->ASID == asid) { -+ tlb->EHINV = 1; -+ } -+ } -+ break; -+ } -+ -+ case 5: { -+ int i; -+ for (i = 0; i < env->tlb->nb_tlb; i++) { -+ struct ls3a5k_tlb_t *tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ uint64_t vpn = addr & 0xffffffffe000 & ~tlb->PageMask; -+ -+ if (!tlb->G && tlb->ASID == asid && vpn == tlb->VPN) { -+ tlb->EHINV = 1; -+ } -+ } -+ break; -+ } -+ case 6: { -+ int i; -+ for (i = 0; i < env->tlb->nb_tlb; i++) { -+ struct ls3a5k_tlb_t *tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ uint64_t vpn = addr & 0xffffffffe000 & ~tlb->PageMask; -+ -+ if ((tlb->G || tlb->ASID == asid) && vpn == tlb->VPN) { -+ tlb->EHINV = 1; -+ } -+ } -+ break; -+ } -+ default: -+ helper_raise_exception(env, EXCP_RI); -+ } -+ -+ cpu_loongarch_tlb_flush(env); -+} -+ -+static void ls3a5k_invalidate_tlb_entry(CPULOONGARCHState *env, -+ ls3a5k_tlb_t *tlb) -+{ -+ LOONGARCHCPU *cpu = loongarch_env_get_cpu(env); -+ CPUState *cs = CPU(cpu); -+ target_ulong addr; -+ target_ulong end; -+ target_ulong mask; -+ -+ mask = tlb->PageMask; /* 000...000111...111 */ -+ -+ if (tlb->V0) { -+ addr = tlb->VPN & ~mask; /* xxx...xxx[0]000..0000 */ -+ end = addr | (mask >> 1); /* xxx...xxx[0]111..1111 */ -+ while (addr < end) { -+ tlb_flush_page(cs, addr); -+ addr += TARGET_PAGE_SIZE; -+ } -+ } -+ -+ if (tlb->V1) { -+ /* xxx...xxx[1]000..0000 */ -+ addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1); -+ end = addr | mask; /* xxx...xxx[1]111..1111 */ -+ while (addr - 1 < end) { -+ tlb_flush_page(cs, addr); -+ addr += TARGET_PAGE_SIZE; -+ } -+ } -+} -+ -+void ls3a5k_invalidate_tlb(CPULOONGARCHState *env, int idx) -+{ -+ ls3a5k_tlb_t *tlb; -+ int asid = env->CSR_ASID & 0x3ff; -+ tlb = &env->tlb->mmu.ls3a5k.tlb[idx]; -+ if (tlb->G == 0 && tlb->ASID != asid) { -+ return; -+ } -+ ls3a5k_invalidate_tlb_entry(env, tlb); -+} -+ -+void ls3a5k_helper_tlbwr(CPULOONGARCHState *env) -+{ -+ int idx = env->CSR_TLBIDX & CSR_TLBIDX_IDX; /* [11:0] */ -+ -+ /* Convert idx if in FTLB */ -+ if (idx < env->tlb->mmu.ls3a5k.ftlb_size) { -+ /* -+ * 0 3 6 0 1 2 -+ * 1 4 7 => 3 4 5 -+ * 2 5 8 6 7 8 -+ */ -+ int set = idx % 256; -+ int way = idx / 256; -+ idx = set * 8 + way; -+ } -+ ls3a5k_invalidate_tlb(env, idx); -+ ls3a5k_fill_tlb(env, idx, true); -+} -+ -+void ls3a5k_helper_tlbfill(CPULOONGARCHState *env) -+{ -+ uint64_t mask; -+ uint64_t address; -+ int idx; -+ int set, ftlb_idx; -+ -+ uint64_t entryhi; -+ uint32_t pagesize; -+ -+ if (env->CSR_TLBRERA & 0x1) { -+ entryhi = env->CSR_TLBREHI & ~0x3f; -+ pagesize = env->CSR_TLBREHI & 0x3f; -+ } else { -+ entryhi = env->CSR_TLBEHI; -+ pagesize = (env->CSR_TLBIDX >> CSR_TLBIDX_PS_SHIFT) & 0x3f; -+ } -+ -+ uint32_t ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; -+ uint32_t vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; -+ -+ mask = ls3a5k_pagesize_to_mask(pagesize); -+ -+ if (mask == env->tlb->mmu.ls3a5k.ftlb_mask && -+ env->tlb->mmu.ls3a5k.ftlb_size > 0) { -+ /* only write into FTLB */ -+ address = entryhi & 0xffffffffe000; /* [47:13] */ -+ -+ /* choose one set ramdomly */ -+ set = cpu_loongarch_get_random_ls3a5k_tlb(0, 7); -+ -+ /* index in one set */ -+ ftlb_idx = (address >> 15) & 0xff; /* [0,255] */ -+ -+ /* final idx */ -+ idx = ftlb_idx * 8 + set; /* max is 7 + 8 * 255 = 2047 */ -+ } else { -+ /* only write into VTLB */ -+ int wired_nr = env->CSR_TLBWIRED & 0x3f; -+ idx = cpu_loongarch_get_random_ls3a5k_tlb( -+ ftlb_size + wired_nr, ftlb_size + vtlb_size - 1); -+ } -+ -+ ls3a5k_invalidate_tlb(env, idx); -+ ls3a5k_fill_tlb(env, idx, false); -+} -+ -+void ls3a5k_helper_tlbsrch(CPULOONGARCHState *env) -+{ -+ uint64_t mask; -+ uint64_t vpn; -+ uint64_t tag; -+ uint16_t asid; -+ -+ int ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; -+ int vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; -+ int i; -+ int ftlb_idx; /* [0,255] 2^8 0xff */ -+ -+ ls3a5k_tlb_t *tlb; -+ -+ asid = env->CSR_ASID & 0x3ff; -+ -+ /* search VTLB */ -+ for (i = ftlb_size; i < ftlb_size + vtlb_size; ++i) { -+ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ mask = tlb->PageMask; -+ -+ vpn = env->CSR_TLBEHI & 0xffffffffe000 & ~mask; -+ tag = tlb->VPN & ~mask; -+ -+ if ((tlb->G == 1 || tlb->ASID == asid) && vpn == tag && tlb->EHINV != 1) -+ { -+ env->CSR_TLBIDX = (i & 0xfff) | -+ ((tlb->PageSize & 0x3f) << CSR_TLBIDX_PS_SHIFT); -+ goto _MATCH_OUT_; -+ } -+ } -+ -+ if (ftlb_size == 0) { -+ goto _NO_MATCH_OUT_; -+ } -+ -+ /* search FTLB */ -+ mask = env->tlb->mmu.ls3a5k.ftlb_mask; -+ vpn = env->CSR_TLBEHI & 0xffffffffe000 & ~mask; -+ -+ ftlb_idx = (env->CSR_TLBEHI & 0xffffffffe000) >> 15; /* 16 KB */ -+ ftlb_idx = ftlb_idx & 0xff; /* [0,255] */ -+ -+ for (i = 0; i < 8; ++i) { -+ tlb = &env->tlb->mmu.ls3a5k.tlb[ftlb_idx * 8 + i]; -+ tag = tlb->VPN & ~mask; -+ -+ if ((tlb->G == 1 || tlb->ASID == asid) && vpn == tag && tlb->EHINV != 1) -+ { -+ env->CSR_TLBIDX = ((i * 256 + ftlb_idx) & 0xfff) | -+ ((tlb->PageSize & 0x3f) << CSR_TLBIDX_PS_SHIFT); -+ goto _MATCH_OUT_; -+ } -+ } -+ -+_NO_MATCH_OUT_: -+ env->CSR_TLBIDX = 1 << CSR_TLBIDX_EHINV_SHIFT; -+_MATCH_OUT_: -+ return; -+} -+ -+void ls3a5k_helper_tlbrd(CPULOONGARCHState *env) -+{ -+ ls3a5k_tlb_t *tlb; -+ int idx; -+ uint16_t asid; -+ -+ idx = env->CSR_TLBIDX & CSR_TLBIDX_IDX; -+ if (idx < env->tlb->mmu.ls3a5k.ftlb_size) { -+ int set = idx % 256; -+ int way = idx / 256; -+ idx = set * 8 + way; -+ } -+ -+ tlb = &env->tlb->mmu.ls3a5k.tlb[idx]; -+ -+ asid = env->CSR_ASID & 0x3ff; -+ -+ if (asid != tlb->ASID) { -+ cpu_loongarch_tlb_flush(env); -+ } -+ -+ if (tlb->EHINV) { -+ /* invalid TLB entry */ -+ env->CSR_TLBIDX = 1 << CSR_TLBIDX_EHINV_SHIFT; -+ env->CSR_TLBEHI = 0; -+ env->CSR_TLBELO0 = 0; -+ env->CSR_TLBELO1 = 0; -+ } else { -+ /* valid TLB entry */ -+ env->CSR_TLBIDX = (env->CSR_TLBIDX & 0xfff) | -+ ((tlb->PageSize & 0x3f) << CSR_TLBIDX_PS_SHIFT); -+ env->CSR_TLBEHI = tlb->VPN; -+ env->CSR_TLBELO0 = (tlb->V0 << CSR_TLBLO0_V_SHIFT) | -+ (tlb->WE0 << CSR_TLBLO0_WE_SHIFT) | -+ (tlb->PLV0 << CSR_TLBLO0_PLV_SHIFT) | -+ (tlb->C0 << CSR_TLBLO0_CCA_SHIFT) | -+ (tlb->G << CSR_TLBLO0_GLOBAL_SHIFT) | -+ (tlb->PPN0 & 0xfffffffff000) | -+ ((uint64_t)tlb->RI0 << CSR_TLBLO0_RI_SHIFT) | -+ ((uint64_t)tlb->XI0 << CSR_TLBLO0_XI_SHIFT) | -+ ((uint64_t)tlb->RPLV0 << CSR_TLBLO0_RPLV_SHIFT); -+ env->CSR_TLBELO1 = (tlb->V1 << CSR_TLBLO1_V_SHIFT) | -+ (tlb->WE1 << CSR_TLBLO1_WE_SHIFT) | -+ (tlb->PLV1 << CSR_TLBLO1_PLV_SHIFT) | -+ (tlb->C1 << CSR_TLBLO1_CCA_SHIFT) | -+ (tlb->G << CSR_TLBLO0_GLOBAL_SHIFT) | -+ (tlb->PPN1 & 0xfffffffff000) | -+ ((uint64_t)tlb->RI1 << CSR_TLBLO1_RI_SHIFT) | -+ ((uint64_t)tlb->XI1 << CSR_TLBLO1_XI_SHIFT) | -+ ((uint64_t)tlb->RPLV1 << CSR_TLBLO1_RPLV_SHIFT); -+ env->CSR_ASID = (tlb->ASID << CSR_ASID_ASID_SHIFT) | -+ (env->CSR_ASID & 0xff0000); -+ } -+} -+ -+void helper_tlbwr(CPULOONGARCHState *env) -+{ -+ env->tlb->helper_tlbwr(env); -+} -+ -+void helper_tlbfill(CPULOONGARCHState *env) -+{ -+ env->tlb->helper_tlbfill(env); -+} -+ -+void helper_tlbsrch(CPULOONGARCHState *env) -+{ -+ env->tlb->helper_tlbsrch(env); -+} -+ -+void helper_tlbrd(CPULOONGARCHState *env) -+{ -+ env->tlb->helper_tlbrd(env); -+} -+ -+void helper_tlbclr(CPULOONGARCHState *env) -+{ -+ env->tlb->helper_tlbclr(env); -+} -+ -+void helper_tlbflush(CPULOONGARCHState *env) -+{ -+ env->tlb->helper_tlbflush(env); -+} -+ -+void helper_invtlb(CPULOONGARCHState *env, target_ulong addr, target_ulong info, -+ target_ulong op) -+{ -+ env->tlb->helper_invtlb(env, addr, info, op); -+} -+ -+static void ls3a5k_mmu_init(CPULOONGARCHState *env, const loongarch_def_t *def) -+{ -+ /* number of VTLB */ -+ env->tlb->nb_tlb = 64; -+ env->tlb->mmu.ls3a5k.vtlb_size = 64; -+ -+ /* number of FTLB */ -+ env->tlb->nb_tlb += 2048; -+ env->tlb->mmu.ls3a5k.ftlb_size = 2048; -+ env->tlb->mmu.ls3a5k.ftlb_mask = (1 << 15) - 1; /* 16 KB */ -+ /* -+ * page_size | ftlb_mask | party field -+ * ---------------------------------------------------------------- -+ * 4 KB = 12 | ( 1 << 13 ) - 1 = [12:0] | [12] -+ * 16 KB = 14 | ( 1 << 15 ) - 1 = [14:0] | [14] -+ * 64 KB = 16 | ( 1 << 17 ) - 1 = [16:0] | [16] -+ * 256 KB = 18 | ( 1 << 19 ) - 1 = [18:0] | [18] -+ * 1 MB = 20 | ( 1 << 21 ) - 1 = [20:0] | [20] -+ * 4 MB = 22 | ( 1 << 23 ) - 1 = [22:0] | [22] -+ * 16 MB = 24 | ( 1 << 25 ) - 1 = [24:0] | [24] -+ * 64 MB = 26 | ( 1 << 27 ) - 1 = [26:0] | [26] -+ * 256 MB = 28 | ( 1 << 29 ) - 1 = [28:0] | [28] -+ * 1 GB = 30 | ( 1 << 31 ) - 1 = [30:0] | [30] -+ * ---------------------------------------------------------------- -+ * take party field index as @n. eg. For 16 KB, n = 14 -+ * ---------------------------------------------------------------- -+ * tlb->VPN = TLBEHI & 0xffffffffe000[47:13] & ~mask = [47:n+1] -+ * tlb->PPN = TLBLO0 & 0xffffffffe000[47:13] & ~mask = [47:n+1] -+ * tlb->PPN = TLBLO1 & 0xffffffffe000[47:13] & ~mask = [47:n+1] -+ * ---------------------------------------------------------------- -+ * On mapping : -+ * > vpn = address & 0xffffffffe000[47:13] & ~mask = [47:n+1] -+ * > tag = tlb->VPN & ~mask = [47:n+1] -+ * ---------------------------------------------------------------- -+ * physical address = [47:n+1] | [n:0] -+ * physical address = tlb->PPN0 | (address & mask) -+ * physical address = tlb->PPN1 | (address & mask) -+ */ -+ -+ int i; -+ for (i = 0; i < env->tlb->nb_tlb; i++) { -+ env->tlb->mmu.ls3a5k.tlb[i].EHINV = 1; -+ } -+ -+ /* TLB's helper functions */ -+ env->tlb->map_address = &ls3a5k_map_address; -+ env->tlb->helper_tlbwr = ls3a5k_helper_tlbwr; -+ env->tlb->helper_tlbfill = ls3a5k_helper_tlbfill; -+ env->tlb->helper_tlbsrch = ls3a5k_helper_tlbsrch; -+ env->tlb->helper_tlbrd = ls3a5k_helper_tlbrd; -+ env->tlb->helper_tlbclr = ls3a5k_helper_tlbclr; -+ env->tlb->helper_tlbflush = ls3a5k_helper_tlbflush; -+ env->tlb->helper_invtlb = ls3a5k_helper_invtlb; -+} -+ -+void mmu_init(CPULOONGARCHState *env, const loongarch_def_t *def) -+{ -+ env->tlb = g_malloc0(sizeof(CPULOONGARCHTLBContext)); -+ -+ switch (def->mmu_type) { -+ case MMU_TYPE_LS3A5K: -+ ls3a5k_mmu_init(env, def); -+ break; -+ default: -+ cpu_abort(CPU(loongarch_env_get_cpu(env)), "MMU type not supported\n"); -+ } -+} -+#endif /* !CONFIG_USER_ONLY */ -diff --git a/target/loongarch64/trace-events b/target/loongarch64/trace-events -new file mode 100644 -index 000000000..e0bca4f82 ---- /dev/null -+++ b/target/loongarch64/trace-events -@@ -0,0 +1,3 @@ -+# See docs/devel/tracing.txt for syntax documentation. -+ -+# target/loongarch/translate.c -diff --git a/target/loongarch64/trans.inc.c b/target/loongarch64/trans.inc.c -new file mode 100644 -index 000000000..e50670be4 ---- /dev/null -+++ b/target/loongarch64/trans.inc.c -@@ -0,0 +1,3472 @@ -+static bool trans_syscall(DisasContext *ctx, arg_syscall *a) -+{ -+ generate_exception_end(ctx, EXCP_SYSCALL); -+ return true; -+} -+ -+static bool trans_break(DisasContext *ctx, arg_break *a) -+{ -+ generate_exception_end(ctx, EXCP_BREAK); -+ return true; -+} -+ -+static bool trans_dbcl(DisasContext *ctx, arg_dbcl *a) -+{ -+ /* -+ * dbcl instruction is not support in tcg -+ */ -+ generate_exception_end(ctx, EXCP_RI); -+ return true; -+} -+ -+static bool trans_addi_w(DisasContext *ctx, arg_addi_w *a) -+{ -+ gen_arith_imm(ctx, OPC_LARCH_ADDI_W, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_addi_d(DisasContext *ctx, arg_addi_d *a) -+{ -+ gen_arith_imm(ctx, OPC_LARCH_ADDI_D, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_slli_d(DisasContext *ctx, arg_slli_d *a) -+{ -+ if (a->rd == 0) { -+ /* Nop */ -+ return true; -+ } -+ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ tcg_gen_shli_tl(cpu_gpr[a->rd], t0, a->ui6); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_andi(DisasContext *ctx, arg_andi *a) -+{ -+ gen_logic_imm(ctx, OPC_LARCH_ANDI, a->rd, a->rj, a->ui12); -+ return true; -+} -+ -+static bool trans_srli_d(DisasContext *ctx, arg_srli_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ tcg_gen_shri_tl(cpu_gpr[a->rd], t0, a->ui6); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_slli_w(DisasContext *ctx, arg_slli_w *a) -+{ -+ if (a->rd == 0) { -+ /* Nop */ -+ return true; -+ } -+ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ tcg_gen_shli_tl(t0, t0, a->ui5); -+ tcg_gen_ext32s_tl(cpu_gpr[a->rd], t0); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_addu16i_d(DisasContext *ctx, arg_addu16i_d *a) -+{ -+ if (a->rj != 0) { -+ tcg_gen_addi_tl(cpu_gpr[a->rd], cpu_gpr[a->rj], a->si16 << 16); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[a->rd], a->si16 << 16); -+ } -+ return true; -+} -+ -+static bool trans_lu12i_w(DisasContext *ctx, arg_lu12i_w *a) -+{ -+ tcg_gen_movi_tl(cpu_gpr[a->rd], a->si20 << 12); -+ return true; -+} -+ -+static bool trans_lu32i_d(DisasContext *ctx, arg_lu32i_d *a) -+{ -+ TCGv_i64 t0, t1; -+ t0 = tcg_temp_new_i64(); -+ t1 = tcg_temp_new_i64(); -+ -+ tcg_gen_movi_tl(t0, a->si20); -+ tcg_gen_concat_tl_i64(t1, cpu_gpr[a->rd], t0); -+ gen_store_gpr(t1, a->rd); -+ -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_pcaddi(DisasContext *ctx, arg_pcaddi *a) -+{ -+ target_ulong pc = ctx->base.pc_next; -+ target_ulong addr = pc + (a->si20 << 2); -+ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); -+ return true; -+} -+ -+static bool trans_pcalau12i(DisasContext *ctx, arg_pcalau12i *a) -+{ -+ target_ulong pc = ctx->base.pc_next; -+ target_ulong addr = (pc + (a->si20 << 12)) & ~0xfff; -+ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); -+ return true; -+} -+ -+static bool trans_pcaddu12i(DisasContext *ctx, arg_pcaddu12i *a) -+{ -+ target_ulong pc = ctx->base.pc_next; -+ target_ulong addr = pc + (a->si20 << 12); -+ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); -+ return true; -+} -+ -+static bool trans_pcaddu18i(DisasContext *ctx, arg_pcaddu18i *a) -+{ -+ target_ulong pc = ctx->base.pc_next; -+ target_ulong addr = pc + ((target_ulong)(a->si20) << 18); -+ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); -+ return true; -+} -+ -+static bool trans_slti(DisasContext *ctx, arg_slti *a) -+{ -+ gen_slt_imm(ctx, OPC_LARCH_SLTI, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_sltui(DisasContext *ctx, arg_sltui *a) -+{ -+ gen_slt_imm(ctx, OPC_LARCH_SLTIU, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_lu52i_d(DisasContext *ctx, arg_lu52i_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ -+ gen_load_gpr(t1, a->rj); -+ -+ tcg_gen_movi_tl(t0, a->si12); -+ tcg_gen_shli_tl(t0, t0, 52); -+ tcg_gen_andi_tl(t1, t1, 0xfffffffffffffU); -+ tcg_gen_or_tl(cpu_gpr[a->rd], t0, t1); -+ -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_ori(DisasContext *ctx, arg_ori *a) -+{ -+ gen_logic_imm(ctx, OPC_LARCH_ORI, a->rd, a->rj, a->ui12); -+ return true; -+} -+ -+static bool trans_xori(DisasContext *ctx, arg_xori *a) -+{ -+ gen_logic_imm(ctx, OPC_LARCH_XORI, a->rd, a->rj, a->ui12); -+ return true; -+} -+ -+static bool trans_bstrins_d(DisasContext *ctx, arg_bstrins_d *a) -+{ -+ int lsb = a->lsbd; -+ int msb = a->msbd; -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ -+ if (lsb > msb) { -+ return false; -+ } -+ -+ gen_load_gpr(t1, a->rj); -+ gen_load_gpr(t0, a->rd); -+ tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); -+ gen_store_gpr(t0, a->rd); -+ -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_bstrpick_d(DisasContext *ctx, arg_bstrpick_d *a) -+{ -+ int lsb = a->lsbd; -+ int msb = a->msbd; -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ -+ if (lsb > msb) { -+ return false; -+ } -+ -+ gen_load_gpr(t1, a->rj); -+ gen_load_gpr(t0, a->rd); -+ tcg_gen_extract_tl(t0, t1, lsb, msb - lsb + 1); -+ gen_store_gpr(t0, a->rd); -+ -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_bstrins_w(DisasContext *ctx, arg_bstrins_w *a) -+{ -+ gen_bitops(ctx, OPC_LARCH_TRINS_W, a->rd, a->rj, a->lsbw, a->msbw); -+ return true; -+} -+ -+static bool trans_bstrpick_w(DisasContext *ctx, arg_bstrpick_w *a) -+{ -+ if (a->lsbw > a->msbw) { -+ return false; -+ } -+ gen_bitops(ctx, OPC_LARCH_TRPICK_W, -+ a->rd, a->rj, a->lsbw, a->msbw - a->lsbw); -+ return true; -+} -+ -+static bool trans_ldptr_w(DisasContext *ctx, arg_ldptr_w *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LDPTR_W, a->rd, a->rj, a->si14 << 2); -+ return true; -+} -+ -+static bool trans_stptr_w(DisasContext *ctx, arg_stptr_w *a) -+{ -+ gen_st(ctx, OPC_LARCH_STPTR_W, a->rd, a->rj, a->si14 << 2); -+ return true; -+} -+ -+static bool trans_ldptr_d(DisasContext *ctx, arg_ldptr_d *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LDPTR_D, a->rd, a->rj, a->si14 << 2); -+ return true; -+} -+ -+static bool trans_stptr_d(DisasContext *ctx, arg_stptr_d *a) -+{ -+ gen_st(ctx, OPC_LARCH_STPTR_D, a->rd, a->rj, a->si14 << 2); -+ return true; -+} -+ -+static bool trans_ld_b(DisasContext *ctx, arg_ld_b *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_B, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ld_h(DisasContext *ctx, arg_ld_h *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_H, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ld_w(DisasContext *ctx, arg_ld_w *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_W, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ld_d(DisasContext *ctx, arg_ld_d *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_D, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_st_b(DisasContext *ctx, arg_st_b *a) -+{ -+ gen_st(ctx, OPC_LARCH_ST_B, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_st_h(DisasContext *ctx, arg_st_h *a) -+{ -+ gen_st(ctx, OPC_LARCH_ST_H, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_st_w(DisasContext *ctx, arg_st_w *a) -+{ -+ gen_st(ctx, OPC_LARCH_ST_W, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_st_d(DisasContext *ctx, arg_st_d *a) -+{ -+ gen_st(ctx, OPC_LARCH_ST_D, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ld_bu(DisasContext *ctx, arg_ld_bu *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_BU, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ld_hu(DisasContext *ctx, arg_ld_hu *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_HU, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ld_wu(DisasContext *ctx, arg_ld_wu *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_WU, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_preld(DisasContext *ctx, arg_preld *a) -+{ -+ /* Treat as NOP. */ -+ return true; -+} -+ -+static bool trans_ll_w(DisasContext *ctx, arg_ll_w *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LL_W, a->rd, a->rj, a->si14 << 2); -+ return true; -+} -+ -+static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a) -+{ -+ gen_st_cond(ctx, a->rd, a->rj, a->si14 << 2, MO_TESL, false); -+ return true; -+} -+ -+static bool trans_ll_d(DisasContext *ctx, arg_ll_d *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LL_D, a->rd, a->rj, a->si14 << 2); -+ return true; -+} -+ -+static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a) -+{ -+ gen_st_cond(ctx, a->rd, a->rj, a->si14 << 2, MO_TEQ, false); -+ return true; -+} -+ -+static bool trans_fld_s(DisasContext *ctx, arg_fld_s *a) -+{ -+ gen_fp_ldst(ctx, OPC_LARCH_FLD_S, a->fd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_fst_s(DisasContext *ctx, arg_fst_s *a) -+{ -+ gen_fp_ldst(ctx, OPC_LARCH_FST_S, a->fd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_fld_d(DisasContext *ctx, arg_fld_d *a) -+{ -+ gen_fp_ldst(ctx, OPC_LARCH_FLD_D, a->fd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_fst_d(DisasContext *ctx, arg_fst_d *a) -+{ -+ gen_fp_ldst(ctx, OPC_LARCH_FST_D, a->fd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ldx_b(DisasContext *ctx, arg_ldx_b *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_SB); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_ldx_h(DisasContext *ctx, arg_ldx_h *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TESW | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_ldx_w(DisasContext *ctx, arg_ldx_w *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TESL | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_ldx_d(DisasContext *ctx, arg_ldx_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TEQ | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_stx_b(DisasContext *ctx, arg_stx_b *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ gen_load_gpr(t1, a->rd); -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_stx_h(DisasContext *ctx, arg_stx_h *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ gen_load_gpr(t1, a->rd); -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | -+ ctx->default_tcg_memop_mask); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_stx_w(DisasContext *ctx, arg_stx_w *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ gen_load_gpr(t1, a->rd); -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | -+ ctx->default_tcg_memop_mask); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_stx_d(DisasContext *ctx, arg_stx_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ gen_load_gpr(t1, a->rd); -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ | -+ ctx->default_tcg_memop_mask); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_ldx_bu(DisasContext *ctx, arg_ldx_bu *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_ldx_hu(DisasContext *ctx, arg_ldx_hu *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TEUW | -+ ctx->default_tcg_memop_mask); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_ldx_wu(DisasContext *ctx, arg_ldx_wu *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TEUL | -+ ctx->default_tcg_memop_mask); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_fldx_s(DisasContext *ctx, arg_fldx_s *a) -+{ -+ gen_flt3_ldst(ctx, OPC_LARCH_FLDX_S, a->fd, 0, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fldx_d(DisasContext *ctx, arg_fldx_d *a) -+{ -+ gen_flt3_ldst(ctx, OPC_LARCH_FLDX_D, a->fd, 0, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fstx_s(DisasContext *ctx, arg_fstx_s *a) -+{ -+ gen_flt3_ldst(ctx, OPC_LARCH_FSTX_S, 0, a->fd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fstx_d(DisasContext *ctx, arg_fstx_d *a) -+{ -+ gen_flt3_ldst(ctx, OPC_LARCH_FSTX_D, 0, a->fd, a->rj, a->rk); -+ return true; -+} -+ -+#define TRANS_AM_W(name, op) \ -+static bool trans_ ## name(DisasContext *ctx, arg_ ## name * a) \ -+{ \ -+ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ -+ printf("%s: warning, register equal\n", __func__); \ -+ return false; \ -+ } \ -+ int mem_idx = ctx->mem_idx; \ -+ TCGv addr = tcg_temp_new(); \ -+ TCGv val = tcg_temp_new(); \ -+ TCGv ret = tcg_temp_new(); \ -+\ -+ gen_load_gpr(addr, a->rj); \ -+ gen_load_gpr(val, a->rk); \ -+ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, MO_TESL | \ -+ ctx->default_tcg_memop_mask); \ -+ gen_store_gpr(ret, a->rd); \ -+\ -+ tcg_temp_free(addr); \ -+ tcg_temp_free(val); \ -+ tcg_temp_free(ret); \ -+ return true; \ -+} -+#define TRANS_AM_D(name, op) \ -+static bool trans_ ## name(DisasContext *ctx, arg_ ## name * a) \ -+{ \ -+ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ -+ printf("%s: warning, register equal\n", __func__); \ -+ return false; \ -+ } \ -+ int mem_idx = ctx->mem_idx; \ -+ TCGv addr = tcg_temp_new(); \ -+ TCGv val = tcg_temp_new(); \ -+ TCGv ret = tcg_temp_new(); \ -+\ -+ gen_load_gpr(addr, a->rj); \ -+ gen_load_gpr(val, a->rk); \ -+ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, MO_TEQ | \ -+ ctx->default_tcg_memop_mask); \ -+ gen_store_gpr(ret, a->rd); \ -+\ -+ tcg_temp_free(addr); \ -+ tcg_temp_free(val); \ -+ tcg_temp_free(ret); \ -+ return true; \ -+} -+#define TRANS_AM(name, op) \ -+ TRANS_AM_W(name##_w, op) \ -+ TRANS_AM_D(name##_d, op) -+TRANS_AM(amswap, xchg) /* trans_amswap_w, trans_amswap_d */ -+TRANS_AM(amadd, fetch_add) /* trans_amadd_w, trans_amadd_d */ -+TRANS_AM(amand, fetch_and) /* trans_amand_w, trans_amand_d */ -+TRANS_AM(amor, fetch_or) /* trans_amor_w, trans_amor_d */ -+TRANS_AM(amxor, fetch_xor) /* trans_amxor_w, trans_amxor_d */ -+TRANS_AM(ammax, fetch_smax) /* trans_ammax_w, trans_ammax_d */ -+TRANS_AM(ammin, fetch_smin) /* trans_ammin_w, trans_ammin_d */ -+TRANS_AM_W(ammax_wu, fetch_umax) /* trans_ammax_wu */ -+TRANS_AM_D(ammax_du, fetch_umax) /* trans_ammax_du */ -+TRANS_AM_W(ammin_wu, fetch_umin) /* trans_ammin_wu */ -+TRANS_AM_D(ammin_du, fetch_umin) /* trans_ammin_du */ -+#undef TRANS_AM -+#undef TRANS_AM_W -+#undef TRANS_AM_D -+ -+#define TRANS_AM_DB_W(name, op) \ -+static bool trans_ ## name(DisasContext *ctx, arg_ ## name * a) \ -+{ \ -+ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ -+ printf("%s: warning, register equal\n", __func__); \ -+ return false; \ -+ } \ -+ int mem_idx = ctx->mem_idx; \ -+ TCGv addr = tcg_temp_new(); \ -+ TCGv val = tcg_temp_new(); \ -+ TCGv ret = tcg_temp_new(); \ -+\ -+ gen_sync(0x10); /* TCG_MO_ALL */ \ -+ gen_load_gpr(addr, a->rj); \ -+ gen_load_gpr(val, a->rk); \ -+ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, MO_TESL | \ -+ ctx->default_tcg_memop_mask); \ -+ gen_store_gpr(ret, a->rd); \ -+\ -+ tcg_temp_free(addr); \ -+ tcg_temp_free(val); \ -+ tcg_temp_free(ret); \ -+ return true; \ -+} -+#define TRANS_AM_DB_D(name, op) \ -+static bool trans_ ## name(DisasContext *ctx, arg_ ## name * a) \ -+{ \ -+ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ -+ printf("%s: warning, register equal\n", __func__); \ -+ return false; \ -+ } \ -+ int mem_idx = ctx->mem_idx; \ -+ TCGv addr = tcg_temp_new(); \ -+ TCGv val = tcg_temp_new(); \ -+ TCGv ret = tcg_temp_new(); \ -+\ -+ gen_sync(0x10); /* TCG_MO_ALL */ \ -+ gen_load_gpr(addr, a->rj); \ -+ gen_load_gpr(val, a->rk); \ -+ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, MO_TEQ | \ -+ ctx->default_tcg_memop_mask); \ -+ gen_store_gpr(ret, a->rd); \ -+\ -+ tcg_temp_free(addr); \ -+ tcg_temp_free(val); \ -+ tcg_temp_free(ret); \ -+ return true; \ -+} -+#define TRANS_AM_DB(name, op) \ -+ TRANS_AM_DB_W(name##_db_w, op) \ -+ TRANS_AM_DB_D(name##_db_d, op) -+TRANS_AM_DB(amswap, xchg) /* trans_amswap_db_w, trans_amswap_db_d */ -+TRANS_AM_DB(amadd, fetch_add) /* trans_amadd_db_w, trans_amadd_db_d */ -+TRANS_AM_DB(amand, fetch_and) /* trans_amand_db_w, trans_amand_db_d */ -+TRANS_AM_DB(amor, fetch_or) /* trans_amor_db_w, trans_amor_db_d */ -+TRANS_AM_DB(amxor, fetch_xor) /* trans_amxor_db_w, trans_amxor_db_d */ -+TRANS_AM_DB(ammax, fetch_smax) /* trans_ammax_db_w, trans_ammax_db_d */ -+TRANS_AM_DB(ammin, fetch_smin) /* trans_ammin_db_w, trans_ammin_db_d */ -+TRANS_AM_DB_W(ammax_db_wu, fetch_umax) /* trans_ammax_db_wu */ -+TRANS_AM_DB_D(ammax_db_du, fetch_umax) /* trans_ammax_db_du */ -+TRANS_AM_DB_W(ammin_db_wu, fetch_umin) /* trans_ammin_db_wu */ -+TRANS_AM_DB_D(ammin_db_du, fetch_umin) /* trans_ammin_db_du */ -+#undef TRANS_AM_DB -+#undef TRANS_AM_DB_W -+#undef TRANS_AM_DB_D -+ -+static bool trans_dbar(DisasContext *ctx, arg_dbar * a) -+{ -+ gen_sync(a->whint); -+ return true; -+} -+ -+static bool trans_ibar(DisasContext *ctx, arg_ibar *a) -+{ -+ /* -+ * FENCE_I is a no-op in QEMU, -+ * however we need to end the translation block -+ */ -+ ctx->base.is_jmp = DISAS_STOP; -+ return true; -+} -+ -+#define ASRTGT \ -+do { \ -+ TCGv t1 = tcg_temp_new(); \ -+ TCGv t2 = tcg_temp_new(); \ -+ gen_load_gpr(t1, a->rj); \ -+ gen_load_gpr(t2, a->rk); \ -+ gen_helper_asrtgt_d(cpu_env, t1, t2); \ -+ tcg_temp_free(t1); \ -+ tcg_temp_free(t2); \ -+} while (0) -+ -+#define ASRTLE \ -+do {\ -+ TCGv t1 = tcg_temp_new(); \ -+ TCGv t2 = tcg_temp_new(); \ -+ gen_load_gpr(t1, a->rj); \ -+ gen_load_gpr(t2, a->rk); \ -+ gen_helper_asrtle_d(cpu_env, t1, t2); \ -+ tcg_temp_free(t1); \ -+ tcg_temp_free(t2); \ -+} while (0) -+ -+static bool trans_fldgt_s(DisasContext *ctx, arg_fldgt_s *a) -+{ -+ ASRTGT; -+ gen_flt3_ldst(ctx, OPC_LARCH_FLDGT_S, a->fd, 0, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fldgt_d(DisasContext *ctx, arg_fldgt_d *a) -+{ -+ ASRTGT; -+ gen_flt3_ldst(ctx, OPC_LARCH_FLDGT_D, a->fd, 0, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fldle_s(DisasContext *ctx, arg_fldle_s *a) -+{ -+ ASRTLE; -+ gen_flt3_ldst(ctx, OPC_LARCH_FLDLE_S, a->fd, 0, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fldle_d(DisasContext *ctx, arg_fldle_d *a) -+{ -+ ASRTLE; -+ gen_flt3_ldst(ctx, OPC_LARCH_FLDLE_D, a->fd, 0, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fstgt_s(DisasContext *ctx, arg_fstgt_s *a) -+{ -+ ASRTGT; -+ gen_flt3_ldst(ctx, OPC_LARCH_FSTGT_S, 0, a->fd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fstgt_d(DisasContext *ctx, arg_fstgt_d *a) -+{ -+ ASRTGT; -+ gen_flt3_ldst(ctx, OPC_LARCH_FSTGT_D, 0, a->fd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fstle_s(DisasContext *ctx, arg_fstle_s *a) -+{ -+ ASRTLE; -+ gen_flt3_ldst(ctx, OPC_LARCH_FSTLE_S, 0, a->fd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fstle_d(DisasContext *ctx, arg_fstle_d *a) -+{ -+ ASRTLE; -+ gen_flt3_ldst(ctx, OPC_LARCH_FSTLE_D, 0, a->fd, a->rj, a->rk); -+ return true; -+} -+ -+#define DECL_ARG(name) \ -+ arg_ ## name arg = { \ -+ .rd = a->rd, \ -+ .rj = a->rj, \ -+ .rk = a->rk, \ -+ }; -+ -+static bool trans_ldgt_b(DisasContext *ctx, arg_ldgt_b *a) -+{ -+ ASRTGT; -+ DECL_ARG(ldx_b) -+ trans_ldx_b(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldgt_h(DisasContext *ctx, arg_ldgt_h *a) -+{ -+ ASRTGT; -+ DECL_ARG(ldx_h) -+ trans_ldx_h(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldgt_w(DisasContext *ctx, arg_ldgt_w *a) -+{ -+ ASRTGT; -+ DECL_ARG(ldx_w) -+ trans_ldx_w(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldgt_d(DisasContext *ctx, arg_ldgt_d *a) -+{ -+ ASRTGT; -+ DECL_ARG(ldx_d) -+ trans_ldx_d(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldle_b(DisasContext *ctx, arg_ldle_b *a) -+{ -+ ASRTLE; -+ DECL_ARG(ldx_b) -+ trans_ldx_b(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldle_h(DisasContext *ctx, arg_ldle_h *a) -+{ -+ ASRTLE; -+ DECL_ARG(ldx_h) -+ trans_ldx_h(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldle_w(DisasContext *ctx, arg_ldle_w *a) -+{ -+ ASRTLE; -+ DECL_ARG(ldx_w) -+ trans_ldx_w(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldle_d(DisasContext *ctx, arg_ldle_d *a) -+{ -+ ASRTLE; -+ DECL_ARG(ldx_d) -+ trans_ldx_d(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stgt_b(DisasContext *ctx, arg_stgt_b *a) -+{ -+ ASRTGT; -+ DECL_ARG(stx_b) -+ trans_stx_b(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stgt_h(DisasContext *ctx, arg_stgt_h *a) -+{ -+ ASRTGT; -+ DECL_ARG(stx_h) -+ trans_stx_h(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stgt_w(DisasContext *ctx, arg_stgt_w *a) -+{ -+ ASRTGT; -+ DECL_ARG(stx_w) -+ trans_stx_w(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stgt_d(DisasContext *ctx, arg_stgt_d *a) -+{ -+ ASRTGT; -+ DECL_ARG(stx_d) -+ trans_stx_d(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stle_b(DisasContext *ctx, arg_stle_b *a) -+{ -+ ASRTLE; -+ DECL_ARG(stx_b) -+ trans_stx_b(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stle_h(DisasContext *ctx, arg_stle_h *a) -+{ -+ ASRTLE; -+ DECL_ARG(stx_h) -+ trans_stx_h(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stle_w(DisasContext *ctx, arg_stle_w *a) -+{ -+ ASRTLE; -+ DECL_ARG(stx_w) -+ trans_stx_w(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stle_d(DisasContext *ctx, arg_stle_d *a) -+{ -+ ASRTLE; -+ DECL_ARG(stx_d) -+ trans_stx_d(ctx, &arg); -+ return true; -+} -+ -+#undef ASRTGT -+#undef ASRTLE -+#undef DECL_ARG -+ -+static bool trans_beqz(DisasContext *ctx, arg_beqz *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BEQZ, 4, a->rj, 0, a->offs21 << 2); -+ return true; -+} -+ -+static bool trans_bnez(DisasContext *ctx, arg_bnez *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BNEZ, 4, a->rj, 0, a->offs21 << 2); -+ return true; -+} -+ -+static bool trans_bceqz(DisasContext *ctx, arg_bceqz *a) -+{ -+ TCGv_i32 cj = tcg_const_i32(a->cj); -+ TCGv v0 = tcg_temp_new(); -+ TCGv v1 = tcg_const_i64(0); -+ -+ gen_helper_movcf2reg(v0, cpu_env, cj); -+ tcg_gen_setcond_tl(TCG_COND_EQ, bcond, v0, v1); -+ ctx->hflags |= LARCH_HFLAG_BC; -+ ctx->btarget = ctx->base.pc_next + (a->offs21 << 2); -+ -+ tcg_temp_free_i32(cj); -+ tcg_temp_free(v0); -+ tcg_temp_free(v1); -+ return true; -+} -+ -+static bool trans_bcnez(DisasContext *ctx, arg_bcnez *a) -+{ -+ TCGv_i32 cj = tcg_const_i32(a->cj); -+ TCGv v0 = tcg_temp_new(); -+ TCGv v1 = tcg_const_i64(0); -+ -+ gen_helper_movcf2reg(v0, cpu_env, cj); -+ tcg_gen_setcond_tl(TCG_COND_NE, bcond, v0, v1); -+ ctx->hflags |= LARCH_HFLAG_BC; -+ ctx->btarget = ctx->base.pc_next + (a->offs21 << 2); -+ -+ tcg_temp_free_i32(cj); -+ tcg_temp_free(v0); -+ tcg_temp_free(v1); -+ return true; -+} -+ -+static bool trans_b(DisasContext *ctx, arg_b *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_B, 4, 0, 0, a->offs << 2); -+ return true; -+} -+ -+static bool trans_bl(DisasContext *ctx, arg_bl *a) -+{ -+ ctx->btarget = ctx->base.pc_next + (a->offs << 2); -+ tcg_gen_movi_tl(cpu_gpr[1], ctx->base.pc_next + 4); -+ ctx->hflags |= LARCH_HFLAG_B; -+ gen_branch(ctx, 4); -+ return true; -+} -+ -+static bool trans_blt(DisasContext *ctx, arg_blt *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BLT, 4, a->rj, a->rd, a->offs16 << 2); -+ return true; -+} -+ -+static bool trans_bge(DisasContext *ctx, arg_bge *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BGE, 4, a->rj, a->rd, a->offs16 << 2); -+ return true; -+} -+ -+static bool trans_bltu(DisasContext *ctx, arg_bltu *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BLTU, 4, a->rj, a->rd, a->offs16 << 2); -+ return true; -+} -+ -+static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BGEU, 4, a->rj, a->rd, a->offs16 << 2); -+ return true; -+} -+ -+static bool trans_beq(DisasContext *ctx, arg_beq *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BEQ, 4, a->rj, a->rd, a->offs16 << 2); -+ return true; -+} -+ -+static bool trans_bne(DisasContext *ctx, arg_bne *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BNE, 4, a->rj, a->rd, a->offs16 << 2); -+ return true; -+} -+ -+static bool trans_jirl(DisasContext *ctx, arg_jirl *a) -+{ -+ gen_base_offset_addr(ctx, btarget, a->rj, a->offs16 << 2); -+ if (a->rd != 0) { -+ tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->base.pc_next + 4); -+ } -+ ctx->hflags |= LARCH_HFLAG_BR; -+ gen_branch(ctx, 4); -+ -+ return true; -+} -+ -+#define TRANS_F4FR(name, fmt, op, bits) \ -+static bool trans_ ## name ## _ ## fmt(DisasContext *ctx, \ -+ arg_##name##_##fmt * a) \ -+{ \ -+ check_cp1_enabled(ctx); \ -+ TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ -+ TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ -+ TCGv_i ## bits fp2 = tcg_temp_new_i ## bits(); \ -+ TCGv_i ## bits fp3 = tcg_temp_new_i ## bits(); \ -+ check_cp1_enabled(ctx); \ -+ gen_load_fpr ## bits(ctx, fp0, a->fj); \ -+ gen_load_fpr ## bits(ctx, fp1, a->fk); \ -+ gen_load_fpr ## bits(ctx, fp2, a->fa); \ -+ gen_helper_float_ ## op ## _ ## fmt(fp3, \ -+ cpu_env, fp0, fp1, fp2); \ -+ gen_store_fpr ## bits(ctx, fp3, a->fd); \ -+ tcg_temp_free_i ## bits(fp3); \ -+ tcg_temp_free_i ## bits(fp2); \ -+ tcg_temp_free_i ## bits(fp1); \ -+ tcg_temp_free_i ## bits(fp0); \ -+ return true; \ -+} -+ -+TRANS_F4FR(fmadd , s, maddf , 32) /* trans_fmadd_s */ -+TRANS_F4FR(fmadd , d, maddf , 64) /* trans_fmadd_d */ -+TRANS_F4FR(fmsub , s, msubf , 32) /* trans_fmsub_s */ -+TRANS_F4FR(fmsub , d, msubf , 64) /* trans_fmsub_d */ -+TRANS_F4FR(fnmadd, s, nmaddf, 32) /* trans_fnmadd_s */ -+TRANS_F4FR(fnmadd, d, nmaddf, 64) /* trans_fnmadd_d */ -+TRANS_F4FR(fnmsub, s, nmsubf, 32) /* trans_fnmsub_s */ -+TRANS_F4FR(fnmsub, d, nmsubf, 64) /* trans_fnmsub_d */ -+#undef TRANS_F4FR -+ -+static bool trans_fadd_s(DisasContext *ctx, arg_fadd_s * a) -+{ -+ gen_farith(ctx, OPC_LARCH_FADD_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fadd_d(DisasContext *ctx, arg_fadd_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FADD_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fsub_s(DisasContext *ctx, arg_fsub_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FSUB_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fsub_d(DisasContext *ctx, arg_fsub_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FSUB_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmul_s(DisasContext *ctx, arg_fmul_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMUL_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmul_d(DisasContext *ctx, arg_fmul_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMUL_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fdiv_s(DisasContext *ctx, arg_fdiv_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FDIV_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fdiv_d(DisasContext *ctx, arg_fdiv_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FDIV_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmax_s(DisasContext *ctx, arg_fmax_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMAX_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmax_d(DisasContext *ctx, arg_fmax_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMAX_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmin_s(DisasContext *ctx, arg_fmin_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMIN_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmin_d(DisasContext *ctx, arg_fmin_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMIN_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmaxa_s(DisasContext *ctx, arg_fmaxa_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMAXA_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmaxa_d(DisasContext *ctx, arg_fmaxa_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMAXA_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmina_s(DisasContext *ctx, arg_fmina_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMINA_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmina_d(DisasContext *ctx, arg_fmina_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMINA_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fscaleb_s(DisasContext *ctx, arg_fscaleb_s *a) -+{ -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr32(ctx, fp0, a->fj); -+ gen_load_fpr32(ctx, fp1, a->fk); -+ gen_helper_float_exp2_s(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i32(fp1); -+ gen_store_fpr32(ctx, fp0, a->fd); -+ tcg_temp_free_i32(fp0); -+ return true; -+} -+ -+static bool trans_fscaleb_d(DisasContext *ctx, arg_fscaleb_d *a) -+{ -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr64(ctx, fp0, a->fj); -+ gen_load_fpr64(ctx, fp1, a->fk); -+ gen_helper_float_exp2_d(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i64(fp1); -+ gen_store_fpr64(ctx, fp0, a->fd); -+ tcg_temp_free_i64(fp0); -+ return true; -+} -+ -+static bool trans_fcopysign_s(DisasContext *ctx, arg_fcopysign_s *a) -+{ -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ TCGv_i32 fp2 = tcg_temp_new_i32(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr32(ctx, fp0, a->fj); -+ gen_load_fpr32(ctx, fp1, a->fk); -+ tcg_gen_deposit_i32(fp2, fp1, fp0, 0, 31); -+ gen_store_fpr32(ctx, fp2, a->fd); -+ -+ tcg_temp_free_i32(fp2); -+ tcg_temp_free_i32(fp1); -+ tcg_temp_free_i32(fp0); -+ return true; -+} -+ -+static bool trans_fcopysign_d(DisasContext *ctx, arg_fcopysign_d *a) -+{ -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ TCGv_i64 fp2 = tcg_temp_new_i64(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr64(ctx, fp0, a->fj); -+ gen_load_fpr64(ctx, fp1, a->fk); -+ tcg_gen_deposit_i64(fp2, fp1, fp0, 0, 63); -+ gen_store_fpr64(ctx, fp2, a->fd); -+ -+ tcg_temp_free_i64(fp2); -+ tcg_temp_free_i64(fp1); -+ tcg_temp_free_i64(fp0); -+ return true; -+} -+ -+static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FABS_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FABS_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FNEG_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FNEG_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_flogb_s(DisasContext *ctx, arg_flogb_s *a) -+{ -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr32(ctx, fp0, a->fj); -+ gen_helper_float_logb_s(fp1, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp1, a->fd); -+ -+ tcg_temp_free_i32(fp0); -+ tcg_temp_free_i32(fp1); -+ return true; -+} -+ -+static bool trans_flogb_d(DisasContext *ctx, arg_flogb_d *a) -+{ -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr64(ctx, fp0, a->fj); -+ gen_helper_float_logb_d(fp1, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp1, a->fd); -+ -+ tcg_temp_free_i64(fp0); -+ tcg_temp_free_i64(fp1); -+ return true; -+} -+ -+static bool trans_fclass_s(DisasContext *ctx, arg_fclass_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FCLASS_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FCLASS_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fsqrt_s(DisasContext *ctx, arg_fsqrt_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FSQRT_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fsqrt_d(DisasContext *ctx, arg_fsqrt_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FSQRT_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_frecip_s(DisasContext *ctx, arg_frecip_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FRECIP_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_frecip_d(DisasContext *ctx, arg_frecip_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FRECIP_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_frsqrt_s(DisasContext *ctx, arg_frsqrt_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FRSQRT_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_frsqrt_d(DisasContext *ctx, arg_frsqrt_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FRSQRT_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmov_s(DisasContext *ctx, arg_fmov_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMOV_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmov_d(DisasContext *ctx, arg_fmov_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMOV_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_movgr2fr_w(DisasContext *ctx, arg_movgr2fr_w *a) -+{ -+ gen_cp1(ctx, OPC_LARCH_GR2FR_W, a->rj, a->fd); -+ return true; -+} -+ -+static bool trans_movgr2fr_d(DisasContext *ctx, arg_movgr2fr_d *a) -+{ -+ gen_cp1(ctx, OPC_LARCH_GR2FR_D, a->rj, a->fd); -+ return true; -+} -+ -+static bool trans_movgr2frh_w(DisasContext *ctx, arg_movgr2frh_w *a) -+{ -+ gen_cp1(ctx, OPC_LARCH_GR2FRH_W, a->rj, a->fd); -+ return true; -+} -+ -+static bool trans_movfr2gr_s(DisasContext *ctx, arg_movfr2gr_s *a) -+{ -+ gen_cp1(ctx, OPC_LARCH_FR2GR_S, a->rd, a->fj); -+ return true; -+} -+ -+static bool trans_movfr2gr_d(DisasContext *ctx, arg_movfr2gr_d *a) -+{ -+ gen_cp1(ctx, OPC_LARCH_FR2GR_D, a->rd, a->fj); -+ return true; -+} -+ -+static bool trans_movfrh2gr_s(DisasContext *ctx, arg_movfrh2gr_s *a) -+{ -+ gen_cp1(ctx, OPC_LARCH_FRH2GR_S, a->rd, a->fj); -+ return true; -+} -+ -+static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_gpr(t0, a->rj); -+ save_cpu_state(ctx, 0); -+ { -+ TCGv_i32 fs_tmp = tcg_const_i32(a->fcsrd); -+ gen_helper_0e2i(movgr2fcsr, t0, fs_tmp, a->rj); -+ tcg_temp_free_i32(fs_tmp); -+ } -+ /* Stop translation as we may have changed hflags */ -+ ctx->base.is_jmp = DISAS_STOP; -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ gen_helper_1e0i(movfcsr2gr, t0, a->fcsrs); -+ gen_store_gpr(t0, a->rd); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a) -+{ -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i32 cd = tcg_const_i32(a->cd); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr64(ctx, fp0, a->fj); -+ gen_helper_movreg2cf(cpu_env, cd, fp0); -+ -+ tcg_temp_free_i64(fp0); -+ tcg_temp_free_i32(cd); -+ return true; -+} -+ -+static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv_i32 cj = tcg_const_i32(a->cj); -+ -+ check_cp1_enabled(ctx); -+ gen_helper_movcf2reg(t0, cpu_env, cj); -+ gen_store_fpr64(ctx, t0, a->fd); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv_i32 cd = tcg_const_i32(a->cd); -+ -+ check_cp1_enabled(ctx); -+ gen_load_gpr(t0, a->rj); -+ gen_helper_movreg2cf(cpu_env, cd, t0); -+ -+ tcg_temp_free(t0); -+ tcg_temp_free_i32(cd); -+ return true; -+} -+ -+static bool trans_movcf2gr(DisasContext *ctx, arg_movcf2gr *a) -+{ -+ TCGv_i32 cj = tcg_const_i32(a->cj); -+ -+ check_cp1_enabled(ctx); -+ gen_helper_movcf2reg(cpu_gpr[a->rd], cpu_env, cj); -+ -+ tcg_temp_free_i32(cj); -+ return true; -+} -+ -+static bool trans_fcvt_s_d(DisasContext *ctx, arg_fcvt_s_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FCVT_S_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fcvt_d_s(DisasContext *ctx, arg_fcvt_d_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FCVT_D_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrm_w_s(DisasContext *ctx, arg_ftintrm_l_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRM_W_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrm_w_d(DisasContext *ctx, arg_ftintrm_l_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRM_W_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrm_l_s(DisasContext *ctx, arg_ftintrm_l_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRM_L_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrm_l_d(DisasContext *ctx, arg_ftintrm_l_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRM_L_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrp_w_s(DisasContext *ctx, arg_ftintrp_w_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRP_W_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrp_w_d(DisasContext *ctx, arg_ftintrp_w_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRP_W_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrp_l_s(DisasContext *ctx, arg_ftintrp_l_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRP_L_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrp_l_d(DisasContext *ctx, arg_ftintrp_l_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRP_L_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrz_w_s(DisasContext *ctx, arg_ftintrz_w_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRZ_W_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrz_w_d(DisasContext *ctx, arg_ftintrz_w_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRZ_W_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrz_l_s(DisasContext *ctx, arg_ftintrz_l_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRZ_L_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrz_l_d(DisasContext *ctx, arg_ftintrz_l_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRZ_L_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrne_w_s(DisasContext *ctx, arg_ftintrne_w_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRNE_W_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrne_w_d(DisasContext *ctx, arg_ftintrne_w_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRNE_W_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrne_l_s(DisasContext *ctx, arg_ftintrne_l_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRNE_L_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrne_l_d(DisasContext *ctx, arg_ftintrne_l_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRNE_L_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftint_w_s(DisasContext *ctx, arg_ftint_w_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINT_W_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftint_w_d(DisasContext *ctx, arg_ftint_w_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINT_W_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftint_l_s(DisasContext *ctx, arg_ftint_l_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINT_L_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftint_l_d(DisasContext *ctx, arg_ftint_l_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINT_L_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ffint_s_w(DisasContext *ctx, arg_ffint_s_w *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FFINT_S_W, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ffint_s_l(DisasContext *ctx, arg_ffint_s_l *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FFINT_S_L, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ffint_d_w(DisasContext *ctx, arg_ffint_d_w *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FFINT_D_W, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ffint_d_l(DisasContext *ctx, arg_ffint_d_l *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FFINT_D_L, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_frint_s(DisasContext *ctx, arg_frint_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FRINT_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_frint_d(DisasContext *ctx, arg_frint_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FRINT_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_alsl_w(DisasContext *ctx, arg_alsl_w *a) -+{ -+ gen_lsa(ctx, OPC_LARCH_ALSL_W, a->rd, a->rj, a->rk, a->sa2); -+ return true; -+} -+ -+static bool trans_alsl_wu(DisasContext *ctx, arg_alsl_wu *a) -+{ -+ TCGv t0, t1; -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rj); -+ gen_load_gpr(t1, a->rk); -+ tcg_gen_shli_tl(t0, t0, a->sa2 + 1); -+ tcg_gen_add_tl(t0, t0, t1); -+ tcg_gen_ext32u_tl(cpu_gpr[a->rd], t0); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ -+ return true; -+} -+ -+static bool trans_alsl_d(DisasContext *ctx, arg_alsl_d *a) -+{ -+ check_larch_64(ctx); -+ gen_lsa(ctx, OPC_LARCH_ALSL_D, a->rd, a->rj, a->rk, a->sa2); -+ return true; -+} -+ -+static bool trans_bytepick_w(DisasContext *ctx, arg_bytepick_w *a) -+{ -+ gen_align(ctx, 32, a->rd, a->rj, a->rk, a->sa2); -+ return true; -+} -+ -+static bool trans_bytepick_d(DisasContext *ctx, arg_bytepick_d *a) -+{ -+ check_larch_64(ctx); -+ gen_align(ctx, 64, a->rd, a->rj, a->rk, a->sa3); -+ return true; -+} -+ -+static bool trans_add_w(DisasContext *ctx, arg_add_w *a) -+{ -+ gen_arith(ctx, OPC_LARCH_ADD_W, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_sub_w(DisasContext *ctx, arg_sub_w *a) -+{ -+ gen_arith(ctx, OPC_LARCH_SUB_W, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_add_d(DisasContext *ctx, arg_add_d *a) -+{ -+ gen_arith(ctx, OPC_LARCH_ADD_D, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_sub_d(DisasContext *ctx, arg_sub_d *a) -+{ -+ check_larch_64(ctx); -+ gen_arith(ctx, OPC_LARCH_SUB_D, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_slt(DisasContext *ctx, arg_slt *a) -+{ -+ gen_slt(ctx, OPC_LARCH_SLT, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_sltu(DisasContext *ctx, arg_sltu *a) -+{ -+ gen_slt(ctx, OPC_LARCH_SLTU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_maskeqz(DisasContext *ctx, arg_maskeqz *a) -+{ -+ gen_cond_move(ctx, OPC_LARCH_MASKEQZ, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_masknez(DisasContext *ctx, arg_masknez *a) -+{ -+ gen_cond_move(ctx, OPC_LARCH_MASKNEZ, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_nor(DisasContext *ctx, arg_nor *a) -+{ -+ gen_logic(ctx, OPC_LARCH_NOR, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_and(DisasContext *ctx, arg_and *a) -+{ -+ gen_logic(ctx, OPC_LARCH_AND, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_or(DisasContext *ctx, arg_or *a) -+{ -+ gen_logic(ctx, OPC_LARCH_OR, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_xor(DisasContext *ctx, arg_xor *a) -+{ -+ gen_logic(ctx, OPC_LARCH_XOR, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_orn(DisasContext *ctx, arg_orn *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rk); -+ tcg_gen_not_tl(t0, t0); -+ tcg_gen_or_tl(cpu_gpr[a->rd], cpu_gpr[a->rj], t0); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_andn(DisasContext *ctx, arg_andn *a) -+{ -+ TCGv t0, t1; -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rk); -+ gen_load_gpr(t1, a->rj); -+ tcg_gen_not_tl(t0, t0); -+ tcg_gen_and_tl(cpu_gpr[a->rd], t1, t0); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_sll_w(DisasContext *ctx, arg_sll_w *a) -+{ -+ gen_shift(ctx, OPC_LARCH_SLL_W, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_srl_w(DisasContext *ctx, arg_srl_w *a) -+{ -+ gen_shift(ctx, OPC_LARCH_SRL_W, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_sra_w(DisasContext *ctx, arg_sra_w *a) -+{ -+ gen_shift(ctx, OPC_LARCH_SRA_W, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_sll_d(DisasContext *ctx, arg_sll_d *a) -+{ -+ check_larch_64(ctx); -+ gen_shift(ctx, OPC_LARCH_SLL_D, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_srl_d(DisasContext *ctx, arg_srl_d *a) -+{ -+ check_larch_64(ctx); -+ gen_shift(ctx, OPC_LARCH_SRL_D, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_sra_d(DisasContext *ctx, arg_sra_d *a) -+{ -+ check_larch_64(ctx); -+ gen_shift(ctx, OPC_LARCH_SRA_D, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_rotr_w(DisasContext *ctx, arg_rotr_w *a) -+{ -+ gen_shift(ctx, OPC_LARCH_ROTR_W, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_rotr_d(DisasContext *ctx, arg_rotr_d *a) -+{ -+ check_larch_64(ctx); -+ gen_shift(ctx, OPC_LARCH_ROTR_D, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_crc_w_b_w(DisasContext *ctx, arg_crc_w_b_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 1, 0); -+ return true; -+} -+ -+static bool trans_crc_w_h_w(DisasContext *ctx, arg_crc_w_h_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 2, 0); -+ return true; -+} -+ -+static bool trans_crc_w_w_w(DisasContext *ctx, arg_crc_w_w_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 4, 0); -+ return true; -+} -+ -+static bool trans_crc_w_d_w(DisasContext *ctx, arg_crc_w_d_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 8, 0); -+ return true; -+} -+ -+static bool trans_crcc_w_b_w(DisasContext *ctx, arg_crcc_w_b_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 1, 1); -+ return true; -+} -+ -+static bool trans_crcc_w_h_w(DisasContext *ctx, arg_crcc_w_h_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 2, 1); -+ return true; -+} -+ -+static bool trans_crcc_w_w_w(DisasContext *ctx, arg_crcc_w_w_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 4, 1); -+ return true; -+} -+ -+static bool trans_crcc_w_d_w(DisasContext *ctx, arg_crcc_w_d_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 8, 1); -+ return true; -+} -+ -+static bool trans_mul_w(DisasContext *ctx, arg_mul_w *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_MUL_W, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mulh_w(DisasContext *ctx, arg_mulh_w *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_MULH_W, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mulh_wu(DisasContext *ctx, arg_mulh_wu *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_MULH_WU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mul_d(DisasContext *ctx, arg_mul_d *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_MUL_D, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mulh_d(DisasContext *ctx, arg_mulh_d *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_MULH_D, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mulh_du(DisasContext *ctx, arg_mulh_du *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_MULH_DU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mulw_d_w(DisasContext *ctx, arg_mulw_d_w *a) -+{ -+ TCGv_i64 t0 = tcg_temp_new_i64(); -+ TCGv_i64 t1 = tcg_temp_new_i64(); -+ TCGv_i64 t2 = tcg_temp_new_i64(); -+ gen_load_gpr(t0, a->rj); -+ gen_load_gpr(t1, a->rk); -+ tcg_gen_ext32s_i64(t0, t0); -+ tcg_gen_ext32s_i64(t1, t1); -+ tcg_gen_mul_i64(t2, t0, t1); -+ gen_store_gpr(t2, a->rd); -+ tcg_temp_free_i64(t0); -+ tcg_temp_free_i64(t1); -+ tcg_temp_free_i64(t2); -+ return true; -+} -+ -+static bool trans_mulw_d_wu(DisasContext *ctx, arg_mulw_d_wu *a) -+{ -+ TCGv_i64 t0 = tcg_temp_new_i64(); -+ TCGv_i64 t1 = tcg_temp_new_i64(); -+ TCGv_i64 t2 = tcg_temp_new_i64(); -+ gen_load_gpr(t0, a->rj); -+ gen_load_gpr(t1, a->rk); -+ tcg_gen_ext32u_i64(t0, t0); -+ tcg_gen_ext32u_i64(t1, t1); -+ tcg_gen_mul_i64(t2, t0, t1); -+ gen_store_gpr(t2, a->rd); -+ tcg_temp_free_i64(t0); -+ tcg_temp_free_i64(t1); -+ tcg_temp_free_i64(t2); -+ return true; -+} -+ -+static bool trans_div_w(DisasContext *ctx, arg_div_w *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_DIV_W, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mod_w(DisasContext *ctx, arg_mod_w *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_MOD_W, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_div_wu(DisasContext *ctx, arg_div_wu *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_DIV_WU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mod_wu(DisasContext *ctx, arg_mod_wu *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_MOD_WU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_div_d(DisasContext *ctx, arg_div_d *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_DIV_D, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mod_d(DisasContext *ctx, arg_mod_d *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_MOD_D, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_div_du(DisasContext *ctx, arg_div_du *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_DIV_DU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mod_du(DisasContext *ctx, arg_mod_du *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_MOD_DU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+/* do not update CP0.BadVaddr */ -+static bool trans_asrtle_d(DisasContext *ctx, arg_asrtle_d * a) -+{ -+ TCGv t1 = tcg_temp_new(); -+ TCGv t2 = tcg_temp_new(); -+ gen_load_gpr(t1, a->rj); -+ gen_load_gpr(t2, a->rk); -+ gen_helper_asrtle_d(cpu_env, t1, t2); -+ tcg_temp_free(t1); -+ tcg_temp_free(t2); -+ return true; -+} -+ -+/* do not update CP0.BadVaddr */ -+static bool trans_asrtgt_d(DisasContext *ctx, arg_asrtgt_d * a) -+{ -+ TCGv t1 = tcg_temp_new(); -+ TCGv t2 = tcg_temp_new(); -+ gen_load_gpr(t1, a->rj); -+ gen_load_gpr(t2, a->rk); -+ gen_helper_asrtgt_d(cpu_env, t1, t2); -+ tcg_temp_free(t1); -+ tcg_temp_free(t2); -+ return true; -+} -+ -+#ifdef CONFIG_USER_ONLY -+static bool trans_gr2scr(DisasContext *ctx, arg_gr2scr *a) -+{ -+ return false; -+} -+ -+static bool trans_scr2gr(DisasContext *ctx, arg_scr2gr *a) -+{ -+ return false; -+} -+#else -+static bool trans_gr2scr(DisasContext *ctx, arg_gr2scr *a) -+{ -+ TCGv_i32 sd = tcg_const_i32(a->sd); -+ TCGv val = tcg_temp_new(); -+ check_lbt_enabled(ctx); -+ gen_load_gpr(val, a->rj); -+ gen_helper_store_scr(cpu_env, sd, val); -+ tcg_temp_free_i32(sd); -+ tcg_temp_free(val); -+ return true; -+} -+ -+static bool trans_scr2gr(DisasContext *ctx, arg_scr2gr *a) -+{ -+ if (a->rd == 0) { -+ /* Nop */ -+ return true; -+ } -+ -+ TCGv_i32 tsj = tcg_const_i32(a->sj); -+ check_lbt_enabled(ctx); -+ gen_helper_load_scr(cpu_gpr[a->rd], cpu_env, tsj); -+ tcg_temp_free_i32(tsj); -+ return true; -+} -+#endif -+ -+static bool trans_clo_w(DisasContext *ctx, arg_clo_w *a) -+{ -+ gen_cl(ctx, OPC_LARCH_CLO_W, a->rd, a->rj); -+ return true; -+} -+ -+static bool trans_clz_w(DisasContext *ctx, arg_clz_w *a) -+{ -+ gen_cl(ctx, OPC_LARCH_CLZ_W, a->rd, a->rj); -+ return true; -+} -+ -+static bool trans_cto_w(DisasContext *ctx, arg_cto_w *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ gen_helper_cto_w(cpu_gpr[a->rd], cpu_env, t0); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_ctz_w(DisasContext *ctx, arg_ctz_w *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ gen_helper_ctz_w(cpu_gpr[a->rd], cpu_env, t0); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_clo_d(DisasContext *ctx, arg_clo_d *a) -+{ -+ check_larch_64(ctx); -+ gen_cl(ctx, OPC_LARCH_CLO_D, a->rd, a->rj); -+ return true; -+} -+ -+static bool trans_clz_d(DisasContext *ctx, arg_clz_d *a) -+{ -+ check_larch_64(ctx); -+ gen_cl(ctx, OPC_LARCH_CLZ_D, a->rd, a->rj); -+ return true; -+} -+ -+static bool trans_cto_d(DisasContext *ctx, arg_cto_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ gen_helper_cto_d(cpu_gpr[a->rd], cpu_env, t0); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_ctz_d(DisasContext *ctx, arg_ctz_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ gen_helper_ctz_d(cpu_gpr[a->rd], cpu_env, t0); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_revb_2h(DisasContext *ctx, arg_revb_2h *a) -+{ -+ gen_bshfl(ctx, OPC_LARCH_REVB_2H, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_revb_4h(DisasContext *ctx, arg_revb_4h *a) -+{ -+ check_larch_64(ctx); -+ gen_bshfl(ctx, OPC_LARCH_REVB_4H, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_revb_2w(DisasContext *ctx, arg_revb_2w *a) -+{ -+ handle_rev32(ctx, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_revb_d(DisasContext *ctx, arg_revb_d *a) -+{ -+ handle_rev64(ctx, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_revh_2w(DisasContext *ctx, arg_revh_2w *a) -+{ -+ handle_rev16(ctx, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_revh_d(DisasContext *ctx, arg_revh_d *a) -+{ -+ check_larch_64(ctx); -+ gen_bshfl(ctx, OPC_LARCH_REVH_D, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_bitrev_4b(DisasContext *ctx, arg_bitrev_4b *a) -+{ -+ gen_bitswap(ctx, OPC_LARCH_BREV_4B, a->rd, a->rj); -+ return true; -+} -+ -+static bool trans_bitrev_8b(DisasContext *ctx, arg_bitrev_8b *a) -+{ -+ check_larch_64(ctx); -+ gen_bitswap(ctx, OPC_LARCH_BREV_8B, a->rd, a->rj); -+ return true; -+} -+ -+static bool trans_bitrev_w(DisasContext *ctx, arg_bitrev_w *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rj); -+ gen_helper_bitrev_w(cpu_gpr[a->rd], cpu_env, t0); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_bitrev_d(DisasContext *ctx, arg_bitrev_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rj); -+ gen_helper_bitrev_d(cpu_gpr[a->rd], cpu_env, t0); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_ext_w_h(DisasContext *ctx, arg_ext_w_h *a) -+{ -+ gen_bshfl(ctx, OPC_LARCH_EXT_WH, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_ext_w_b(DisasContext *ctx, arg_ext_w_b *a) -+{ -+ gen_bshfl(ctx, OPC_LARCH_EXT_WB, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_srli_w(DisasContext *ctx, arg_srli_w *a) -+{ -+ gen_shift_imm(ctx, OPC_LARCH_SRLI_W, a->rd, a->rj, a->ui5); -+ return true; -+} -+ -+static bool trans_srai_w(DisasContext *ctx, arg_srai_w *a) -+{ -+ gen_shift_imm(ctx, OPC_LARCH_SRAI_W, a->rd, a->rj, a->ui5); -+ return true; -+} -+ -+static bool trans_srai_d(DisasContext *ctx, arg_srai_d *a) -+{ -+ TCGv t0; -+ check_larch_64(ctx); -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rj); -+ tcg_gen_sari_tl(cpu_gpr[a->rd], t0, a->ui6); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_rotri_w(DisasContext *ctx, arg_rotri_w *a) -+{ -+ gen_shift_imm(ctx, OPC_LARCH_ROTRI_W, a->rd, a->rj, a->ui5); -+ return true; -+} -+ -+static bool trans_rotri_d(DisasContext *ctx, arg_rotri_d *a) -+{ -+ TCGv t0; -+ check_larch_64(ctx); -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rj); -+ tcg_gen_rotri_tl(cpu_gpr[a->rd], t0, a->ui6); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a) -+{ -+ check_cp1_enabled(ctx); -+ gen_fcmp_s(ctx, a->fcond, a->fk, a->fj, a->cd); -+ return true; -+} -+ -+static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a) -+{ -+ check_cp1_enabled(ctx); -+ gen_fcmp_d(ctx, a->fcond, a->fk, a->fj, a->cd); -+ return true; -+} -+ -+static bool trans_fsel(DisasContext *ctx, arg_fsel *a) -+{ -+ TCGv_i64 fj = tcg_temp_new_i64(); -+ TCGv_i64 fk = tcg_temp_new_i64(); -+ TCGv_i64 fd = tcg_temp_new_i64(); -+ TCGv_i32 ca = tcg_const_i32(a->ca); -+ check_cp1_enabled(ctx); -+ gen_load_fpr64(ctx, fj, a->fj); -+ gen_load_fpr64(ctx, fk, a->fk); -+ gen_helper_fsel(fd, cpu_env, fj, fk, ca); -+ gen_store_fpr64(ctx, fd, a->fd); -+ tcg_temp_free_i64(fj); -+ tcg_temp_free_i64(fk); -+ tcg_temp_free_i64(fd); -+ tcg_temp_free_i32(ca); -+ return true; -+} -+ -+#include "cpu-csr.h" -+ -+#ifdef CONFIG_USER_ONLY -+ -+static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) -+{ -+ return false; -+} -+ -+#else -+ -+ -+#define GEN_CSRRQ_CASE(name) \ -+ do { \ -+ case LOONGARCH_CSR_ ## name: \ -+ gen_csr_rdq(ctx, cpu_gpr[rd], LOONGARCH_CSR_ ## name);\ -+ } while (0) -+ -+static bool trans_csrrd(DisasContext *ctx, unsigned rd, unsigned csr) -+{ -+ switch (csr) { -+ GEN_CSRRQ_CASE(CRMD); -+ break; -+ GEN_CSRRQ_CASE(PRMD); -+ break; -+ GEN_CSRRQ_CASE(EUEN); -+ break; -+ GEN_CSRRQ_CASE(MISC); -+ break; -+ GEN_CSRRQ_CASE(ECFG); -+ break; -+ GEN_CSRRQ_CASE(ESTAT); -+ break; -+ GEN_CSRRQ_CASE(ERA); -+ break; -+ GEN_CSRRQ_CASE(BADV); -+ break; -+ GEN_CSRRQ_CASE(BADI); -+ break; -+ GEN_CSRRQ_CASE(EEPN); -+ break; -+ GEN_CSRRQ_CASE(TLBIDX); -+ break; -+ GEN_CSRRQ_CASE(TLBEHI); -+ break; -+ GEN_CSRRQ_CASE(TLBELO0); -+ break; -+ GEN_CSRRQ_CASE(TLBELO1); -+ break; -+ GEN_CSRRQ_CASE(TLBWIRED); -+ break; -+ GEN_CSRRQ_CASE(GTLBC); -+ break; -+ GEN_CSRRQ_CASE(TRGP); -+ break; -+ GEN_CSRRQ_CASE(ASID); -+ break; -+ GEN_CSRRQ_CASE(PGDL); -+ break; -+ GEN_CSRRQ_CASE(PGDH); -+ break; -+ case LOONGARCH_CSR_PGD: -+ gen_helper_read_pgd(cpu_gpr[rd], cpu_env); -+ break; -+ GEN_CSRRQ_CASE(PWCTL0); -+ break; -+ GEN_CSRRQ_CASE(PWCTL1); -+ break; -+ GEN_CSRRQ_CASE(STLBPGSIZE); -+ break; -+ GEN_CSRRQ_CASE(RVACFG); -+ break; -+ GEN_CSRRQ_CASE(CPUID); -+ break; -+ GEN_CSRRQ_CASE(PRCFG1); -+ break; -+ GEN_CSRRQ_CASE(PRCFG2); -+ break; -+ GEN_CSRRQ_CASE(PRCFG3); -+ break; -+ GEN_CSRRQ_CASE(KS0); -+ break; -+ GEN_CSRRQ_CASE(KS1); -+ break; -+ GEN_CSRRQ_CASE(KS2); -+ break; -+ GEN_CSRRQ_CASE(KS3); -+ break; -+ GEN_CSRRQ_CASE(KS4); -+ break; -+ GEN_CSRRQ_CASE(KS5); -+ break; -+ GEN_CSRRQ_CASE(KS6); -+ break; -+ GEN_CSRRQ_CASE(KS7); -+ break; -+ GEN_CSRRQ_CASE(KS8); -+ break; -+ GEN_CSRRQ_CASE(TMID); -+ break; -+ GEN_CSRRQ_CASE(TCFG); -+ break; -+ GEN_CSRRQ_CASE(TVAL); -+ break; -+ GEN_CSRRQ_CASE(CNTC); -+ break; -+ GEN_CSRRQ_CASE(TINTCLR); -+ break; -+ GEN_CSRRQ_CASE(GSTAT); -+ break; -+ GEN_CSRRQ_CASE(GCFG); -+ break; -+ GEN_CSRRQ_CASE(GINTC); -+ break; -+ GEN_CSRRQ_CASE(GCNTC); -+ break; -+ GEN_CSRRQ_CASE(LLBCTL); -+ break; -+ GEN_CSRRQ_CASE(IMPCTL1); -+ break; -+ GEN_CSRRQ_CASE(IMPCTL2); -+ break; -+ GEN_CSRRQ_CASE(GNMI); -+ break; -+ GEN_CSRRQ_CASE(TLBRENT); -+ break; -+ GEN_CSRRQ_CASE(TLBRBADV); -+ break; -+ GEN_CSRRQ_CASE(TLBRERA); -+ break; -+ GEN_CSRRQ_CASE(TLBRSAVE); -+ break; -+ GEN_CSRRQ_CASE(TLBRELO0); -+ break; -+ GEN_CSRRQ_CASE(TLBRELO1); -+ break; -+ GEN_CSRRQ_CASE(TLBREHI); -+ break; -+ GEN_CSRRQ_CASE(TLBRPRMD); -+ break; -+ GEN_CSRRQ_CASE(ERRCTL); -+ break; -+ GEN_CSRRQ_CASE(ERRINFO); -+ break; -+ GEN_CSRRQ_CASE(ERRINFO1); -+ break; -+ GEN_CSRRQ_CASE(ERRENT); -+ break; -+ GEN_CSRRQ_CASE(ERRERA); -+ break; -+ GEN_CSRRQ_CASE(ERRSAVE); -+ break; -+ GEN_CSRRQ_CASE(CTAG); -+ break; -+ GEN_CSRRQ_CASE(DMWIN0); -+ break; -+ GEN_CSRRQ_CASE(DMWIN1); -+ break; -+ GEN_CSRRQ_CASE(DMWIN2); -+ break; -+ GEN_CSRRQ_CASE(DMWIN3); -+ break; -+ GEN_CSRRQ_CASE(PERFCTRL0); -+ break; -+ GEN_CSRRQ_CASE(PERFCNTR0); -+ break; -+ GEN_CSRRQ_CASE(PERFCTRL1); -+ break; -+ GEN_CSRRQ_CASE(PERFCNTR1); -+ break; -+ GEN_CSRRQ_CASE(PERFCTRL2); -+ break; -+ GEN_CSRRQ_CASE(PERFCNTR2); -+ break; -+ GEN_CSRRQ_CASE(PERFCTRL3); -+ break; -+ GEN_CSRRQ_CASE(PERFCNTR3); -+ break; -+ /* debug */ -+ GEN_CSRRQ_CASE(MWPC); -+ break; -+ GEN_CSRRQ_CASE(MWPS); -+ break; -+ GEN_CSRRQ_CASE(DB0ADDR); -+ break; -+ GEN_CSRRQ_CASE(DB0MASK); -+ break; -+ GEN_CSRRQ_CASE(DB0CTL); -+ break; -+ GEN_CSRRQ_CASE(DB0ASID); -+ break; -+ GEN_CSRRQ_CASE(DB1ADDR); -+ break; -+ GEN_CSRRQ_CASE(DB1MASK); -+ break; -+ GEN_CSRRQ_CASE(DB1CTL); -+ break; -+ GEN_CSRRQ_CASE(DB1ASID); -+ break; -+ GEN_CSRRQ_CASE(DB2ADDR); -+ break; -+ GEN_CSRRQ_CASE(DB2MASK); -+ break; -+ GEN_CSRRQ_CASE(DB2CTL); -+ break; -+ GEN_CSRRQ_CASE(DB2ASID); -+ break; -+ GEN_CSRRQ_CASE(DB3ADDR); -+ break; -+ GEN_CSRRQ_CASE(DB3MASK); -+ break; -+ GEN_CSRRQ_CASE(DB3CTL); -+ break; -+ GEN_CSRRQ_CASE(DB3ASID); -+ break; -+ GEN_CSRRQ_CASE(FWPC); -+ break; -+ GEN_CSRRQ_CASE(FWPS); -+ break; -+ GEN_CSRRQ_CASE(IB0ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB0MASK); -+ break; -+ GEN_CSRRQ_CASE(IB0CTL); -+ break; -+ GEN_CSRRQ_CASE(IB0ASID); -+ break; -+ GEN_CSRRQ_CASE(IB1ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB1MASK); -+ break; -+ GEN_CSRRQ_CASE(IB1CTL); -+ break; -+ GEN_CSRRQ_CASE(IB1ASID); -+ break; -+ GEN_CSRRQ_CASE(IB2ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB2MASK); -+ break; -+ GEN_CSRRQ_CASE(IB2CTL); -+ break; -+ GEN_CSRRQ_CASE(IB2ASID); -+ break; -+ GEN_CSRRQ_CASE(IB3ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB3MASK); -+ break; -+ GEN_CSRRQ_CASE(IB3CTL); -+ break; -+ GEN_CSRRQ_CASE(IB3ASID); -+ break; -+ GEN_CSRRQ_CASE(IB4ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB4MASK); -+ break; -+ GEN_CSRRQ_CASE(IB4CTL); -+ break; -+ GEN_CSRRQ_CASE(IB4ASID); -+ break; -+ GEN_CSRRQ_CASE(IB5ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB5MASK); -+ break; -+ GEN_CSRRQ_CASE(IB5CTL); -+ break; -+ GEN_CSRRQ_CASE(IB5ASID); -+ break; -+ GEN_CSRRQ_CASE(IB6ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB6MASK); -+ break; -+ GEN_CSRRQ_CASE(IB6CTL); -+ break; -+ GEN_CSRRQ_CASE(IB6ASID); -+ break; -+ GEN_CSRRQ_CASE(IB7ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB7MASK); -+ break; -+ GEN_CSRRQ_CASE(IB7CTL); -+ break; -+ GEN_CSRRQ_CASE(IB7ASID); -+ break; -+ GEN_CSRRQ_CASE(DEBUG); -+ break; -+ GEN_CSRRQ_CASE(DERA); -+ break; -+ GEN_CSRRQ_CASE(DESAVE); -+ break; -+ default: -+ return false; -+ } -+ -+ #undef GEN_CSRRQ_CASE -+ -+ return true; -+} -+ -+#define GEN_CSRWQ_CASE(name) \ -+do { \ -+ case LOONGARCH_CSR_ ## name: \ -+ gen_csr_wrq(ctx, cpu_gpr[rd], LOONGARCH_CSR_ ## name); \ -+} while (0) -+ -+static bool trans_csrwr(DisasContext *ctx, unsigned rd, unsigned csr) -+{ -+ -+ switch (csr) { -+ case LOONGARCH_CSR_CRMD: -+ save_cpu_state(ctx, 1); -+ gen_csr_wrq(ctx, cpu_gpr[rd], LOONGARCH_CSR_CRMD); -+ gen_save_pc(ctx->base.pc_next + 4); -+ ctx->base.is_jmp = DISAS_EXIT; -+ break; -+ GEN_CSRWQ_CASE(PRMD); -+ break; -+ case LOONGARCH_CSR_EUEN: -+ gen_csr_wrq(ctx, cpu_gpr[rd], LOONGARCH_CSR_EUEN); -+ /* Stop translation */ -+ gen_save_pc(ctx->base.pc_next + 4); -+ ctx->base.is_jmp = DISAS_EXIT; -+ break; -+ GEN_CSRWQ_CASE(MISC); -+ break; -+ GEN_CSRWQ_CASE(ECFG); -+ break; -+ GEN_CSRWQ_CASE(ESTAT); -+ break; -+ GEN_CSRWQ_CASE(ERA); -+ break; -+ GEN_CSRWQ_CASE(BADV); -+ break; -+ GEN_CSRWQ_CASE(BADI); -+ break; -+ GEN_CSRWQ_CASE(EEPN); -+ break; -+ GEN_CSRWQ_CASE(TLBIDX); -+ break; -+ GEN_CSRWQ_CASE(TLBEHI); -+ break; -+ GEN_CSRWQ_CASE(TLBELO0); -+ break; -+ GEN_CSRWQ_CASE(TLBELO1); -+ break; -+ GEN_CSRWQ_CASE(TLBWIRED); -+ break; -+ GEN_CSRWQ_CASE(GTLBC); -+ break; -+ GEN_CSRWQ_CASE(TRGP); -+ break; -+ GEN_CSRWQ_CASE(ASID); -+ break; -+ GEN_CSRWQ_CASE(PGDL); -+ break; -+ GEN_CSRWQ_CASE(PGDH); -+ break; -+ GEN_CSRWQ_CASE(PGD); -+ break; -+ GEN_CSRWQ_CASE(PWCTL0); -+ break; -+ GEN_CSRWQ_CASE(PWCTL1); -+ break; -+ GEN_CSRWQ_CASE(STLBPGSIZE); -+ break; -+ GEN_CSRWQ_CASE(RVACFG); -+ break; -+ GEN_CSRWQ_CASE(CPUID); -+ break; -+ GEN_CSRWQ_CASE(PRCFG1); -+ break; -+ GEN_CSRWQ_CASE(PRCFG2); -+ break; -+ GEN_CSRWQ_CASE(PRCFG3); -+ break; -+ GEN_CSRWQ_CASE(KS0); -+ break; -+ GEN_CSRWQ_CASE(KS1); -+ break; -+ GEN_CSRWQ_CASE(KS2); -+ break; -+ GEN_CSRWQ_CASE(KS3); -+ break; -+ GEN_CSRWQ_CASE(KS4); -+ break; -+ GEN_CSRWQ_CASE(KS5); -+ break; -+ GEN_CSRWQ_CASE(KS6); -+ break; -+ GEN_CSRWQ_CASE(KS7); -+ break; -+ GEN_CSRWQ_CASE(KS8); -+ break; -+ GEN_CSRWQ_CASE(TMID); -+ break; -+ GEN_CSRWQ_CASE(TCFG); -+ break; -+ GEN_CSRWQ_CASE(TVAL); -+ break; -+ GEN_CSRWQ_CASE(CNTC); -+ break; -+ GEN_CSRWQ_CASE(TINTCLR); -+ break; -+ GEN_CSRWQ_CASE(GSTAT); -+ break; -+ GEN_CSRWQ_CASE(GCFG); -+ break; -+ GEN_CSRWQ_CASE(GINTC); -+ break; -+ GEN_CSRWQ_CASE(GCNTC); -+ break; -+ GEN_CSRWQ_CASE(LLBCTL); -+ break; -+ GEN_CSRWQ_CASE(IMPCTL1); -+ break; -+ GEN_CSRWQ_CASE(IMPCTL2); -+ break; -+ GEN_CSRWQ_CASE(GNMI); -+ break; -+ GEN_CSRWQ_CASE(TLBRENT); -+ break; -+ GEN_CSRWQ_CASE(TLBRBADV); -+ break; -+ GEN_CSRWQ_CASE(TLBRERA); -+ break; -+ GEN_CSRWQ_CASE(TLBRSAVE); -+ break; -+ GEN_CSRWQ_CASE(TLBRELO0); -+ break; -+ GEN_CSRWQ_CASE(TLBRELO1); -+ break; -+ GEN_CSRWQ_CASE(TLBREHI); -+ break; -+ GEN_CSRWQ_CASE(TLBRPRMD); -+ break; -+ GEN_CSRWQ_CASE(ERRCTL); -+ break; -+ GEN_CSRWQ_CASE(ERRINFO); -+ break; -+ GEN_CSRWQ_CASE(ERRINFO1); -+ break; -+ GEN_CSRWQ_CASE(ERRENT); -+ break; -+ GEN_CSRWQ_CASE(ERRERA); -+ break; -+ GEN_CSRWQ_CASE(ERRSAVE); -+ break; -+ GEN_CSRWQ_CASE(CTAG); -+ break; -+ GEN_CSRWQ_CASE(DMWIN0); -+ break; -+ GEN_CSRWQ_CASE(DMWIN1); -+ break; -+ GEN_CSRWQ_CASE(DMWIN2); -+ break; -+ GEN_CSRWQ_CASE(DMWIN3); -+ break; -+ GEN_CSRWQ_CASE(PERFCTRL0); -+ break; -+ GEN_CSRWQ_CASE(PERFCNTR0); -+ break; -+ GEN_CSRWQ_CASE(PERFCTRL1); -+ break; -+ GEN_CSRWQ_CASE(PERFCNTR1); -+ break; -+ GEN_CSRWQ_CASE(PERFCTRL2); -+ break; -+ GEN_CSRWQ_CASE(PERFCNTR2); -+ break; -+ GEN_CSRWQ_CASE(PERFCTRL3); -+ break; -+ GEN_CSRWQ_CASE(PERFCNTR3); -+ break; -+ /* debug */ -+ GEN_CSRWQ_CASE(MWPC); -+ break; -+ GEN_CSRWQ_CASE(MWPS); -+ break; -+ GEN_CSRWQ_CASE(DB0ADDR); -+ break; -+ GEN_CSRWQ_CASE(DB0MASK); -+ break; -+ GEN_CSRWQ_CASE(DB0CTL); -+ break; -+ GEN_CSRWQ_CASE(DB0ASID); -+ break; -+ GEN_CSRWQ_CASE(DB1ADDR); -+ break; -+ GEN_CSRWQ_CASE(DB1MASK); -+ break; -+ GEN_CSRWQ_CASE(DB1CTL); -+ break; -+ GEN_CSRWQ_CASE(DB1ASID); -+ break; -+ GEN_CSRWQ_CASE(DB2ADDR); -+ break; -+ GEN_CSRWQ_CASE(DB2MASK); -+ break; -+ GEN_CSRWQ_CASE(DB2CTL); -+ break; -+ GEN_CSRWQ_CASE(DB2ASID); -+ break; -+ GEN_CSRWQ_CASE(DB3ADDR); -+ break; -+ GEN_CSRWQ_CASE(DB3MASK); -+ break; -+ GEN_CSRWQ_CASE(DB3CTL); -+ break; -+ GEN_CSRWQ_CASE(DB3ASID); -+ break; -+ GEN_CSRWQ_CASE(FWPC); -+ break; -+ GEN_CSRWQ_CASE(FWPS); -+ break; -+ GEN_CSRWQ_CASE(IB0ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB0MASK); -+ break; -+ GEN_CSRWQ_CASE(IB0CTL); -+ break; -+ GEN_CSRWQ_CASE(IB0ASID); -+ break; -+ GEN_CSRWQ_CASE(IB1ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB1MASK); -+ break; -+ GEN_CSRWQ_CASE(IB1CTL); -+ break; -+ GEN_CSRWQ_CASE(IB1ASID); -+ break; -+ GEN_CSRWQ_CASE(IB2ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB2MASK); -+ break; -+ GEN_CSRWQ_CASE(IB2CTL); -+ break; -+ GEN_CSRWQ_CASE(IB2ASID); -+ break; -+ GEN_CSRWQ_CASE(IB3ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB3MASK); -+ break; -+ GEN_CSRWQ_CASE(IB3CTL); -+ break; -+ GEN_CSRWQ_CASE(IB3ASID); -+ break; -+ GEN_CSRWQ_CASE(IB4ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB4MASK); -+ break; -+ GEN_CSRWQ_CASE(IB4CTL); -+ break; -+ GEN_CSRWQ_CASE(IB4ASID); -+ break; -+ GEN_CSRWQ_CASE(IB5ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB5MASK); -+ break; -+ GEN_CSRWQ_CASE(IB5CTL); -+ break; -+ GEN_CSRWQ_CASE(IB5ASID); -+ break; -+ GEN_CSRWQ_CASE(IB6ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB6MASK); -+ break; -+ GEN_CSRWQ_CASE(IB6CTL); -+ break; -+ GEN_CSRWQ_CASE(IB6ASID); -+ break; -+ GEN_CSRWQ_CASE(IB7ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB7MASK); -+ break; -+ GEN_CSRWQ_CASE(IB7CTL); -+ break; -+ GEN_CSRWQ_CASE(IB7ASID); -+ break; -+ GEN_CSRWQ_CASE(DEBUG); -+ break; -+ GEN_CSRWQ_CASE(DERA); -+ break; -+ GEN_CSRWQ_CASE(DESAVE); -+ break; -+ default: -+ return false; -+ } -+ -+ #undef GEN_CSRWQ_CASE -+ -+ return true; -+} -+ -+#define GEN_CSRXQ_CASE(name) \ -+do { \ -+ case LOONGARCH_CSR_ ## name: \ -+ if (rd == 0) { \ -+ gen_csr_xchgq(ctx, zero, cpu_gpr[rj], \ -+ LOONGARCH_CSR_ ## name); \ -+ } else { \ -+ gen_csr_xchgq(ctx, cpu_gpr[rd], cpu_gpr[rj], \ -+ LOONGARCH_CSR_ ## name); \ -+ } \ -+} while (0) -+ -+static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) -+{ -+ unsigned rd, rj, csr; -+ TCGv zero = tcg_const_tl(0); -+ rd = a->rd; -+ rj = a->rj; -+ csr = a->csr; -+ -+ if (rj == 0) { -+ return trans_csrrd(ctx, rd, csr); -+ } else if (rj == 1) { -+ return trans_csrwr(ctx, rd, csr); -+ } -+ -+ switch (csr) { -+ case LOONGARCH_CSR_CRMD: -+ save_cpu_state(ctx, 1); -+ if (rd == 0) { -+ gen_csr_xchgq(ctx, zero, cpu_gpr[rj], LOONGARCH_CSR_CRMD); -+ } else { -+ gen_csr_xchgq(ctx, cpu_gpr[rd], cpu_gpr[rj], LOONGARCH_CSR_CRMD); -+ } -+ gen_save_pc(ctx->base.pc_next + 4); -+ ctx->base.is_jmp = DISAS_EXIT; -+ break; -+ -+ GEN_CSRXQ_CASE(PRMD); -+ break; -+ case LOONGARCH_CSR_EUEN: -+ if (rd == 0) { -+ gen_csr_xchgq(ctx, zero, cpu_gpr[rj], LOONGARCH_CSR_EUEN); -+ } else { -+ gen_csr_xchgq(ctx, cpu_gpr[rd], cpu_gpr[rj], LOONGARCH_CSR_EUEN); -+ } -+ /* Stop translation */ -+ gen_save_pc(ctx->base.pc_next + 4); -+ ctx->base.is_jmp = DISAS_EXIT; -+ break; -+ GEN_CSRXQ_CASE(MISC); -+ break; -+ GEN_CSRXQ_CASE(ECFG); -+ break; -+ GEN_CSRXQ_CASE(ESTAT); -+ break; -+ GEN_CSRXQ_CASE(ERA); -+ break; -+ GEN_CSRXQ_CASE(BADV); -+ break; -+ GEN_CSRXQ_CASE(BADI); -+ break; -+ GEN_CSRXQ_CASE(EEPN); -+ break; -+ GEN_CSRXQ_CASE(TLBIDX); -+ break; -+ GEN_CSRXQ_CASE(TLBEHI); -+ break; -+ GEN_CSRXQ_CASE(TLBELO0); -+ break; -+ GEN_CSRXQ_CASE(TLBELO1); -+ break; -+ GEN_CSRXQ_CASE(TLBWIRED); -+ break; -+ GEN_CSRXQ_CASE(GTLBC); -+ break; -+ GEN_CSRXQ_CASE(TRGP); -+ break; -+ GEN_CSRXQ_CASE(ASID); -+ break; -+ GEN_CSRXQ_CASE(PGDL); -+ break; -+ GEN_CSRXQ_CASE(PGDH); -+ break; -+ GEN_CSRXQ_CASE(PGD); -+ break; -+ GEN_CSRXQ_CASE(PWCTL0); -+ break; -+ GEN_CSRXQ_CASE(PWCTL1); -+ break; -+ GEN_CSRXQ_CASE(STLBPGSIZE); -+ break; -+ GEN_CSRXQ_CASE(RVACFG); -+ break; -+ GEN_CSRXQ_CASE(CPUID); -+ break; -+ GEN_CSRXQ_CASE(PRCFG1); -+ break; -+ GEN_CSRXQ_CASE(PRCFG2); -+ break; -+ GEN_CSRXQ_CASE(PRCFG3); -+ break; -+ GEN_CSRXQ_CASE(KS0); -+ break; -+ GEN_CSRXQ_CASE(KS1); -+ break; -+ GEN_CSRXQ_CASE(KS2); -+ break; -+ GEN_CSRXQ_CASE(KS3); -+ break; -+ GEN_CSRXQ_CASE(KS4); -+ break; -+ GEN_CSRXQ_CASE(KS5); -+ break; -+ GEN_CSRXQ_CASE(KS6); -+ break; -+ GEN_CSRXQ_CASE(KS7); -+ break; -+ GEN_CSRXQ_CASE(KS8); -+ break; -+ GEN_CSRXQ_CASE(TMID); -+ break; -+ GEN_CSRXQ_CASE(TCFG); -+ break; -+ GEN_CSRXQ_CASE(TVAL); -+ break; -+ GEN_CSRXQ_CASE(CNTC); -+ break; -+ GEN_CSRXQ_CASE(TINTCLR); -+ break; -+ GEN_CSRXQ_CASE(GSTAT); -+ break; -+ GEN_CSRXQ_CASE(GCFG); -+ break; -+ GEN_CSRXQ_CASE(GINTC); -+ break; -+ GEN_CSRXQ_CASE(GCNTC); -+ break; -+ GEN_CSRXQ_CASE(LLBCTL); -+ break; -+ GEN_CSRXQ_CASE(IMPCTL1); -+ break; -+ GEN_CSRXQ_CASE(IMPCTL2); -+ break; -+ GEN_CSRXQ_CASE(GNMI); -+ break; -+ GEN_CSRXQ_CASE(TLBRENT); -+ break; -+ GEN_CSRXQ_CASE(TLBRBADV); -+ break; -+ GEN_CSRXQ_CASE(TLBRERA); -+ break; -+ GEN_CSRXQ_CASE(TLBRSAVE); -+ break; -+ GEN_CSRXQ_CASE(TLBRELO0); -+ break; -+ GEN_CSRXQ_CASE(TLBRELO1); -+ break; -+ GEN_CSRXQ_CASE(TLBREHI); -+ break; -+ GEN_CSRXQ_CASE(TLBRPRMD); -+ break; -+ GEN_CSRXQ_CASE(ERRCTL); -+ break; -+ GEN_CSRXQ_CASE(ERRINFO); -+ break; -+ GEN_CSRXQ_CASE(ERRINFO1); -+ break; -+ GEN_CSRXQ_CASE(ERRENT); -+ break; -+ GEN_CSRXQ_CASE(ERRERA); -+ break; -+ GEN_CSRXQ_CASE(ERRSAVE); -+ break; -+ GEN_CSRXQ_CASE(CTAG); -+ break; -+ GEN_CSRXQ_CASE(DMWIN0); -+ break; -+ GEN_CSRXQ_CASE(DMWIN1); -+ break; -+ GEN_CSRXQ_CASE(DMWIN2); -+ break; -+ GEN_CSRXQ_CASE(DMWIN3); -+ break; -+ GEN_CSRXQ_CASE(PERFCTRL0); -+ break; -+ GEN_CSRXQ_CASE(PERFCNTR0); -+ break; -+ GEN_CSRXQ_CASE(PERFCTRL1); -+ break; -+ GEN_CSRXQ_CASE(PERFCNTR1); -+ break; -+ GEN_CSRXQ_CASE(PERFCTRL2); -+ break; -+ GEN_CSRXQ_CASE(PERFCNTR2); -+ break; -+ GEN_CSRXQ_CASE(PERFCTRL3); -+ break; -+ GEN_CSRXQ_CASE(PERFCNTR3); -+ break; -+ /* debug */ -+ GEN_CSRXQ_CASE(MWPC); -+ break; -+ GEN_CSRXQ_CASE(MWPS); -+ break; -+ GEN_CSRXQ_CASE(DB0ADDR); -+ break; -+ GEN_CSRXQ_CASE(DB0MASK); -+ break; -+ GEN_CSRXQ_CASE(DB0CTL); -+ break; -+ GEN_CSRXQ_CASE(DB0ASID); -+ break; -+ GEN_CSRXQ_CASE(DB1ADDR); -+ break; -+ GEN_CSRXQ_CASE(DB1MASK); -+ break; -+ GEN_CSRXQ_CASE(DB1CTL); -+ break; -+ GEN_CSRXQ_CASE(DB1ASID); -+ break; -+ GEN_CSRXQ_CASE(DB2ADDR); -+ break; -+ GEN_CSRXQ_CASE(DB2MASK); -+ break; -+ GEN_CSRXQ_CASE(DB2CTL); -+ break; -+ GEN_CSRXQ_CASE(DB2ASID); -+ break; -+ GEN_CSRXQ_CASE(DB3ADDR); -+ break; -+ GEN_CSRXQ_CASE(DB3MASK); -+ break; -+ GEN_CSRXQ_CASE(DB3CTL); -+ break; -+ GEN_CSRXQ_CASE(DB3ASID); -+ break; -+ GEN_CSRXQ_CASE(FWPC); -+ break; -+ GEN_CSRXQ_CASE(FWPS); -+ break; -+ GEN_CSRXQ_CASE(IB0ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB0MASK); -+ break; -+ GEN_CSRXQ_CASE(IB0CTL); -+ break; -+ GEN_CSRXQ_CASE(IB0ASID); -+ break; -+ GEN_CSRXQ_CASE(IB1ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB1MASK); -+ break; -+ GEN_CSRXQ_CASE(IB1CTL); -+ break; -+ GEN_CSRXQ_CASE(IB1ASID); -+ break; -+ GEN_CSRXQ_CASE(IB2ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB2MASK); -+ break; -+ GEN_CSRXQ_CASE(IB2CTL); -+ break; -+ GEN_CSRXQ_CASE(IB2ASID); -+ break; -+ GEN_CSRXQ_CASE(IB3ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB3MASK); -+ break; -+ GEN_CSRXQ_CASE(IB3CTL); -+ break; -+ GEN_CSRXQ_CASE(IB3ASID); -+ break; -+ GEN_CSRXQ_CASE(IB4ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB4MASK); -+ break; -+ GEN_CSRXQ_CASE(IB4CTL); -+ break; -+ GEN_CSRXQ_CASE(IB4ASID); -+ break; -+ GEN_CSRXQ_CASE(IB5ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB5MASK); -+ break; -+ GEN_CSRXQ_CASE(IB5CTL); -+ break; -+ GEN_CSRXQ_CASE(IB5ASID); -+ break; -+ GEN_CSRXQ_CASE(IB6ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB6MASK); -+ break; -+ GEN_CSRXQ_CASE(IB6CTL); -+ break; -+ GEN_CSRXQ_CASE(IB6ASID); -+ break; -+ GEN_CSRXQ_CASE(IB7ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB7MASK); -+ break; -+ GEN_CSRXQ_CASE(IB7CTL); -+ break; -+ GEN_CSRXQ_CASE(IB7ASID); -+ break; -+ GEN_CSRXQ_CASE(DEBUG); -+ break; -+ GEN_CSRXQ_CASE(DERA); -+ break; -+ GEN_CSRXQ_CASE(DESAVE); -+ break; -+ default: -+ return false; -+ } -+ -+ #undef GEN_CSRXQ_CASE -+ tcg_temp_free(zero); -+ return true; -+} -+ -+#endif -+ -+static bool trans_cacop(DisasContext *ctx, arg_cacop *a) -+{ -+ /* Treat as NOP. */ -+ return true; -+} -+ -+#ifdef CONFIG_USER_ONLY -+ -+static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a) -+{ -+ return false; -+} -+ -+static bool trans_lddir(DisasContext *ctx, arg_lddir *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrrd_b(DisasContext *ctx, arg_iocsrrd_b *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrrd_h(DisasContext *ctx, arg_iocsrrd_h *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrrd_w(DisasContext *ctx, arg_iocsrrd_w *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrrd_d(DisasContext *ctx, arg_iocsrrd_d *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrwr_b(DisasContext *ctx, arg_iocsrwr_b *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrwr_h(DisasContext *ctx, arg_iocsrwr_h *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrwr_w(DisasContext *ctx, arg_iocsrwr_w *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrwr_d(DisasContext *ctx, arg_iocsrwr_d *a) -+{ -+ return false; -+} -+#else -+ -+static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a) -+{ -+ TCGv t0, t1; -+ TCGv_i32 t2; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->seq); -+ t2 = tcg_const_i32(ctx->mem_idx); -+ gen_helper_ldpte(cpu_env, t0, t1, t2); -+ -+ return true; -+} -+ -+static bool trans_lddir(DisasContext *ctx, arg_lddir *a) -+{ -+ TCGv t0, t1, t2; -+ TCGv_i32 t3; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->rd); -+ t2 = tcg_const_tl(a->level); -+ t3 = tcg_const_i32(ctx->mem_idx); -+ gen_helper_lddir(cpu_env, t0, t1, t2, t3); -+ -+ return true; -+} -+ -+static bool trans_iocsrrd_b(DisasContext *ctx, arg_iocsrrd_b *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrrd_h(DisasContext *ctx, arg_iocsrrd_h *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrrd_w(DisasContext *ctx, arg_iocsrrd_w *a) -+{ -+ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_LD_W); -+ TCGv t0, t1; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->rd); -+ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); -+ return true; -+} -+ -+static bool trans_iocsrrd_d(DisasContext *ctx, arg_iocsrrd_d *a) -+{ -+ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_LD_D); -+ TCGv t0, t1; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->rd); -+ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); -+ return true; -+} -+ -+static bool trans_iocsrwr_b(DisasContext *ctx, arg_iocsrwr_b *a) -+{ -+ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_ST_B); -+ TCGv t0, t1; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->rd); -+ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); -+ return true; -+} -+ -+static bool trans_iocsrwr_h(DisasContext *ctx, arg_iocsrwr_h *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrwr_w(DisasContext *ctx, arg_iocsrwr_w *a) -+{ -+ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_ST_W); -+ TCGv t0, t1; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->rd); -+ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); -+ return true; -+} -+ -+static bool trans_iocsrwr_d(DisasContext *ctx, arg_iocsrwr_d *a) -+{ -+ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_ST_D); -+ TCGv t0, t1; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->rd); -+ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); -+ return true; -+} -+#endif /* !CONFIG_USER_ONLY */ -+ -+ -+#ifdef CONFIG_USER_ONLY -+ -+#define GEN_FALSE_TRANS(name) \ -+static bool trans_##name(DisasContext *ctx, arg_##name * a) \ -+{ \ -+ return false; \ -+} -+ -+GEN_FALSE_TRANS(tlbclr) -+GEN_FALSE_TRANS(invtlb) -+GEN_FALSE_TRANS(tlbflush) -+GEN_FALSE_TRANS(tlbsrch) -+GEN_FALSE_TRANS(tlbrd) -+GEN_FALSE_TRANS(tlbwr) -+GEN_FALSE_TRANS(tlbfill) -+GEN_FALSE_TRANS(ertn) -+ -+#else -+ -+static bool trans_tlbclr(DisasContext *ctx, arg_tlbclr *a) -+{ -+ gen_helper_tlbclr(cpu_env); -+ return true; -+} -+ -+static bool trans_tlbflush(DisasContext *ctx, arg_tlbflush *a) -+{ -+ gen_helper_tlbflush(cpu_env); -+ return true; -+} -+ -+static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a) -+{ -+ TCGv addr = tcg_temp_new(); -+ TCGv info = tcg_temp_new(); -+ TCGv op = tcg_const_tl(a->invop); -+ -+ gen_load_gpr(addr, a->addr); -+ gen_load_gpr(info, a->info); -+ gen_helper_invtlb(cpu_env, addr, info, op); -+ -+ tcg_temp_free(addr); -+ tcg_temp_free(info); -+ tcg_temp_free(op); -+ return true; -+} -+ -+static bool trans_tlbsrch(DisasContext *ctx, arg_tlbsrch *a) -+{ -+ gen_helper_tlbsrch(cpu_env); -+ return true; -+} -+ -+static bool trans_tlbrd(DisasContext *ctx, arg_tlbrd *a) -+{ -+ gen_helper_tlbrd(cpu_env); -+ return true; -+} -+ -+static bool trans_tlbwr(DisasContext *ctx, arg_tlbwr *a) -+{ -+ gen_helper_tlbwr(cpu_env); -+ return true; -+} -+ -+static bool trans_tlbfill(DisasContext *ctx, arg_tlbfill *a) -+{ -+ gen_helper_tlbfill(cpu_env); -+ return true; -+} -+ -+static bool trans_ertn(DisasContext *ctx, arg_ertn *a) -+{ -+ gen_helper_ertn(cpu_env); -+ ctx->base.is_jmp = DISAS_EXIT; -+ return true; -+} -+ -+#endif /* CONFIG_USER_ONLY */ -+ -+static bool trans_idle(DisasContext *ctx, arg_idle *a) -+{ -+ ctx->base.pc_next += 4; -+ save_cpu_state(ctx, 1); -+ ctx->base.pc_next -= 4; -+ gen_helper_idle(cpu_env); -+ ctx->base.is_jmp = DISAS_NORETURN; -+ return true; -+} -+ -+#ifdef CONFIG_USER_ONLY -+ -+static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a) -+{ -+ /* Nop */ -+ return true; -+} -+ -+#else -+ -+static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a) -+{ -+ TCGv t0, t1; -+ t0 = tcg_const_tl(a->rd); -+ t1 = tcg_const_tl(a->rj); -+ gen_helper_drdtime(cpu_env, t0, t1); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+#endif -+ -+static bool trans_cpucfg(DisasContext *ctx, arg_cpucfg *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rj); -+ gen_helper_cpucfg(cpu_gpr[a->rd], cpu_env, t0); -+ tcg_temp_free(t0); -+ return true; -+} -diff --git a/target/loongarch64/translate.c b/target/loongarch64/translate.c -new file mode 100644 -index 000000000..fe122e4c3 ---- /dev/null -+++ b/target/loongarch64/translate.c -@@ -0,0 +1,2892 @@ -+/* -+ * LOONGARCH emulation for QEMU - main translation routines -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+ -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "internal.h" -+#include "disas/disas.h" -+#include "exec/exec-all.h" -+#include "tcg/tcg-op.h" -+#include "exec/cpu_ldst.h" -+#include "hw/loongarch/cpudevs.h" -+ -+#include "exec/helper-proto.h" -+#include "exec/helper-gen.h" -+#include "semihosting/semihost.h" -+ -+#include "trace-tcg.h" -+#include "exec/translator.h" -+#include "exec/log.h" -+ -+#include "instmap.h" -+ -+#define LARCH_DEBUG_DISAS 0 -+ -+/* Values for the fmt field in FP instructions */ -+enum { -+ /* 0 - 15 are reserved */ -+ FMT_S = 16, /* single fp */ -+ FMT_D = 17, /* double fp */ -+}; -+ -+/* global register indices */ -+static TCGv cpu_gpr[32], cpu_PC; -+static TCGv btarget, bcond; -+static TCGv cpu_lladdr, cpu_llval; -+static TCGv_i32 hflags; -+static TCGv_i32 fpu_fcsr0; -+static TCGv_i64 fpu_f64[32]; -+ -+#include "exec/gen-icount.h" -+ -+#define gen_helper_0e0i(name, arg) do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg); \ -+ gen_helper_##name(cpu_env, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+#define gen_helper_0e1i(name, arg1, arg2) do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ -+ gen_helper_##name(cpu_env, arg1, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+#define gen_helper_1e0i(name, ret, arg1) do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg1); \ -+ gen_helper_##name(ret, cpu_env, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+#define gen_helper_1e1i(name, ret, arg1, arg2) do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ -+ gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ -+ gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ -+ gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg4); \ -+ gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+typedef struct DisasContext { -+ DisasContextBase base; -+ target_ulong saved_pc; -+ target_ulong page_start; -+ uint32_t opcode; -+ uint64_t insn_flags; -+ /* Routine used to access memory */ -+ int mem_idx; -+ MemOp default_tcg_memop_mask; -+ uint32_t hflags, saved_hflags; -+ target_ulong btarget; -+} DisasContext; -+ -+#define DISAS_STOP DISAS_TARGET_0 -+#define DISAS_EXIT DISAS_TARGET_1 -+ -+#define LOG_DISAS(...) \ -+ do { \ -+ if (LARCH_DEBUG_DISAS) { \ -+ qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \ -+ } \ -+ } while (0) -+ -+#define LARCH_INVAL(op) \ -+ do { \ -+ if (LARCH_DEBUG_DISAS) { \ -+ qemu_log_mask(CPU_LOG_TB_IN_ASM, \ -+ TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \ -+ ctx->base.pc_next, ctx->opcode, op, \ -+ ctx->opcode >> 26, ctx->opcode & 0x3F, \ -+ ((ctx->opcode >> 16) & 0x1F)); \ -+ } \ -+ } while (0) -+ -+/* General purpose registers moves. */ -+static inline void gen_load_gpr(TCGv t, int reg) -+{ -+ if (reg == 0) { -+ tcg_gen_movi_tl(t, 0); -+ } else { -+ tcg_gen_mov_tl(t, cpu_gpr[reg]); -+ } -+} -+ -+static inline void gen_store_gpr(TCGv t, int reg) -+{ -+ if (reg != 0) { -+ tcg_gen_mov_tl(cpu_gpr[reg], t); -+ } -+} -+ -+/* Moves to/from shadow registers. */ -+/* Tests */ -+static inline void gen_save_pc(target_ulong pc) -+{ -+ tcg_gen_movi_tl(cpu_PC, pc); -+} -+ -+static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) -+{ -+ LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); -+ if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { -+ gen_save_pc(ctx->base.pc_next); -+ ctx->saved_pc = ctx->base.pc_next; -+ } -+ if (ctx->hflags != ctx->saved_hflags) { -+ tcg_gen_movi_i32(hflags, ctx->hflags); -+ ctx->saved_hflags = ctx->hflags; -+ switch (ctx->hflags & LARCH_HFLAG_BMASK) { -+ case LARCH_HFLAG_BR: -+ break; -+ case LARCH_HFLAG_BC: -+ case LARCH_HFLAG_B: -+ tcg_gen_movi_tl(btarget, ctx->btarget); -+ break; -+ } -+ } -+} -+ -+static inline void restore_cpu_state(CPULOONGARCHState *env, DisasContext *ctx) -+{ -+ ctx->saved_hflags = ctx->hflags; -+ switch (ctx->hflags & LARCH_HFLAG_BMASK) { -+ case LARCH_HFLAG_BR: -+ break; -+ case LARCH_HFLAG_BC: -+ case LARCH_HFLAG_B: -+ ctx->btarget = env->btarget; -+ break; -+ } -+} -+ -+static inline void generate_exception_err(DisasContext *ctx, int excp, int err) -+{ -+ TCGv_i32 texcp = tcg_const_i32(excp); -+ TCGv_i32 terr = tcg_const_i32(err); -+ save_cpu_state(ctx, 1); -+ gen_helper_raise_exception_err(cpu_env, texcp, terr); -+ tcg_temp_free_i32(terr); -+ tcg_temp_free_i32(texcp); -+ ctx->base.is_jmp = DISAS_NORETURN; -+} -+ -+static inline void generate_exception_end(DisasContext *ctx, int excp) -+{ -+ generate_exception_err(ctx, excp, 0); -+} -+ -+/* Floating point register moves. */ -+static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) -+{ -+ tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); -+} -+ -+static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) -+{ -+ TCGv_i64 t64; -+ t64 = tcg_temp_new_i64(); -+ tcg_gen_extu_i32_i64(t64, t); -+ tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); -+ tcg_temp_free_i64(t64); -+} -+ -+static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) -+{ -+ tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); -+} -+ -+static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) -+{ -+ TCGv_i64 t64 = tcg_temp_new_i64(); -+ tcg_gen_extu_i32_i64(t64, t); -+ tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); -+ tcg_temp_free_i64(t64); -+} -+ -+static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) -+{ -+ tcg_gen_mov_i64(t, fpu_f64[reg]); -+} -+ -+static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) -+{ -+ tcg_gen_mov_i64(fpu_f64[reg], t); -+} -+ -+static inline int get_fp_bit(int cc) -+{ -+ if (cc) { -+ return 24 + cc; -+ } else { -+ return 23; -+ } -+} -+ -+/* Addresses computation */ -+static inline void gen_op_addr_add(DisasContext *ctx, -+ TCGv ret, TCGv arg0, TCGv arg1) -+{ -+ tcg_gen_add_tl(ret, arg0, arg1); -+ -+ if (ctx->hflags & LARCH_HFLAG_AWRAP) { -+ tcg_gen_ext32s_i64(ret, ret); -+ } -+} -+ -+static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, -+ target_long ofs) -+{ -+ tcg_gen_addi_tl(ret, base, ofs); -+ -+ if (ctx->hflags & LARCH_HFLAG_AWRAP) { -+ tcg_gen_ext32s_i64(ret, ret); -+ } -+} -+ -+/* Sign-extract the low 32-bits to a target_long. */ -+static inline void gen_move_low32(TCGv ret, TCGv_i64 arg) -+{ -+ tcg_gen_ext32s_i64(ret, arg); -+} -+ -+/* Sign-extract the high 32-bits to a target_long. */ -+static inline void gen_move_high32(TCGv ret, TCGv_i64 arg) -+{ -+ tcg_gen_sari_i64(ret, arg, 32); -+} -+ -+static inline void check_cp1_enabled(DisasContext *ctx) -+{ -+#ifndef CONFIG_USER_ONLY -+ if (unlikely(!(ctx->hflags & LARCH_HFLAG_FPU))) { -+ generate_exception_err(ctx, EXCP_FPDIS, 1); -+ } -+#endif -+} -+ -+static inline void check_lsx_enabled(DisasContext *ctx) -+{ -+#ifndef CONFIG_USER_ONLY -+ if (unlikely(!(ctx->hflags & LARCH_HFLAG_LSX))) { -+ generate_exception_err(ctx, EXCP_LSXDIS, 1); -+ } -+#endif -+} -+ -+static inline void check_lasx_enabled(DisasContext *ctx) -+{ -+#ifndef CONFIG_USER_ONLY -+ if (unlikely(!(ctx->hflags & LARCH_HFLAG_LASX))) { -+ generate_exception_err(ctx, EXCP_LASXDIS, 1); -+ } -+#endif -+} -+ -+static inline void check_lbt_enabled(DisasContext *ctx) -+{ -+#ifndef CONFIG_USER_ONLY -+ if (unlikely(!(ctx->hflags & LARCH_HFLAG_LBT))) { -+ generate_exception_err(ctx, EXCP_BTDIS, 1); -+ } -+#endif -+} -+ -+/* This code generates a "reserved instruction" exception if the -+ CPU does not support the instruction set corresponding to flags. */ -+static inline void check_insn(DisasContext *ctx, uint64_t flags) -+{ -+ if (unlikely(!(ctx->insn_flags & flags))) { -+ generate_exception_end(ctx, EXCP_RI); -+ } -+} -+ -+/* This code generates a "reserved instruction" exception if the -+ CPU has corresponding flag set which indicates that the instruction -+ has been removed. */ -+static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) -+{ -+ if (unlikely(ctx->insn_flags & flags)) { -+ generate_exception_end(ctx, EXCP_RI); -+ } -+} -+ -+/* -+ * The Linux kernel traps certain reserved instruction exceptions to -+ * emulate the corresponding instructions. QEMU is the kernel in user -+ * mode, so those traps are emulated by accepting the instructions. -+ * -+ * A reserved instruction exception is generated for flagged CPUs if -+ * QEMU runs in system mode. -+ */ -+static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) -+{ -+#ifndef CONFIG_USER_ONLY -+ check_insn_opc_removed(ctx, flags); -+#endif -+} -+ -+/* This code generates a "reserved instruction" exception if 64-bit -+ instructions are not enabled. */ -+static inline void check_larch_64(DisasContext *ctx) -+{ -+ if (unlikely(!(ctx->hflags & LARCH_HFLAG_64))) { -+ generate_exception_end(ctx, EXCP_RI); -+ } -+} -+ -+/* Define small wrappers for gen_load_fpr* so that we have a uniform -+ calling interface for 32 and 64-bit FPRs. No sense in changing -+ all callers for gen_load_fpr32 when we need the CTX parameter for -+ this one use. */ -+#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) -+#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) -+#define FCOP_CONDNS(fmt, ifmt, bits, STORE) \ -+static inline void gen_fcmp_ ## fmt(DisasContext *ctx, int n, \ -+ int ft, int fs, int cd) \ -+{ \ -+ TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ -+ TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ -+ TCGv_i32 fcc = tcg_const_i32(cd); \ -+ check_cp1_enabled(ctx); \ -+ gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ -+ gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ -+ switch (n) { \ -+ case 0: \ -+ gen_helper_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 1: \ -+ gen_helper_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 2: \ -+ gen_helper_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 3: \ -+ gen_helper_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 4: \ -+ gen_helper_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 5: \ -+ gen_helper_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 6: \ -+ gen_helper_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 7: \ -+ gen_helper_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 8: \ -+ gen_helper_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 9: \ -+ gen_helper_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 10: \ -+ gen_helper_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 11: \ -+ gen_helper_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 12: \ -+ gen_helper_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 13: \ -+ gen_helper_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 14: \ -+ gen_helper_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 15: \ -+ gen_helper_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 16: \ -+ gen_helper_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 17: \ -+ gen_helper_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 20: \ -+ gen_helper_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 21: \ -+ gen_helper_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 24: \ -+ gen_helper_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 25: \ -+ gen_helper_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ default: \ -+ abort(); \ -+ } \ -+ STORE; \ -+ tcg_temp_free_i ## bits(fp0); \ -+ tcg_temp_free_i ## bits(fp1); \ -+ tcg_temp_free_i32(fcc); \ -+} -+ -+FCOP_CONDNS(d, FMT_D, 64, gen_helper_movreg2cf_i64(cpu_env, fcc, fp0)) -+FCOP_CONDNS(s, FMT_S, 32, gen_helper_movreg2cf_i32(cpu_env, fcc, fp0)) -+#undef FCOP_CONDNS -+#undef gen_ldcmp_fpr32 -+#undef gen_ldcmp_fpr64 -+ -+/* load/store instructions. */ -+#ifdef CONFIG_USER_ONLY -+#define OP_LD_ATOMIC(insn, fname) \ -+static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ -+ DisasContext *ctx) \ -+{ \ -+ TCGv t0 = tcg_temp_new(); \ -+ tcg_gen_mov_tl(t0, arg1); \ -+ tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ -+ tcg_gen_st_tl(t0, cpu_env, \ -+ offsetof(CPULOONGARCHState, lladdr)); \ -+ tcg_gen_st_tl(ret, cpu_env, \ -+ offsetof(CPULOONGARCHState, llval)); \ -+ tcg_temp_free(t0); \ -+} -+#else -+#define OP_LD_ATOMIC(insn, fname) \ -+static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ -+ DisasContext *ctx) \ -+{ \ -+ gen_helper_1e1i(insn, ret, arg1, mem_idx); \ -+} -+#endif -+#if 0 -+OP_LD_ATOMIC(ll, ld32s); -+OP_LD_ATOMIC(lld, ld64); -+#endif -+#undef OP_LD_ATOMIC -+ -+static void gen_base_offset_addr(DisasContext *ctx, TCGv addr, -+ int base, int offset) -+{ -+ if (base == 0) { -+ tcg_gen_movi_tl(addr, offset); -+ } else if (offset == 0) { -+ gen_load_gpr(addr, base); -+ } else { -+ tcg_gen_movi_tl(addr, offset); -+ gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); -+ } -+} -+ -+/* Load */ -+static void gen_ld(DisasContext *ctx, uint32_t opc, -+ int rt, int base, int offset) -+{ -+ TCGv t0; -+ int mem_idx = ctx->mem_idx; -+ -+ t0 = tcg_temp_new(); -+ gen_base_offset_addr(ctx, t0, base, offset); -+ -+ switch (opc) { -+ case OPC_LARCH_LD_WU: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL | -+ ctx->default_tcg_memop_mask); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LDPTR_D: -+ case OPC_LARCH_LD_D: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ | -+ ctx->default_tcg_memop_mask); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LL_D: -+#if 0 -+ op_ld_lld(t0, t0, mem_idx, ctx); -+#endif -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LDPTR_W: -+ case OPC_LARCH_LD_W: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL | -+ ctx->default_tcg_memop_mask); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LD_H: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW | -+ ctx->default_tcg_memop_mask); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LD_HU: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW | -+ ctx->default_tcg_memop_mask); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LD_B: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LD_BU: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LL_W: -+#if 0 -+ op_ld_ll(t0, t0, mem_idx, ctx); -+#endif -+ gen_store_gpr(t0, rt); -+ break; -+ } -+ -+ tcg_temp_free(t0); -+} -+ -+/* Store */ -+static void gen_st(DisasContext *ctx, uint32_t opc, int rt, -+ int base, int offset) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_base_offset_addr(ctx, t0, base, offset); -+ gen_load_gpr(t1, rt); -+ -+ switch (opc) { -+ case OPC_LARCH_STPTR_D: -+ case OPC_LARCH_ST_D: -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ | -+ ctx->default_tcg_memop_mask); -+ break; -+ case OPC_LARCH_STPTR_W: -+ case OPC_LARCH_ST_W: -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | -+ ctx->default_tcg_memop_mask); -+ break; -+ case OPC_LARCH_ST_H: -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | -+ ctx->default_tcg_memop_mask); -+ break; -+ case OPC_LARCH_ST_B: -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); -+ break; -+ } -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+} -+ -+/* Store conditional */ -+static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, -+ MemOp tcg_mo, bool eva) -+{ -+ TCGv addr, t0, val; -+ TCGLabel *l1 = gen_new_label(); -+ TCGLabel *done = gen_new_label(); -+ -+ t0 = tcg_temp_new(); -+ addr = tcg_temp_new(); -+ /* compare the address against that of the preceeding LL */ -+ gen_base_offset_addr(ctx, addr, base, offset); -+ tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); -+ tcg_temp_free(addr); -+ tcg_gen_movi_tl(t0, 0); -+ gen_store_gpr(t0, rt); -+ tcg_gen_br(done); -+ -+ gen_set_label(l1); -+ /* generate cmpxchg */ -+ val = tcg_temp_new(); -+ gen_load_gpr(val, rt); -+ tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, -+ eva ? LARCH_HFLAG_UM : ctx->mem_idx, tcg_mo); -+ tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); -+ gen_store_gpr(t0, rt); -+ tcg_temp_free(val); -+ -+ gen_set_label(done); -+ tcg_temp_free(t0); -+} -+ -+/* Load and store */ -+static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, -+ TCGv t0) -+{ -+ /* Don't do NOP if destination is zero: we must perform the actual -+ memory access. */ -+ switch (opc) { -+ case OPC_LARCH_FLD_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | -+ ctx->default_tcg_memop_mask); -+ gen_store_fpr32(ctx, fp0, ft); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FST_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, ft); -+ tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | -+ ctx->default_tcg_memop_mask); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FLD_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ | -+ ctx->default_tcg_memop_mask); -+ gen_store_fpr64(ctx, fp0, ft); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FST_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, ft); -+ tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ | -+ ctx->default_tcg_memop_mask); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ default: -+ LARCH_INVAL("flt_ldst"); -+ generate_exception_end(ctx, EXCP_RI); -+ break; -+ } -+} -+ -+static void gen_fp_ldst(DisasContext *ctx, uint32_t op, int rt, -+ int rs, int16_t imm) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ check_cp1_enabled(ctx); -+ gen_base_offset_addr(ctx, t0, rs, imm); -+ gen_flt_ldst(ctx, op, rt, t0); -+ tcg_temp_free(t0); -+} -+ -+/* Arithmetic with immediate operand */ -+static void gen_arith_imm(DisasContext *ctx, uint32_t opc, -+ int rt, int rs, int imm) -+{ -+ target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ -+ -+ if (rt == 0) { -+ /* If no destination, treat it as a NOP. -+ For addi, we must generate the overflow exception when needed. */ -+ return; -+ } -+ switch (opc) { -+ case OPC_LARCH_ADDI_W: -+ if (rs != 0) { -+ tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); -+ tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rt], uimm); -+ } -+ break; -+ case OPC_LARCH_ADDI_D: -+ if (rs != 0) { -+ tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rt], uimm); -+ } -+ break; -+ } -+} -+ -+/* Logic with immediate operand */ -+static void gen_logic_imm(DisasContext *ctx, uint32_t opc, -+ int rt, int rs, int16_t imm) -+{ -+ target_ulong uimm; -+ -+ if (rt == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ uimm = (uint16_t)imm; -+ switch (opc) { -+ case OPC_LARCH_ANDI: -+ if (likely(rs != 0)) { -+ tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rt], 0); -+ } -+ break; -+ case OPC_LARCH_ORI: -+ if (rs != 0) { -+ tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rt], uimm); -+ } -+ break; -+ case OPC_LARCH_XORI: -+ if (likely(rs != 0)) { -+ tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rt], uimm); -+ } -+ break; -+ default: -+ break; -+ } -+} -+ -+/* Set on less than with immediate operand */ -+static void gen_slt_imm(DisasContext *ctx, uint32_t opc, -+ int rt, int rs, int16_t imm) -+{ -+ target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ -+ TCGv t0; -+ -+ if (rt == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, rs); -+ switch (opc) { -+ case OPC_LARCH_SLTI: -+ tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); -+ break; -+ case OPC_LARCH_SLTIU: -+ tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); -+ break; -+ } -+ tcg_temp_free(t0); -+} -+ -+/* Shifts with immediate operand */ -+static void gen_shift_imm(DisasContext *ctx, uint32_t opc, -+ int rt, int rs, int16_t imm) -+{ -+ target_ulong uimm = ((uint16_t)imm) & 0x1f; -+ TCGv t0; -+ -+ if (rt == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, rs); -+ switch (opc) { -+ case OPC_LARCH_SRAI_W: -+ tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); -+ break; -+ case OPC_LARCH_SRLI_W: -+ if (uimm != 0) { -+ tcg_gen_ext32u_tl(t0, t0); -+ tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); -+ } else { -+ tcg_gen_ext32s_tl(cpu_gpr[rt], t0); -+ } -+ break; -+ case OPC_LARCH_ROTRI_W: -+ if (uimm != 0) { -+ TCGv_i32 t1 = tcg_temp_new_i32(); -+ -+ tcg_gen_trunc_tl_i32(t1, t0); -+ tcg_gen_rotri_i32(t1, t1, uimm); -+ tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); -+ tcg_temp_free_i32(t1); -+ } else { -+ tcg_gen_ext32s_tl(cpu_gpr[rt], t0); -+ } -+ break; -+ } -+ tcg_temp_free(t0); -+} -+ -+/* Arithmetic */ -+static void gen_arith(DisasContext *ctx, uint32_t opc, -+ int rd, int rs, int rt) -+{ -+ if (rd == 0) { -+ /* If no destination, treat it as a NOP. -+ For add & sub, we must generate the -+ overflow exception when needed. */ -+ return; -+ } -+ -+ switch (opc) { -+ case OPC_LARCH_ADD_W: -+ if (rs != 0 && rt != 0) { -+ tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ case OPC_LARCH_SUB_W: -+ if (rs != 0 && rt != 0) { -+ tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ case OPC_LARCH_ADD_D: -+ if (rs != 0 && rt != 0) { -+ tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ case OPC_LARCH_SUB_D: -+ if (rs != 0 && rt != 0) { -+ tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ } -+} -+ -+/* Conditional move */ -+static void gen_cond_move(DisasContext *ctx, uint32_t opc, -+ int rd, int rs, int rt) -+{ -+ TCGv t0, t1, t2; -+ -+ if (rd == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, rt); -+ t1 = tcg_const_tl(0); -+ t2 = tcg_temp_new(); -+ gen_load_gpr(t2, rs); -+ switch (opc) { -+ case OPC_LARCH_MASKEQZ: -+ tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); -+ break; -+ case OPC_LARCH_MASKNEZ: -+ tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); -+ break; -+ } -+ tcg_temp_free(t2); -+ tcg_temp_free(t1); -+ tcg_temp_free(t0); -+} -+ -+/* Logic */ -+static void gen_logic(DisasContext *ctx, uint32_t opc, -+ int rd, int rs, int rt) -+{ -+ if (rd == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ -+ switch (opc) { -+ case OPC_LARCH_AND: -+ if (likely(rs != 0 && rt != 0)) { -+ tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ case OPC_LARCH_NOR: -+ if (rs != 0 && rt != 0) { -+ tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); -+ } -+ break; -+ case OPC_LARCH_OR: -+ if (likely(rs != 0 && rt != 0)) { -+ tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ case OPC_LARCH_XOR: -+ if (likely(rs != 0 && rt != 0)) { -+ tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ } -+} -+ -+/* Set on lower than */ -+static void gen_slt(DisasContext *ctx, uint32_t opc, -+ int rd, int rs, int rt) -+{ -+ TCGv t0, t1; -+ -+ if (rd == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ gen_load_gpr(t0, rs); -+ gen_load_gpr(t1, rt); -+ switch (opc) { -+ case OPC_LARCH_SLT: -+ tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); -+ break; -+ case OPC_LARCH_SLTU: -+ tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); -+ break; -+ } -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+} -+ -+/* Shifts */ -+static void gen_shift(DisasContext *ctx, uint32_t opc, -+ int rd, int rs, int rt) -+{ -+ TCGv t0, t1; -+ -+ if (rd == 0) { -+ /* If no destination, treat it as a NOP. -+ For add & sub, we must generate the -+ overflow exception when needed. */ -+ return; -+ } -+ -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ gen_load_gpr(t0, rs); -+ gen_load_gpr(t1, rt); -+ switch (opc) { -+ case OPC_LARCH_SLL_W: -+ tcg_gen_andi_tl(t0, t0, 0x1f); -+ tcg_gen_shl_tl(t0, t1, t0); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); -+ break; -+ case OPC_LARCH_SRA_W: -+ tcg_gen_andi_tl(t0, t0, 0x1f); -+ tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); -+ break; -+ case OPC_LARCH_SRL_W: -+ tcg_gen_ext32u_tl(t1, t1); -+ tcg_gen_andi_tl(t0, t0, 0x1f); -+ tcg_gen_shr_tl(t0, t1, t0); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); -+ break; -+ case OPC_LARCH_ROTR_W: -+ { -+ TCGv_i32 t2 = tcg_temp_new_i32(); -+ TCGv_i32 t3 = tcg_temp_new_i32(); -+ -+ tcg_gen_trunc_tl_i32(t2, t0); -+ tcg_gen_trunc_tl_i32(t3, t1); -+ tcg_gen_andi_i32(t2, t2, 0x1f); -+ tcg_gen_rotr_i32(t2, t3, t2); -+ tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); -+ tcg_temp_free_i32(t2); -+ tcg_temp_free_i32(t3); -+ } -+ break; -+ case OPC_LARCH_SLL_D: -+ tcg_gen_andi_tl(t0, t0, 0x3f); -+ tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); -+ break; -+ case OPC_LARCH_SRA_D: -+ tcg_gen_andi_tl(t0, t0, 0x3f); -+ tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); -+ break; -+ case OPC_LARCH_SRL_D: -+ tcg_gen_andi_tl(t0, t0, 0x3f); -+ tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); -+ break; -+ case OPC_LARCH_ROTR_D: -+ tcg_gen_andi_tl(t0, t0, 0x3f); -+ tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); -+ break; -+ } -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+} -+ -+static inline void gen_r6_ld(target_long addr, int reg, int memidx, -+ MemOp memop) -+{ -+ TCGv t0 = tcg_const_tl(addr); -+ tcg_gen_qemu_ld_tl(t0, t0, memidx, memop); -+ gen_store_gpr(t0, reg); -+ tcg_temp_free(t0); -+} -+ -+static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) -+{ -+ TCGv t0, t1; -+ -+ if (rd == 0) { -+ /* Treat as NOP. */ -+ return; -+ } -+ -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, rs); -+ gen_load_gpr(t1, rt); -+ -+ switch (opc) { -+ case OPC_LARCH_DIV_W: -+ { -+ TCGv t2 = tcg_temp_new(); -+ TCGv t3 = tcg_temp_new(); -+ tcg_gen_ext32s_tl(t0, t0); -+ tcg_gen_ext32s_tl(t1, t1); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); -+ tcg_gen_and_tl(t2, t2, t3); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); -+ tcg_gen_or_tl(t2, t2, t3); -+ tcg_gen_movi_tl(t3, 0); -+ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); -+ tcg_gen_div_tl(cpu_gpr[rd], t0, t1); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } -+ break; -+ case OPC_LARCH_MOD_W: -+ { -+ TCGv t2 = tcg_temp_new(); -+ TCGv t3 = tcg_temp_new(); -+ tcg_gen_ext32s_tl(t0, t0); -+ tcg_gen_ext32s_tl(t1, t1); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); -+ tcg_gen_and_tl(t2, t2, t3); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); -+ tcg_gen_or_tl(t2, t2, t3); -+ tcg_gen_movi_tl(t3, 0); -+ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); -+ tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } -+ break; -+ case OPC_LARCH_DIV_WU: -+ { -+ TCGv t2 = tcg_const_tl(0); -+ TCGv t3 = tcg_const_tl(1); -+ tcg_gen_ext32u_tl(t0, t0); -+ tcg_gen_ext32u_tl(t1, t1); -+ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); -+ tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } -+ break; -+ case OPC_LARCH_MOD_WU: -+ { -+ TCGv t2 = tcg_const_tl(0); -+ TCGv t3 = tcg_const_tl(1); -+ tcg_gen_ext32u_tl(t0, t0); -+ tcg_gen_ext32u_tl(t1, t1); -+ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); -+ tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } -+ break; -+ case OPC_LARCH_MUL_W: -+ { -+ TCGv_i32 t2 = tcg_temp_new_i32(); -+ TCGv_i32 t3 = tcg_temp_new_i32(); -+ tcg_gen_trunc_tl_i32(t2, t0); -+ tcg_gen_trunc_tl_i32(t3, t1); -+ tcg_gen_mul_i32(t2, t2, t3); -+ tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); -+ tcg_temp_free_i32(t2); -+ tcg_temp_free_i32(t3); -+ } -+ break; -+ case OPC_LARCH_MULH_W: -+ { -+ TCGv_i32 t2 = tcg_temp_new_i32(); -+ TCGv_i32 t3 = tcg_temp_new_i32(); -+ tcg_gen_trunc_tl_i32(t2, t0); -+ tcg_gen_trunc_tl_i32(t3, t1); -+ tcg_gen_muls2_i32(t2, t3, t2, t3); -+ tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); -+ tcg_temp_free_i32(t2); -+ tcg_temp_free_i32(t3); -+ } -+ break; -+ case OPC_LARCH_MULH_WU: -+ { -+ TCGv_i32 t2 = tcg_temp_new_i32(); -+ TCGv_i32 t3 = tcg_temp_new_i32(); -+ tcg_gen_trunc_tl_i32(t2, t0); -+ tcg_gen_trunc_tl_i32(t3, t1); -+ tcg_gen_mulu2_i32(t2, t3, t2, t3); -+ tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); -+ tcg_temp_free_i32(t2); -+ tcg_temp_free_i32(t3); -+ } -+ break; -+ case OPC_LARCH_DIV_D: -+ { -+ TCGv t2 = tcg_temp_new(); -+ TCGv t3 = tcg_temp_new(); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); -+ tcg_gen_and_tl(t2, t2, t3); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); -+ tcg_gen_or_tl(t2, t2, t3); -+ tcg_gen_movi_tl(t3, 0); -+ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); -+ tcg_gen_div_tl(cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } -+ break; -+ case OPC_LARCH_MOD_D: -+ { -+ TCGv t2 = tcg_temp_new(); -+ TCGv t3 = tcg_temp_new(); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); -+ tcg_gen_and_tl(t2, t2, t3); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); -+ tcg_gen_or_tl(t2, t2, t3); -+ tcg_gen_movi_tl(t3, 0); -+ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); -+ tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } -+ break; -+ case OPC_LARCH_DIV_DU: -+ { -+ TCGv t2 = tcg_const_tl(0); -+ TCGv t3 = tcg_const_tl(1); -+ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); -+ tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } -+ break; -+ case OPC_LARCH_MOD_DU: -+ { -+ TCGv t2 = tcg_const_tl(0); -+ TCGv t3 = tcg_const_tl(1); -+ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); -+ tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } -+ break; -+ case OPC_LARCH_MUL_D: -+ tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); -+ break; -+ case OPC_LARCH_MULH_D: -+ { -+ TCGv t2 = tcg_temp_new(); -+ tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t2); -+ } -+ break; -+ case OPC_LARCH_MULH_DU: -+ { -+ TCGv t2 = tcg_temp_new(); -+ tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t2); -+ } -+ break; -+ default: -+ LARCH_INVAL("r6 mul/div"); -+ generate_exception_end(ctx, EXCP_RI); -+ goto out; -+ } -+ out: -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+} -+ -+static void gen_cl(DisasContext *ctx, uint32_t opc, -+ int rd, int rs) -+{ -+ TCGv t0; -+ -+ if (rd == 0) { -+ /* Treat as NOP. */ -+ return; -+ } -+ t0 = cpu_gpr[rd]; -+ gen_load_gpr(t0, rs); -+ -+ switch (opc) { -+ case OPC_LARCH_CLO_W: -+ case OPC_LARCH_CLO_D: -+ tcg_gen_not_tl(t0, t0); -+ break; -+ } -+ -+ switch (opc) { -+ case OPC_LARCH_CLO_W: -+ case OPC_LARCH_CLZ_W: -+ tcg_gen_ext32u_tl(t0, t0); -+ tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); -+ tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); -+ break; -+ case OPC_LARCH_CLO_D: -+ case OPC_LARCH_CLZ_D: -+ tcg_gen_clzi_i64(t0, t0, 64); -+ break; -+ } -+} -+ -+static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) -+{ -+ if (unlikely(ctx->base.singlestep_enabled)) { -+ return false; -+ } -+ -+#ifndef CONFIG_USER_ONLY -+ return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); -+#else -+ return true; -+#endif -+} -+ -+static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) -+{ -+ if (use_goto_tb(ctx, dest)) { -+ tcg_gen_goto_tb(n); -+ gen_save_pc(dest); -+ tcg_gen_exit_tb(ctx->base.tb, n); -+ } else { -+ gen_save_pc(dest); -+ if (ctx->base.singlestep_enabled) { -+ save_cpu_state(ctx, 0); -+ gen_helper_raise_exception_debug(cpu_env); -+ } -+ tcg_gen_lookup_and_goto_ptr(); -+ } -+} -+ -+/* Branches */ -+static void gen_compute_branch(DisasContext *ctx, uint32_t opc, -+ int insn_bytes, -+ int rs, int rt, int32_t offset) -+{ -+ target_ulong btgt = -1; -+ int bcond_compute = 0; -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ -+ if (ctx->hflags & LARCH_HFLAG_BMASK) { -+#ifdef LARCH_DEBUG_DISAS -+ LOG_DISAS("Branch at PC 0x" -+ TARGET_FMT_lx "\n", ctx->base.pc_next); -+#endif -+ generate_exception_end(ctx, EXCP_RI); -+ goto out; -+ } -+ -+ /* Load needed operands */ -+ switch (opc) { -+ case OPC_LARCH_BLT: -+ case OPC_LARCH_BGE: -+ case OPC_LARCH_BLTU: -+ case OPC_LARCH_BGEU: -+ gen_load_gpr(t0, rs); -+ gen_load_gpr(t1, rt); -+ bcond_compute = 1; -+ btgt = ctx->base.pc_next + offset; -+ break; -+ case OPC_LARCH_BEQZ: -+ case OPC_LARCH_B: -+ case OPC_LARCH_BEQ: -+ case OPC_LARCH_BNEZ: -+ case OPC_LARCH_BNE: -+ /* Compare two registers */ -+ if (rs != rt) { -+ gen_load_gpr(t0, rs); -+ gen_load_gpr(t1, rt); -+ bcond_compute = 1; -+ } -+ btgt = ctx->base.pc_next + offset; -+ break; -+ default: -+ LARCH_INVAL("branch/jump"); -+ generate_exception_end(ctx, EXCP_RI); -+ goto out; -+ } -+ if (bcond_compute == 0) { -+ /* No condition to be computed */ -+ switch (opc) { -+ case OPC_LARCH_BEQZ: /* rx == rx */ -+ case OPC_LARCH_B: -+ case OPC_LARCH_BEQ: -+ /* Always take */ -+ ctx->hflags |= LARCH_HFLAG_B; -+ break; -+ case OPC_LARCH_BNEZ: -+ case OPC_LARCH_BNE: -+ /* Treat as NOP. */ -+ goto out; -+ default: -+ LARCH_INVAL("branch/jump"); -+ generate_exception_end(ctx, EXCP_RI); -+ goto out; -+ } -+ } else { -+ switch (opc) { -+ case OPC_LARCH_BLT: -+ tcg_gen_setcond_tl(TCG_COND_LT, bcond, t0, t1); -+ goto not_likely; -+ case OPC_LARCH_BGE: -+ tcg_gen_setcond_tl(TCG_COND_GE, bcond, t0, t1); -+ goto not_likely; -+ case OPC_LARCH_BLTU: -+ tcg_gen_setcond_tl(TCG_COND_LTU, bcond, t0, t1); -+ goto not_likely; -+ case OPC_LARCH_BGEU: -+ tcg_gen_setcond_tl(TCG_COND_GEU, bcond, t0, t1); -+ goto not_likely; -+ case OPC_LARCH_BEQZ: -+ case OPC_LARCH_B: -+ case OPC_LARCH_BEQ: -+ tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); -+ goto not_likely; -+ case OPC_LARCH_BNEZ: -+ case OPC_LARCH_BNE: -+ tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); -+ goto not_likely; -+ not_likely: -+ ctx->hflags |= LARCH_HFLAG_BC; -+ break; -+ default: -+ LARCH_INVAL("conditional branch/jump"); -+ generate_exception_end(ctx, EXCP_RI); -+ goto out; -+ } -+ } -+ -+ ctx->btarget = btgt; -+ -+ out: -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+} -+ -+/* special3 bitfield operations */ -+static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, -+ int rs, int lsb, int msb) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ -+ gen_load_gpr(t1, rs); -+ switch (opc) { -+ case OPC_LARCH_TRPICK_W: -+ if (lsb + msb > 31) { -+ goto fail; -+ } -+ if (msb != 31) { -+ tcg_gen_extract_tl(t0, t1, lsb, msb + 1); -+ } else { -+ /* -+ * The two checks together imply that lsb == 0, -+ * so this is a simple sign-extension. -+ */ -+ tcg_gen_ext32s_tl(t0, t1); -+ } -+ break; -+ case OPC_LARCH_TRINS_W: -+ if (lsb > msb) { -+ goto fail; -+ } -+ gen_load_gpr(t0, rt); -+ tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); -+ tcg_gen_ext32s_tl(t0, t0); -+ break; -+ default: -+fail: -+ LARCH_INVAL("bitops"); -+ generate_exception_end(ctx, EXCP_RI); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return; -+ } -+ gen_store_gpr(t0, rt); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+} -+ -+static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) -+{ -+ TCGv t0; -+ -+ if (rd == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, rt); -+ switch (op2) { -+ case OPC_LARCH_REVB_2H: -+ { -+ TCGv t1 = tcg_temp_new(); -+ TCGv t2 = tcg_const_tl(0x00FF00FF); -+ -+ tcg_gen_shri_tl(t1, t0, 8); -+ tcg_gen_and_tl(t1, t1, t2); -+ tcg_gen_and_tl(t0, t0, t2); -+ tcg_gen_shli_tl(t0, t0, 8); -+ tcg_gen_or_tl(t0, t0, t1); -+ tcg_temp_free(t2); -+ tcg_temp_free(t1); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); -+ } -+ break; -+ case OPC_LARCH_EXT_WB: -+ tcg_gen_ext8s_tl(cpu_gpr[rd], t0); -+ break; -+ case OPC_LARCH_EXT_WH: -+ tcg_gen_ext16s_tl(cpu_gpr[rd], t0); -+ break; -+ case OPC_LARCH_REVB_4H: -+ { -+ TCGv t1 = tcg_temp_new(); -+ TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL); -+ -+ tcg_gen_shri_tl(t1, t0, 8); -+ tcg_gen_and_tl(t1, t1, t2); -+ tcg_gen_and_tl(t0, t0, t2); -+ tcg_gen_shli_tl(t0, t0, 8); -+ tcg_gen_or_tl(cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t2); -+ tcg_temp_free(t1); -+ } -+ break; -+ case OPC_LARCH_REVH_D: -+ { -+ TCGv t1 = tcg_temp_new(); -+ TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL); -+ -+ tcg_gen_shri_tl(t1, t0, 16); -+ tcg_gen_and_tl(t1, t1, t2); -+ tcg_gen_and_tl(t0, t0, t2); -+ tcg_gen_shli_tl(t0, t0, 16); -+ tcg_gen_or_tl(t0, t0, t1); -+ tcg_gen_shri_tl(t1, t0, 32); -+ tcg_gen_shli_tl(t0, t0, 32); -+ tcg_gen_or_tl(cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t2); -+ tcg_temp_free(t1); -+ } -+ break; -+ default: -+ LARCH_INVAL("bsfhl"); -+ generate_exception_end(ctx, EXCP_RI); -+ tcg_temp_free(t0); -+ return; -+ } -+ tcg_temp_free(t0); -+} -+ -+/* REV with sf==1, opcode==3 ("REV64") */ -+static void handle_rev64(DisasContext *ctx, -+ unsigned int rn, unsigned int rd) -+{ -+ tcg_gen_bswap64_i64(cpu_gpr[rd], cpu_gpr[rn]); -+} -+ -+/* REV with sf==0, opcode==2 -+ * REV32 (sf==1, opcode==2) -+ */ -+static void handle_rev32(DisasContext *ctx, -+ unsigned int rn, unsigned int rd) -+{ -+ TCGv_i64 tcg_rd = tcg_temp_new_i64(); -+ gen_load_gpr(tcg_rd, rd); -+ -+ TCGv_i64 tcg_tmp = tcg_temp_new_i64(); -+ TCGv_i64 tcg_rn = tcg_temp_new_i64(); -+ gen_load_gpr(tcg_rn, rn); -+ -+ /* bswap32_i64 requires zero high word */ -+ tcg_gen_ext32u_i64(tcg_tmp, tcg_rn); -+ tcg_gen_bswap32_i64(tcg_rd, tcg_tmp, TCG_BSWAP_OZ); -+ tcg_gen_shri_i64(tcg_tmp, tcg_rn, 32); -+ tcg_gen_bswap32_i64(tcg_tmp, tcg_tmp, TCG_BSWAP_OZ); -+ tcg_gen_concat32_i64(cpu_gpr[rd], tcg_rd, tcg_tmp); -+ -+ tcg_temp_free_i64(tcg_tmp); -+ tcg_temp_free_i64(tcg_rd); -+ tcg_temp_free_i64(tcg_rn); -+} -+ -+/* REV16 */ -+static void handle_rev16(DisasContext *ctx, unsigned int rn, unsigned int rd) -+{ -+ TCGv_i64 tcg_rd = tcg_temp_new_i64(); -+ TCGv_i64 tcg_rn = tcg_temp_new_i64(); -+ gen_load_gpr(tcg_rd, rd); -+ gen_load_gpr(tcg_rn, rn); -+ TCGv_i64 tcg_tmp = tcg_temp_new_i64(); -+ TCGv_i64 mask = tcg_const_i64(0x0000ffff0000ffffull); -+ -+ tcg_gen_shri_i64(tcg_tmp, tcg_rn, 16); -+ tcg_gen_and_i64(tcg_rd, tcg_rn, mask); -+ tcg_gen_and_i64(tcg_tmp, tcg_tmp, mask); -+ tcg_gen_shli_i64(tcg_rd, tcg_rd, 16); -+ tcg_gen_or_i64(cpu_gpr[rd], tcg_rd, tcg_tmp); -+ -+ tcg_temp_free_i64(mask); -+ tcg_temp_free_i64(tcg_tmp); -+ tcg_temp_free_i64(tcg_rd); -+ tcg_temp_free_i64(tcg_rn); -+} -+ -+static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt, -+ int imm2) -+{ -+ TCGv t0; -+ TCGv t1; -+ if (rd == 0) { -+ /* Treat as NOP. */ -+ return; -+ } -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ gen_load_gpr(t0, rs); -+ gen_load_gpr(t1, rt); -+ tcg_gen_shli_tl(t0, t0, imm2 + 1); -+ tcg_gen_add_tl(cpu_gpr[rd], t0, t1); -+ if (opc == OPC_LARCH_ALSL_W) { -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ } -+ -+ tcg_temp_free(t1); -+ tcg_temp_free(t0); -+ -+ return; -+} -+ -+static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, -+ int rt, int bits) -+{ -+ TCGv t0; -+ if (rd == 0) { -+ /* Treat as NOP. */ -+ return; -+ } -+ t0 = tcg_temp_new(); -+ if (bits == 0 || bits == wordsz) { -+ if (bits == 0) { -+ gen_load_gpr(t0, rt); -+ } else { -+ gen_load_gpr(t0, rs); -+ } -+ switch (wordsz) { -+ case 32: -+ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); -+ break; -+ case 64: -+ tcg_gen_mov_tl(cpu_gpr[rd], t0); -+ break; -+ } -+ } else { -+ TCGv t1 = tcg_temp_new(); -+ gen_load_gpr(t0, rt); -+ gen_load_gpr(t1, rs); -+ switch (wordsz) { -+ case 32: -+ { -+ TCGv_i64 t2 = tcg_temp_new_i64(); -+ tcg_gen_concat_tl_i64(t2, t1, t0); -+ tcg_gen_shri_i64(t2, t2, 32 - bits); -+ gen_move_low32(cpu_gpr[rd], t2); -+ tcg_temp_free_i64(t2); -+ } -+ break; -+ case 64: -+ tcg_gen_shli_tl(t0, t0, bits); -+ tcg_gen_shri_tl(t1, t1, 64 - bits); -+ tcg_gen_or_tl(cpu_gpr[rd], t1, t0); -+ break; -+ } -+ tcg_temp_free(t1); -+ } -+ -+ tcg_temp_free(t0); -+} -+ -+static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, -+ int bp) -+{ -+ gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); -+} -+ -+static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) -+{ -+ TCGv t0; -+ if (rd == 0) { -+ /* Treat as NOP. */ -+ return; -+ } -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, rt); -+ switch (opc) { -+ case OPC_LARCH_BREV_4B: -+ gen_helper_bitswap(cpu_gpr[rd], t0); -+ break; -+ case OPC_LARCH_BREV_8B: -+ gen_helper_dbitswap(cpu_gpr[rd], t0); -+ break; -+ } -+ tcg_temp_free(t0); -+} -+ -+static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) -+{ -+ TCGv t0 = tcg_temp_new(); -+ check_cp1_enabled(ctx); -+ -+ switch (opc) { -+ case OPC_LARCH_FR2GR_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ tcg_gen_ext_i32_tl(t0, fp0); -+ tcg_temp_free_i32(fp0); -+ } -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_GR2FR_W: -+ gen_load_gpr(t0, rt); -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ tcg_gen_trunc_tl_i32(fp0, t0); -+ gen_store_fpr32(ctx, fp0, fs); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FR2GR_D: -+ gen_load_fpr64(ctx, t0, fs); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_GR2FR_D: -+ gen_load_gpr(t0, rt); -+ gen_store_fpr64(ctx, t0, fs); -+ break; -+ case OPC_LARCH_FRH2GR_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32h(ctx, fp0, fs); -+ tcg_gen_ext_i32_tl(t0, fp0); -+ tcg_temp_free_i32(fp0); -+ } -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_GR2FRH_W: -+ gen_load_gpr(t0, rt); -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ tcg_gen_trunc_tl_i32(fp0, t0); -+ gen_store_fpr32h(ctx, fp0, fs); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ default: -+ LARCH_INVAL("cp1 move"); -+ generate_exception_end(ctx, EXCP_RI); -+ goto out; -+ } -+ -+ out: -+ tcg_temp_free(t0); -+} -+ -+static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, -+ int cc, int tf) -+{ -+ int cond; -+ TCGv_i32 t0 = tcg_temp_new_i32(); -+ TCGLabel *l1 = gen_new_label(); -+ TCGLabel *l2 = gen_new_label(); -+ -+ if (tf) { -+ cond = TCG_COND_EQ; -+ } else { -+ cond = TCG_COND_NE; -+ } -+ -+ tcg_gen_andi_i32(t0, fpu_fcsr0, 1 << get_fp_bit(cc)); -+ tcg_gen_brcondi_i32(cond, t0, 0, l1); -+ gen_load_fpr32(ctx, t0, fs); -+ gen_store_fpr32(ctx, t0, fd); -+ gen_set_label(l1); -+ -+ tcg_gen_andi_i32(t0, fpu_fcsr0, 1 << get_fp_bit(cc + 1)); -+ tcg_gen_brcondi_i32(cond, t0, 0, l2); -+ gen_load_fpr32h(ctx, t0, fs); -+ gen_store_fpr32h(ctx, t0, fd); -+ tcg_temp_free_i32(t0); -+ gen_set_label(l2); -+} -+ -+static void gen_farith(DisasContext *ctx, uint32_t opc, -+ int ft, int fs, int fd, int cc) -+{ -+ check_cp1_enabled(ctx); -+ switch (opc) { -+ case OPC_LARCH_FADD_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i32(fp1); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FSUB_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i32(fp1); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FMUL_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i32(fp1); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FDIV_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i32(fp1); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FSQRT_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_sqrt_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FABS_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_abs_s(fp0, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FMOV_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FNEG_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_chs_s(fp0, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FTINTRNE_L_S: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_round_l_s(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } -+ break; -+ case OPC_LARCH_FTINTRZ_L_S: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_trunc_l_s(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } -+ break; -+ case OPC_LARCH_FTINTRP_L_S: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_ceil_l_s(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } -+ break; -+ case OPC_LARCH_FTINTRM_L_S: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_floor_l_s(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } -+ break; -+ case OPC_LARCH_FTINTRNE_W_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_round_w_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FTINTRZ_W_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_trunc_w_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FTINTRP_W_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_ceil_w_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FTINTRM_W_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_floor_w_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FRECIP_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_recip_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FRSQRT_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FRINT_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_rint_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FCLASS_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_class_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FMIN_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ TCGv_i32 fp2 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_min_s(fp2, cpu_env, fp0, fp1); -+ gen_store_fpr32(ctx, fp2, fd); -+ tcg_temp_free_i32(fp2); -+ tcg_temp_free_i32(fp1); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FMINA_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ TCGv_i32 fp2 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1); -+ gen_store_fpr32(ctx, fp2, fd); -+ tcg_temp_free_i32(fp2); -+ tcg_temp_free_i32(fp1); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FMAX_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_max_s(fp1, cpu_env, fp0, fp1); -+ gen_store_fpr32(ctx, fp1, fd); -+ tcg_temp_free_i32(fp1); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FMAXA_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1); -+ gen_store_fpr32(ctx, fp1, fd); -+ tcg_temp_free_i32(fp1); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FCVT_D_S: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_cvtd_s(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } -+ break; -+ case OPC_LARCH_FTINT_W_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_cvt_w_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FTINT_L_S: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_cvt_l_s(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } -+ break; -+ case OPC_LARCH_FADD_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i64(fp1); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FSUB_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i64(fp1); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FMUL_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i64(fp1); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FDIV_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i64(fp1); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FSQRT_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_sqrt_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FABS_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_abs_d(fp0, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FMOV_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FNEG_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_chs_d(fp0, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FTINTRNE_L_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_round_l_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FTINTRZ_L_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_trunc_l_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FTINTRP_L_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_ceil_l_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FTINTRM_L_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_floor_l_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FTINTRNE_W_D: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_round_w_d(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } -+ break; -+ case OPC_LARCH_FTINTRZ_W_D: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_trunc_w_d(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } -+ break; -+ case OPC_LARCH_FTINTRP_W_D: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_ceil_w_d(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } -+ break; -+ case OPC_LARCH_FTINTRM_W_D: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_floor_w_d(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } -+ break; -+ case OPC_LARCH_FRECIP_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_recip_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FRSQRT_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FRINT_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_rint_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FCLASS_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_class_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FMIN_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_min_d(fp1, cpu_env, fp0, fp1); -+ gen_store_fpr64(ctx, fp1, fd); -+ tcg_temp_free_i64(fp1); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FMINA_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1); -+ gen_store_fpr64(ctx, fp1, fd); -+ tcg_temp_free_i64(fp1); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FMAX_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_max_d(fp1, cpu_env, fp0, fp1); -+ gen_store_fpr64(ctx, fp1, fd); -+ tcg_temp_free_i64(fp1); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FMAXA_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1); -+ gen_store_fpr64(ctx, fp1, fd); -+ tcg_temp_free_i64(fp1); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FCVT_S_D: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_cvts_d(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } -+ break; -+ case OPC_LARCH_FTINT_W_D: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_cvt_w_d(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } -+ break; -+ case OPC_LARCH_FTINT_L_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_cvt_l_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FFINT_S_W: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_cvts_w(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FFINT_D_W: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_cvtd_w(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } -+ break; -+ case OPC_LARCH_FFINT_S_L: -+ { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_cvts_l(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } -+ break; -+ case OPC_LARCH_FFINT_D_L: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_cvtd_l(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ default: -+ LARCH_INVAL("farith"); -+ generate_exception_end(ctx, EXCP_RI); -+ return; -+ } -+} -+ -+/* Coprocessor 3 (FPU) */ -+static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, -+ int fd, int fs, int base, int index) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ check_cp1_enabled(ctx); -+ if (base == 0) { -+ gen_load_gpr(t0, index); -+ } else if (index == 0) { -+ gen_load_gpr(t0, base); -+ } else { -+ gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); -+ } -+ -+ /* -+ * Don't do NOP if destination is zero: we must perform the actual -+ * memory access. -+ */ -+ switch (opc) { -+ case OPC_LARCH_FLDX_S: -+ case OPC_LARCH_FLDGT_S: -+ case OPC_LARCH_FLDLE_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); -+ tcg_gen_trunc_tl_i32(fp0, t0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FLDX_D: -+ case OPC_LARCH_FLDGT_D: -+ case OPC_LARCH_FLDLE_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ case OPC_LARCH_FSTX_S: -+ case OPC_LARCH_FSTGT_S: -+ case OPC_LARCH_FSTLE_S: -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FSTX_D: -+ case OPC_LARCH_FSTGT_D: -+ case OPC_LARCH_FSTLE_D: -+ { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); -+ tcg_temp_free_i64(fp0); -+ } -+ break; -+ } -+ tcg_temp_free(t0); -+} -+ -+static inline void clear_branch_hflags(DisasContext *ctx) -+{ -+ ctx->hflags &= ~LARCH_HFLAG_BMASK; -+ if (ctx->base.is_jmp == DISAS_NEXT) { -+ save_cpu_state(ctx, 0); -+ } else { -+ /* -+ * It is not safe to save ctx->hflags as hflags may be changed -+ * in execution time. -+ */ -+ tcg_gen_andi_i32(hflags, hflags, ~LARCH_HFLAG_BMASK); -+ } -+} -+ -+static void gen_branch(DisasContext *ctx, int insn_bytes) -+{ -+ if (ctx->hflags & LARCH_HFLAG_BMASK) { -+ int proc_hflags = ctx->hflags & LARCH_HFLAG_BMASK; -+ /* Branches completion */ -+ clear_branch_hflags(ctx); -+ ctx->base.is_jmp = DISAS_NORETURN; -+ /* FIXME: Need to clear can_do_io. */ -+ switch (proc_hflags & LARCH_HFLAG_BMASK) { -+ case LARCH_HFLAG_B: -+ /* unconditional branch */ -+ gen_goto_tb(ctx, 0, ctx->btarget); -+ break; -+ case LARCH_HFLAG_BC: -+ /* Conditional branch */ -+ { -+ TCGLabel *l1 = gen_new_label(); -+ -+ tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); -+ gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); -+ gen_set_label(l1); -+ gen_goto_tb(ctx, 0, ctx->btarget); -+ } -+ break; -+ case LARCH_HFLAG_BR: -+ /* unconditional branch to register */ -+ tcg_gen_mov_tl(cpu_PC, btarget); -+ if (ctx->base.singlestep_enabled) { -+ save_cpu_state(ctx, 0); -+ gen_helper_raise_exception_debug(cpu_env); -+ } -+ tcg_gen_lookup_and_goto_ptr(); -+ break; -+ default: -+ fprintf(stderr, "unknown branch 0x%x\n", proc_hflags); -+ abort(); -+ } -+ } -+} -+ -+/* Signed immediate */ -+#define SIMM(op, start, width) \ -+ ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \ -+ << (32 - width)) \ -+ >> (32 - width)) -+/* Zero-extended immediate */ -+#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width))) -+ -+static void gen_sync(int stype) -+{ -+ TCGBar tcg_mo = TCG_BAR_SC; -+ -+ switch (stype) { -+ case 0x4: /* SYNC_WMB */ -+ tcg_mo |= TCG_MO_ST_ST; -+ break; -+ case 0x10: /* SYNC_MB */ -+ tcg_mo |= TCG_MO_ALL; -+ break; -+ case 0x11: /* SYNC_ACQUIRE */ -+ tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; -+ break; -+ case 0x12: /* SYNC_RELEASE */ -+ tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; -+ break; -+ case 0x13: /* SYNC_RMB */ -+ tcg_mo |= TCG_MO_LD_LD; -+ break; -+ default: -+ tcg_mo |= TCG_MO_ALL; -+ break; -+ } -+ -+ tcg_gen_mb(tcg_mo); -+} -+ -+static void gen_crc32(DisasContext *ctx, int rd, int rs, int rt, int sz, -+ int crc32c) -+{ -+ TCGv t0; -+ TCGv t1; -+ TCGv_i32 tsz = tcg_const_i32(1 << sz); -+ if (rd == 0) { -+ /* Treat as NOP. */ -+ return; -+ } -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, rt); -+ gen_load_gpr(t1, rs); -+ -+ if (crc32c) { -+ gen_helper_crc32c(cpu_gpr[rd], t0, t1, tsz); -+ } else { -+ gen_helper_crc32(cpu_gpr[rd], t0, t1, tsz); -+ } -+ -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ tcg_temp_free_i32(tsz); -+} -+ -+#include "cpu-csr.h" -+ -+#ifndef CONFIG_USER_ONLY -+ -+/* -+ * 64-bit CSR read -+ * -+ * @arg : GPR to store the value of CSR register -+ * @csr : CSR register number -+ */ -+static void gen_csr_rdq(DisasContext *ctx, TCGv rd, int64_t a1) -+{ -+ TCGv_i64 csr = tcg_const_i64(a1); -+ gen_helper_csr_rdq(rd, cpu_env, csr); -+} -+ -+/* -+ * 64-bit CSR write -+ * -+ * @arg : GPR that stores the new value of CSR register -+ * @csr : CSR register number -+ */ -+static void gen_csr_wrq(DisasContext *ctx, TCGv val, int64_t a1) -+{ -+ TCGv_i64 csr = tcg_const_i64(a1); -+ gen_helper_csr_wrq(val, cpu_env, val, csr); -+} -+ -+/* -+ * 64-bit CSR exchange -+ * -+ * @arg : GPR that stores the new value of CSR register -+ * @csr : CSR register number -+ */ -+static void gen_csr_xchgq(DisasContext *ctx, TCGv val, TCGv mask, int64_t a1) -+{ -+ TCGv_i64 csr = tcg_const_i64(a1); -+ gen_helper_csr_xchgq(val, cpu_env, val, mask, csr); -+} -+#endif /* !CONFIG_USER_ONLY */ -+ -+static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, -+ CPUState *cs) -+{ -+ DisasContext *ctx = container_of(dcbase, DisasContext, base); -+ CPULOONGARCHState *env = cs->env_ptr; -+ -+ ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; -+ ctx->saved_pc = -1; -+ ctx->insn_flags = env->insn_flags; -+ ctx->btarget = 0; -+ /* Restore state from the tb context. */ -+ ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ -+ restore_cpu_state(env, ctx); -+#ifdef CONFIG_USER_ONLY -+ ctx->mem_idx = LARCH_HFLAG_UM; -+#else -+ ctx->mem_idx = hflags_mmu_index(ctx->hflags); -+#endif -+ ctx->default_tcg_memop_mask = MO_ALIGN; -+ -+ LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, -+ ctx->hflags); -+} -+ -+static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) -+{ -+} -+ -+static void loongarch_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) -+{ -+ DisasContext *ctx = container_of(dcbase, DisasContext, base); -+ -+ tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & LARCH_HFLAG_BMASK, -+ ctx->btarget); -+} -+#if 0 -+static bool loongarch_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, -+ const CPUBreakpoint *bp) -+{ -+ DisasContext *ctx = container_of(dcbase, DisasContext, base); -+ -+ save_cpu_state(ctx, 1); -+ ctx->base.is_jmp = DISAS_NORETURN; -+ gen_helper_raise_exception_debug(cpu_env); -+ /* 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->base.pc_next += 4; -+ return true; -+} -+#endif -+/* 128 and 256 lsx vector instructions are not supported yet */ -+static bool decode_vector_lsx(uint32_t opcode) -+{ -+ uint32_t value = (opcode & 0xff000000); -+ -+ if ((opcode & 0xf0000000) == 0x70000000) { -+ return true; -+ } else if ((opcode & 0xfff00000) == 0x38400000) { -+ return true; -+ } else { -+ switch (value) { -+ case 0x09000000: -+ case 0x0a000000: -+ case 0x0e000000: -+ case 0x0f000000: -+ case 0x2c000000: -+ case 0x30000000: -+ case 0x31000000: -+ case 0x32000000: -+ case 0x33000000: -+ return true; -+ } -+ } -+ return false; -+} -+ -+static bool decode_insn(DisasContext *ctx, uint32_t insn); -+#include "decode-insn.c.inc" -+#include "trans.inc.c" -+ -+static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) -+{ -+ CPULOONGARCHState *env = cs->env_ptr; -+ DisasContext *ctx = container_of(dcbase, DisasContext, base); -+ int insn_bytes = 4; -+ -+ ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next); -+ -+ if (!decode_insn(ctx, ctx->opcode)) { -+ if (decode_vector_lsx(ctx->opcode)) { -+ generate_exception_end(ctx, EXCP_RI); -+ } else { -+ fprintf(stderr, "Error: unkown opcode. 0x%lx: 0x%x\n", -+ ctx->base.pc_next, ctx->opcode); -+ generate_exception_end(ctx, EXCP_RI); -+ } -+ } -+ -+ if (ctx->hflags & LARCH_HFLAG_BMASK) { -+ gen_branch(ctx, insn_bytes); -+ } -+ ctx->base.pc_next += insn_bytes; -+} -+ -+static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) -+{ -+ DisasContext *ctx = container_of(dcbase, DisasContext, base); -+ -+ if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) { -+ save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT); -+ gen_helper_raise_exception_debug(cpu_env); -+ } else { -+ switch (ctx->base.is_jmp) { -+ case DISAS_STOP: -+ gen_save_pc(ctx->base.pc_next); -+ tcg_gen_lookup_and_goto_ptr(); -+ break; -+ case DISAS_NEXT: -+ case DISAS_TOO_MANY: -+ save_cpu_state(ctx, 0); -+ gen_goto_tb(ctx, 0, ctx->base.pc_next); -+ break; -+ case DISAS_EXIT: -+ tcg_gen_exit_tb(NULL, 0); -+ break; -+ case DISAS_NORETURN: -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+ } -+} -+ -+static void loongarch_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) -+{ -+ qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); -+ log_target_disas(cs, dcbase->pc_first, dcbase->tb->size); -+} -+ -+static const TranslatorOps loongarch_tr_ops = { -+ .init_disas_context = loongarch_tr_init_disas_context, -+ .tb_start = loongarch_tr_tb_start, -+ .insn_start = loongarch_tr_insn_start, -+#if 0 -+ .breakpoint_check = loongarch_tr_breakpoint_check, -+#endif -+ .translate_insn = loongarch_tr_translate_insn, -+ .tb_stop = loongarch_tr_tb_stop, -+ .disas_log = loongarch_tr_disas_log, -+}; -+ -+void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb, int max_insns) -+{ -+ DisasContext ctx; -+ -+ translator_loop(&loongarch_tr_ops, &ctx.base, cs, tb, max_insns); -+} -+ -+void loongarch_tcg_init(void) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) -+ cpu_gpr[i] = tcg_global_mem_new(cpu_env, -+ offsetof(CPULOONGARCHState, -+ active_tc.gpr[i]), -+ regnames[i]); -+ -+ for (i = 0; i < 32; i++) { -+ int off = offsetof(CPULOONGARCHState, active_fpu.fpr[i].d); -+ fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); -+ } -+ -+ cpu_PC = tcg_global_mem_new(cpu_env, -+ offsetof(CPULOONGARCHState, active_tc.PC), "PC"); -+ bcond = tcg_global_mem_new(cpu_env, -+ offsetof(CPULOONGARCHState, bcond), "bcond"); -+ btarget = tcg_global_mem_new(cpu_env, -+ offsetof(CPULOONGARCHState, btarget), "btarget"); -+ hflags = tcg_global_mem_new_i32(cpu_env, -+ offsetof(CPULOONGARCHState, hflags), "hflags"); -+ fpu_fcsr0 = tcg_global_mem_new_i32(cpu_env, -+ offsetof(CPULOONGARCHState, active_fpu.fcsr0), -+ "fcsr0"); -+ cpu_lladdr = tcg_global_mem_new(cpu_env, -+ offsetof(CPULOONGARCHState, lladdr), -+ "lladdr"); -+ cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPULOONGARCHState, llval), -+ "llval"); -+} -+ -+void restore_state_to_opc(CPULOONGARCHState *env, TranslationBlock *tb, -+ target_ulong *data) -+{ -+ env->active_tc.PC = data[0]; -+ env->hflags &= ~LARCH_HFLAG_BMASK; -+ env->hflags |= data[1]; -+ switch (env->hflags & LARCH_HFLAG_BMASK) { -+ case LARCH_HFLAG_BR: -+ break; -+ case LARCH_HFLAG_BC: -+ case LARCH_HFLAG_B: -+ env->btarget = data[2]; -+ break; -+ } -+} -diff --git a/target/meson.build b/target/meson.build -index 2f6940255..ac0ce618b 100644 ---- a/target/meson.build -+++ b/target/meson.build -@@ -5,6 +5,7 @@ subdir('cris') - subdir('hexagon') - subdir('hppa') - subdir('i386') -+subdir('loongarch64') - subdir('m68k') - subdir('microblaze') - subdir('mips') --- -2.43.5 - diff --git a/0004-anolis-csv-i386-add-command-to-load-vmcb-to-guest-me.patch b/0004-anolis-csv-i386-add-command-to-load-vmcb-to-guest-me.patch deleted file mode 100644 index 1ea643b..0000000 --- a/0004-anolis-csv-i386-add-command-to-load-vmcb-to-guest-me.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 630d76cc15bd98669162f785861cdd81f2ee8f01 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Wed, 25 Aug 2021 12:25:05 +0800 -Subject: [PATCH 4/8] anolis: csv/i386: add command to load vmcb to guest - memory - -The KVM_CSV_LAUNCH_ENCRYPT_VMCB command is used to load and encrypt -the initial VMCB data to secure memory in an isolated region -that guest owns. - -Signed-off-by: Xin Jiang -Change-Id: I821bc8ab726f1bd22df36c163196951504eaa8da ---- - linux-headers/linux/kvm.h | 1 + - target/i386/csv-sysemu-stub.c | 5 +++++ - target/i386/csv.c | 21 +++++++++++++++++++++ - target/i386/csv.h | 1 + - target/i386/sev.c | 7 +++++-- - 5 files changed, 33 insertions(+), 2 deletions(-) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 53f9202ffb..c6cd3a619a 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1814,6 +1814,7 @@ enum csv_cmd_id { - - KVM_CSV_INIT = KVM_CSV_NR_MIN, - KVM_CSV_LAUNCH_ENCRYPT_DATA, -+ KVM_CSV_LAUNCH_ENCRYPT_VMCB, - }; - - struct kvm_csv_launch_encrypt_data { -diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c -index 236a6909d2..a5ce986e3c 100644 ---- a/target/i386/csv-sysemu-stub.c -+++ b/target/i386/csv-sysemu-stub.c -@@ -24,3 +24,8 @@ int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) - { - g_assert_not_reached(); - } -+ -+int csv_launch_encrypt_vmcb(void) -+{ -+ g_assert_not_reached(); -+} -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 3b3dff5174..d166d3775e 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -162,3 +162,24 @@ csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) - - return ret; - } -+ -+int -+csv_launch_encrypt_vmcb(void) -+{ -+ int ret, fw_error; -+ -+ if (!csv_enabled()) { -+ error_report("%s: CSV is not enabled",__func__); -+ return -1; -+ } -+ -+ ret = csv_ioctl(KVM_CSV_LAUNCH_ENCRYPT_VMCB, NULL, &fw_error); -+ if (ret) { -+ error_report("%s: CSV LAUNCH_ENCRYPT_VMCB ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+err: -+ return ret; -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 6f7b112d96..7dc5c75366 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -34,6 +34,7 @@ typedef struct CsvGuestState CsvGuestState; - - extern struct CsvGuestState csv_guest; - extern int csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops); -+extern int csv_launch_encrypt_vmcb(void); - - int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 023532f4ec..73a794ef74 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -770,8 +770,11 @@ sev_launch_get_measure(Notifier *notifier, void *unused) - } - - if (sev_es_enabled()) { -- /* measure all the VM save areas before getting launch_measure */ -- ret = sev_launch_update_vmsa(sev); -+ if (csv_enabled()) -+ ret = csv_launch_encrypt_vmcb(); -+ else -+ /* measure all the VM save areas before getting launch_measure */ -+ ret = sev_launch_update_vmsa(sev); - if (ret) { - exit(1); - } --- -2.17.1 - diff --git a/0005-Add-linux-headers-and-linux-user.patch b/0005-Add-linux-headers-and-linux-user.patch deleted file mode 100644 index 8e5b37e..0000000 --- a/0005-Add-linux-headers-and-linux-user.patch +++ /dev/null @@ -1,1663 +0,0 @@ -From be4aee607329aee902b9a03936523c7d57d47100 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Fri, 19 Aug 2022 23:47:06 -0400 -Subject: [PATCH 05/28] Add linux-headers and linux-user. - -Change-Id: If052442a981fed87c03ca431c010629dc8e872ca -Signed-off-by: lixianglai ---- - linux-headers/asm-loongarch64/bitsperlong.h | 9 + - linux-headers/asm-loongarch64/kvm.h | 346 ++++++++++++++++++++ - linux-headers/asm-loongarch64/sgidefs.h | 20 ++ - linux-headers/asm-loongarch64/unistd.h | 23 ++ - linux-user/loongarch64/cpu_loop.c | 193 +++++++++++ - linux-user/loongarch64/meson.build | 6 + - linux-user/loongarch64/signal.c | 212 ++++++++++++ - linux-user/loongarch64/sockbits.h | 1 + - linux-user/loongarch64/syscall_nr.h | 287 ++++++++++++++++ - linux-user/loongarch64/target_cpu.h | 45 +++ - linux-user/loongarch64/target_elf.h | 14 + - linux-user/loongarch64/target_fcntl.h | 13 + - linux-user/loongarch64/target_signal.h | 23 ++ - linux-user/loongarch64/target_structs.h | 62 ++++ - linux-user/loongarch64/target_syscall.h | 44 +++ - linux-user/loongarch64/termbits.h | 224 +++++++++++++ - 16 files changed, 1522 insertions(+) - create mode 100644 linux-headers/asm-loongarch64/bitsperlong.h - create mode 100644 linux-headers/asm-loongarch64/kvm.h - create mode 100644 linux-headers/asm-loongarch64/sgidefs.h - create mode 100644 linux-headers/asm-loongarch64/unistd.h - create mode 100644 linux-user/loongarch64/cpu_loop.c - create mode 100644 linux-user/loongarch64/meson.build - create mode 100644 linux-user/loongarch64/signal.c - create mode 100644 linux-user/loongarch64/sockbits.h - create mode 100644 linux-user/loongarch64/syscall_nr.h - create mode 100644 linux-user/loongarch64/target_cpu.h - create mode 100644 linux-user/loongarch64/target_elf.h - create mode 100644 linux-user/loongarch64/target_fcntl.h - create mode 100644 linux-user/loongarch64/target_signal.h - create mode 100644 linux-user/loongarch64/target_structs.h - create mode 100644 linux-user/loongarch64/target_syscall.h - create mode 100644 linux-user/loongarch64/termbits.h - -diff --git a/linux-headers/asm-loongarch64/bitsperlong.h b/linux-headers/asm-loongarch64/bitsperlong.h -new file mode 100644 -index 000000000..5c2c8779a ---- /dev/null -+++ b/linux-headers/asm-loongarch64/bitsperlong.h -@@ -0,0 +1,9 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+#ifndef __ASM_LOONGARCH_BITSPERLONG_H -+#define __ASM_LOONGARCH_BITSPERLONG_H -+ -+#define __BITS_PER_LONG _LOONGARCH_SZLONG -+ -+#include -+ -+#endif /* __ASM_LOONGARCH_BITSPERLONG_H */ -diff --git a/linux-headers/asm-loongarch64/kvm.h b/linux-headers/asm-loongarch64/kvm.h -new file mode 100644 -index 000000000..a24375ee5 ---- /dev/null -+++ b/linux-headers/asm-loongarch64/kvm.h -@@ -0,0 +1,346 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2020 Loongson Technologies, Inc. All rights reserved. -+ * Authors: Sanjay Lal -+ * Authors: Xing Li -+ */ -+ -+#ifndef __LINUX_KVM_LOONGARCH_H -+#define __LINUX_KVM_LOONGARCH_H -+ -+#include -+ -+#define __KVM_HAVE_GUEST_DEBUG -+#define KVM_GUESTDBG_USE_SW_BP 0x00010000 -+#define KVM_GUESTDBG_USE_HW_BP 0x00020000 -+#define KVM_DATA_HW_BREAKPOINT_NUM 8 -+#define KVM_INST_HW_BREAKPOINT_NUM 8 -+ -+/* -+ * KVM Loongarch specific structures and definitions. -+ * -+ * Some parts derived from the x86 version of this file. -+ */ -+ -+#define __KVM_HAVE_READONLY_MEM -+ -+#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 -+ -+#define KVM_LARCH_VCPU_PVTIME_CTRL 2 -+#define KVM_LARCH_VCPU_PVTIME_IPA 0 -+ -+/* -+ * for KVM_GET_REGS and KVM_SET_REGS -+ */ -+struct kvm_regs { -+ /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */ -+ __u64 gpr[32]; -+ __u64 pc; -+}; -+ -+/* -+ * for KVM_GET_CPUCFG -+ */ -+struct kvm_cpucfg { -+ /* out (KVM_GET_CPUCFG) */ -+ __u32 cpucfg[64]; -+}; -+ -+/* -+ * for KVM_GET_FPU and KVM_SET_FPU -+ */ -+struct kvm_fpu { -+ __u32 fcsr; -+ __u32 vcsr; -+ __u64 fcc; /* 8x8 */ -+ struct kvm_fpureg { -+ __u64 val64[4]; //support max 256 bits -+ }fpr[32]; -+}; -+ -+/* -+ * For LOONGARCH, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various -+ * registers. The id field is broken down as follows: -+ * -+ * bits[63..52] - As per linux/kvm.h -+ * bits[51..32] - Must be zero. -+ * bits[31..16] - Register set. -+ * -+ * Register set = 0: GP registers from kvm_regs (see definitions below). -+ * -+ * Register set = 1: CP0 registers. -+ * bits[15..8] - COP0 register set. -+ * -+ * COP0 register set = 0: Main CP0 registers. -+ * bits[7..3] - Register 'rd' index. -+ * bits[2..0] - Register 'sel' index. -+ * -+ * COP0 register set = 1: MAARs. -+ * bits[7..0] - MAAR index. -+ * -+ * Register set = 2: KVM specific registers (see definitions below). -+ * -+ * Register set = 3: FPU / MSA registers (see definitions below). -+ * -+ * Other sets registers may be added in the future. Each set would -+ * have its own identifier in bits[31..16]. -+ */ -+ -+#define KVM_REG_LOONGARCH_GP (KVM_REG_LOONGARCH | 0x0000000000000000ULL) -+#define KVM_REG_LOONGARCH_CSR (KVM_REG_LOONGARCH | 0x0000000000010000ULL) -+#define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x0000000000020000ULL) -+#define KVM_REG_LOONGARCH_FPU (KVM_REG_LOONGARCH | 0x0000000000030000ULL) -+ -+ -+/* -+ * KVM_REG_LOONGARCH_GP - General purpose registers from kvm_regs. -+ */ -+ -+#define KVM_REG_LOONGARCH_R0 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 0) -+#define KVM_REG_LOONGARCH_R1 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 1) -+#define KVM_REG_LOONGARCH_R2 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 2) -+#define KVM_REG_LOONGARCH_R3 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 3) -+#define KVM_REG_LOONGARCH_R4 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 4) -+#define KVM_REG_LOONGARCH_R5 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 5) -+#define KVM_REG_LOONGARCH_R6 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 6) -+#define KVM_REG_LOONGARCH_R7 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 7) -+#define KVM_REG_LOONGARCH_R8 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 8) -+#define KVM_REG_LOONGARCH_R9 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 9) -+#define KVM_REG_LOONGARCH_R10 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 10) -+#define KVM_REG_LOONGARCH_R11 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 11) -+#define KVM_REG_LOONGARCH_R12 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 12) -+#define KVM_REG_LOONGARCH_R13 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 13) -+#define KVM_REG_LOONGARCH_R14 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 14) -+#define KVM_REG_LOONGARCH_R15 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 15) -+#define KVM_REG_LOONGARCH_R16 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 16) -+#define KVM_REG_LOONGARCH_R17 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 17) -+#define KVM_REG_LOONGARCH_R18 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 18) -+#define KVM_REG_LOONGARCH_R19 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 19) -+#define KVM_REG_LOONGARCH_R20 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 20) -+#define KVM_REG_LOONGARCH_R21 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 21) -+#define KVM_REG_LOONGARCH_R22 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 22) -+#define KVM_REG_LOONGARCH_R23 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 23) -+#define KVM_REG_LOONGARCH_R24 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 24) -+#define KVM_REG_LOONGARCH_R25 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 25) -+#define KVM_REG_LOONGARCH_R26 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 26) -+#define KVM_REG_LOONGARCH_R27 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 27) -+#define KVM_REG_LOONGARCH_R28 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 28) -+#define KVM_REG_LOONGARCH_R29 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 29) -+#define KVM_REG_LOONGARCH_R30 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 30) -+#define KVM_REG_LOONGARCH_R31 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 31) -+ -+#define KVM_REG_LOONGARCH_HI (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 32) -+#define KVM_REG_LOONGARCH_LO (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 33) -+#define KVM_REG_LOONGARCH_PC (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 34) -+ -+ -+/* -+ * KVM_REG_LOONGARCH_KVM - KVM specific control registers. -+ */ -+ -+/* -+ * CP0_Count control -+ * DC: Set 0: Master disable CP0_Count and set COUNT_RESUME to now -+ * Set 1: Master re-enable CP0_Count with unchanged bias, handling timer -+ * interrupts since COUNT_RESUME -+ * This can be used to freeze the timer to get a consistent snapshot of -+ * the CP0_Count and timer interrupt pending state, while also resuming -+ * safely without losing time or guest timer interrupts. -+ * Other: Reserved, do not change. -+ */ -+#define KVM_REG_LOONGARCH_COUNT_CTL (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 0) -+#define KVM_REG_LOONGARCH_COUNT_CTL_DC 0x00000001 -+ -+/* -+ * CP0_Count resume monotonic nanoseconds -+ * The monotonic nanosecond time of the last set of COUNT_CTL.DC (master -+ * disable). Any reads and writes of Count related registers while -+ * COUNT_CTL.DC=1 will appear to occur at this time. When COUNT_CTL.DC is -+ * cleared again (master enable) any timer interrupts since this time will be -+ * emulated. -+ * Modifications to times in the future are rejected. -+ */ -+#define KVM_REG_LOONGARCH_COUNT_RESUME (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 1) -+/* -+ * CP0_Count rate in Hz -+ * Specifies the rate of the CP0_Count timer in Hz. Modifications occur without -+ * discontinuities in CP0_Count. -+ */ -+#define KVM_REG_LOONGARCH_COUNT_HZ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 2) -+ -+#define KVM_REG_LOONGARCH_COUNTER (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3) -+ -+#define KVM_REG_LOONGARCH_VCPU_RESET (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 4) -+ -+struct kvm_iocsr_entry { -+ __u32 addr; -+ __u32 pad; -+ __u64 data; -+}; -+ -+struct kvm_csr_entry { -+ __u32 index; -+ __u32 reserved; -+ __u64 data; -+}; -+ -+/* for KVM_GET_MSRS and KVM_SET_MSRS */ -+struct kvm_msrs { -+ __u32 ncsrs; /* number of msrs in entries */ -+ __u32 pad; -+ struct kvm_csr_entry entries[0]; -+}; -+ -+#define __KVM_HAVE_IRQ_LINE -+ -+struct kvm_debug_exit_arch { -+ __u64 epc; -+ __u32 fwps; -+ __u32 mwps; -+ __u32 exception; -+}; -+ -+/* for KVM_SET_GUEST_DEBUG */ -+struct hw_breakpoint { -+ __u64 addr; -+ __u64 mask; -+ __u32 asid; -+ __u32 ctrl; -+}; -+ -+struct kvm_guest_debug_arch { -+ struct hw_breakpoint data_breakpoint[KVM_DATA_HW_BREAKPOINT_NUM]; -+ struct hw_breakpoint inst_breakpoint[KVM_INST_HW_BREAKPOINT_NUM]; -+ int inst_bp_nums, data_bp_nums; -+}; -+ -+/* definition of registers in kvm_run */ -+struct kvm_sync_regs { -+}; -+ -+/* dummy definition */ -+struct kvm_sregs { -+}; -+ -+struct kvm_loongarch_interrupt { -+ /* in */ -+ __u32 cpu; -+ __u32 irq; -+}; -+ -+#define KVM_IRQCHIP_LS7A_IOAPIC 0x0 -+#define KVM_IRQCHIP_LS3A_GIPI 0x1 -+#define KVM_IRQCHIP_LS3A_HT_IRQ 0x2 -+#define KVM_IRQCHIP_LS3A_ROUTE 0x3 -+#define KVM_IRQCHIP_LS3A_EXTIRQ 0x4 -+#define KVM_IRQCHIP_LS3A_IPMASK 0x5 -+#define KVM_NR_IRQCHIPS 1 -+#define KVM_IRQCHIP_NUM_PINS 64 -+ -+#define KVM_MAX_CORES 256 -+#define KVM_EXTIOI_IRQS (256) -+#define KVM_EXTIOI_IRQS_BITMAP_SIZE (KVM_EXTIOI_IRQS / 8) -+/* map to ipnum per 32 irqs */ -+#define KVM_EXTIOI_IRQS_IPMAP_SIZE (KVM_EXTIOI_IRQS / 32) -+#define KVM_EXTIOI_IRQS_PER_GROUP 32 -+#define KVM_EXTIOI_IRQS_COREMAP_SIZE (KVM_EXTIOI_IRQS) -+#define KVM_EXTIOI_IRQS_NODETYPE_SIZE 16 -+ -+struct ls7a_ioapic_state { -+ __u64 int_id; -+ /* 0x020 interrupt mask register */ -+ __u64 int_mask; -+ /* 0x040 1=msi */ -+ __u64 htmsi_en; -+ /* 0x060 edge=1 level =0 */ -+ __u64 intedge; -+ /* 0x080 for clean edge int,set 1 clean,set 0 is noused */ -+ __u64 intclr; -+ /* 0x0c0 */ -+ __u64 auto_crtl0; -+ /* 0x0e0 */ -+ __u64 auto_crtl1; -+ /* 0x100 - 0x140 */ -+ __u8 route_entry[64]; -+ /* 0x200 - 0x240 */ -+ __u8 htmsi_vector[64]; -+ /* 0x300 */ -+ __u64 intisr_chip0; -+ /* 0x320 */ -+ __u64 intisr_chip1; -+ /* edge detection */ -+ __u64 last_intirr; -+ /* 0x380 interrupt request register */ -+ __u64 intirr; -+ /* 0x3a0 interrupt service register */ -+ __u64 intisr; -+ /* 0x3e0 interrupt level polarity selection register, -+ * 0 for high level tirgger -+ */ -+ __u64 int_polarity; -+}; -+ -+struct loongarch_gipi_single { -+ __u32 status; -+ __u32 en; -+ __u32 set; -+ __u32 clear; -+ __u64 buf[4]; -+}; -+ -+struct loongarch_gipiState { -+ struct loongarch_gipi_single core[KVM_MAX_CORES]; -+}; -+ -+struct kvm_loongarch_ls3a_extirq_state { -+ union ext_en_r { -+ uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; -+ uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; -+ uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE]; -+ } ext_en_r; -+ union bounce_r { -+ uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; -+ uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; -+ uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE]; -+ } bounce_r; -+ union ext_isr_r { -+ uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; -+ uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; -+ uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE]; -+ } ext_isr_r; -+ union ext_core_isr_r { -+ uint64_t reg_u64[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; -+ uint32_t reg_u32[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; -+ uint8_t reg_u8[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE]; -+ } ext_core_isr_r; -+ union ip_map_r { -+ uint64_t reg_u64; -+ uint32_t reg_u32[KVM_EXTIOI_IRQS_IPMAP_SIZE / 4]; -+ uint8_t reg_u8[KVM_EXTIOI_IRQS_IPMAP_SIZE]; -+ } ip_map_r; -+ union core_map_r { -+ uint64_t reg_u64[KVM_EXTIOI_IRQS_COREMAP_SIZE / 8]; -+ uint32_t reg_u32[KVM_EXTIOI_IRQS_COREMAP_SIZE / 4]; -+ uint8_t reg_u8[KVM_EXTIOI_IRQS_COREMAP_SIZE]; -+ } core_map_r; -+ union node_type_r { -+ uint64_t reg_u64[KVM_EXTIOI_IRQS_NODETYPE_SIZE / 4]; -+ uint32_t reg_u32[KVM_EXTIOI_IRQS_NODETYPE_SIZE / 2]; -+ uint16_t reg_u16[KVM_EXTIOI_IRQS_NODETYPE_SIZE]; -+ uint8_t reg_u8[KVM_EXTIOI_IRQS_NODETYPE_SIZE * 2]; -+ } node_type_r; -+}; -+ -+struct loongarch_kvm_irqchip { -+ __u16 chip_id; -+ __u16 len; -+ __u16 vcpu_id; -+ __u16 reserved; -+ char data[0]; -+}; -+ -+#endif /* __LINUX_KVM_LOONGARCH_H */ -diff --git a/linux-headers/asm-loongarch64/sgidefs.h b/linux-headers/asm-loongarch64/sgidefs.h -new file mode 100644 -index 000000000..b80960834 ---- /dev/null -+++ b/linux-headers/asm-loongarch64/sgidefs.h -@@ -0,0 +1,20 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ -+/* -+* Copyright (C) 2020 Loongson Technology Corporation Limited -+* -+* Author: Hanlu Li -+*/ -+#ifndef __ASM_SGIDEFS_H -+#define __ASM_SGIDEFS_H -+ -+#define _LOONGARCH_ISA_LOONGARCH32 6 -+#define _LOONGARCH_ISA_LOONGARCH64 7 -+ -+/* -+ * Subprogram calling convention -+ */ -+#define _LOONGARCH_SIM_ABILP32 1 -+#define _LOONGARCH_SIM_ABILPX32 2 -+#define _LOONGARCH_SIM_ABILP64 3 -+ -+#endif /* __ASM_SGIDEFS_H */ -diff --git a/linux-headers/asm-loongarch64/unistd.h b/linux-headers/asm-loongarch64/unistd.h -new file mode 100644 -index 000000000..2a6014562 ---- /dev/null -+++ b/linux-headers/asm-loongarch64/unistd.h -@@ -0,0 +1,23 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* -+ * 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. -+ * -+ * 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 . -+ * -+ * Copyright (C) 2020 Loongson Technologies, Inc. -+ * Authors: Jun Yi -+ */ -+ -+#ifdef __LP64__ -+#define __ARCH_WANT_NEW_STAT -+#endif /* __LP64__ */ -+ -+#include -diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c -new file mode 100644 -index 000000000..6d4093e1d ---- /dev/null -+++ b/linux-user/loongarch64/cpu_loop.c -@@ -0,0 +1,193 @@ -+/* -+ * qemu user cpu loop -+ * -+ * Copyright (c) 2003-2008 Fabrice Bellard -+ * -+ * 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 . -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu.h" -+#include "cpu_loop-common.h" -+#include "elf.h" -+ -+/* Break codes */ -+enum { -+ BRK_OVERFLOW = 6, -+ BRK_DIVZERO = 7 -+}; -+ -+static int do_break(CPULOONGARCHState *env, target_siginfo_t *info, -+ unsigned int code) -+{ -+ int ret = -1; -+ -+ switch (code) { -+ case BRK_OVERFLOW: -+ case BRK_DIVZERO: -+ info->si_signo = TARGET_SIGFPE; -+ info->si_errno = 0; -+ info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV; -+ queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info); -+ ret = 0; -+ break; -+ default: -+ info->si_signo = TARGET_SIGTRAP; -+ info->si_errno = 0; -+ queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info); -+ ret = 0; -+ break; -+ } -+ -+ return ret; -+} -+ -+void cpu_loop(CPULOONGARCHState *env) -+{ -+ CPUState *cs = CPU(loongarch_env_get_cpu(env)); -+ target_siginfo_t info; -+ int trapnr; -+ abi_long ret; -+ -+ for (;;) { -+ cpu_exec_start(cs); -+ trapnr = cpu_exec(cs); -+ cpu_exec_end(cs); -+ process_queued_cpu_work(cs); -+ -+ switch (trapnr) { -+ case EXCP_SYSCALL: -+ env->active_tc.PC += 4; -+ ret = do_syscall(env, env->active_tc.gpr[11], -+ env->active_tc.gpr[4], env->active_tc.gpr[5], -+ env->active_tc.gpr[6], env->active_tc.gpr[7], -+ env->active_tc.gpr[8], env->active_tc.gpr[9], -+ -1, -1); -+ if (ret == -TARGET_ERESTARTSYS) { -+ env->active_tc.PC -= 4; -+ break; -+ } -+ if (ret == -TARGET_QEMU_ESIGRETURN) { -+ /* Returning from a successful sigreturn syscall. -+ Avoid clobbering register state. */ -+ break; -+ } -+ env->active_tc.gpr[4] = ret; -+ break; -+ case EXCP_TLBL: -+ case EXCP_TLBS: -+ case EXCP_AdEL: -+ case EXCP_AdES: -+ info.si_signo = TARGET_SIGSEGV; -+ info.si_errno = 0; -+ /* XXX: check env->error_code */ -+ info.si_code = TARGET_SEGV_MAPERR; -+ info._sifields._sigfault._addr = env->CSR_BADV; -+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); -+ break; -+ case EXCP_FPDIS: -+ case EXCP_LSXDIS: -+ case EXCP_LASXDIS: -+ case EXCP_RI: -+ info.si_signo = TARGET_SIGILL; -+ info.si_errno = 0; -+ info.si_code = 0; -+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); -+ break; -+ case EXCP_INTERRUPT: -+ /* just indicate that signals should be handled asap */ -+ break; -+ case EXCP_DEBUG: -+ info.si_signo = TARGET_SIGTRAP; -+ info.si_errno = 0; -+ info.si_code = TARGET_TRAP_BRKPT; -+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); -+ break; -+ case EXCP_FPE: -+ info.si_signo = TARGET_SIGFPE; -+ info.si_errno = 0; -+ info.si_code = TARGET_FPE_FLTUNK; -+ if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_INVALID) { -+ info.si_code = TARGET_FPE_FLTINV; -+ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_DIV0) { -+ info.si_code = TARGET_FPE_FLTDIV; -+ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_OVERFLOW) { -+ info.si_code = TARGET_FPE_FLTOVF; -+ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_UNDERFLOW) { -+ info.si_code = TARGET_FPE_FLTUND; -+ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_INEXACT) { -+ info.si_code = TARGET_FPE_FLTRES; -+ } -+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); -+ break; -+ case EXCP_BREAK: -+ { -+ abi_ulong trap_instr; -+ unsigned int code; -+ -+ ret = get_user_u32(trap_instr, env->active_tc.PC); -+ if (ret != 0) { -+ goto error; -+ } -+ -+ code = trap_instr & 0x7fff; -+ -+ if (do_break(env, &info, code) != 0) { -+ goto error; -+ } -+ } -+ break; -+ case EXCP_TRAP: -+ { -+ abi_ulong trap_instr; -+ unsigned int code = 0; -+ -+ ret = get_user_u32(trap_instr, env->active_tc.PC); -+ -+ if (ret != 0) { -+ goto error; -+ } -+ -+ /* The immediate versions don't provide a code. */ -+ if (!(trap_instr & 0xFC000000)) { -+ code = ((trap_instr >> 6) & ((1 << 10) - 1)); -+ } -+ -+ if (do_break(env, &info, code) != 0) { -+ goto error; -+ } -+ } -+ break; -+ case EXCP_ATOMIC: -+ cpu_exec_step_atomic(cs); -+ break; -+ default: -+error: -+ printf("111111\n"); -+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr); -+ abort(); -+ } -+ process_pending_signals(env); -+ } -+} -+ -+void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ env->active_tc.gpr[i] = regs->regs[i]; -+ } -+ env->active_tc.PC = regs->csr_era & ~(target_ulong)1; -+} -diff --git a/linux-user/loongarch64/meson.build b/linux-user/loongarch64/meson.build -new file mode 100644 -index 000000000..c4c0b4d70 ---- /dev/null -+++ b/linux-user/loongarch64/meson.build -@@ -0,0 +1,6 @@ -+syscall_nr_generators += { -+ 'loongarch64': generator(sh, -+ arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@', -+ '', 'TARGET_SYSCALL_OFFSET' ], -+ output: '@BASENAME@_nr.h') -+} -diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c -new file mode 100644 -index 000000000..6fe685275 ---- /dev/null -+++ b/linux-user/loongarch64/signal.c -@@ -0,0 +1,212 @@ -+/* -+ * Emulation of Linux signals -+ * -+ * Copyright (c) 2003 Fabrice Bellard -+ * -+ * 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 . -+ */ -+#include "qemu/osdep.h" -+#include "qemu.h" -+#include "signal-common.h" -+#include "linux-user/trace.h" -+ -+#define FPU_REG_WIDTH 256 -+union fpureg { -+ uint32_t val32[FPU_REG_WIDTH / 32]; -+ uint64_t val64[FPU_REG_WIDTH / 64]; -+}; -+ -+struct target_sigcontext { -+ uint64_t sc_pc; -+ uint64_t sc_regs[32]; -+ uint32_t sc_flags; -+ -+ uint32_t sc_fcsr; -+ uint32_t sc_vcsr; -+ uint64_t sc_fcc; -+ union fpureg sc_fpregs[32] __attribute__((aligned(32))); -+ -+ uint32_t sc_reserved; -+ -+}; -+ -+struct sigframe { -+ uint32_t sf_ass[4]; /* argument save space for o32 */ -+ uint32_t sf_code[2]; /* signal trampoline */ -+ struct target_sigcontext sf_sc; -+ target_sigset_t sf_mask; -+}; -+ -+struct target_ucontext { -+ target_ulong tuc_flags; -+ target_ulong tuc_link; -+ target_stack_t tuc_stack; -+ target_ulong pad0; -+ struct target_sigcontext tuc_mcontext; -+ target_sigset_t tuc_sigmask; -+}; -+ -+struct target_rt_sigframe { -+ uint32_t rs_ass[4]; /* argument save space for o32 */ -+ uint32_t rs_code[2]; /* signal trampoline */ -+ struct target_siginfo rs_info; -+ struct target_ucontext rs_uc; -+}; -+ -+static inline void setup_sigcontext(CPULOONGARCHState *regs, -+ struct target_sigcontext *sc) -+{ -+ int i; -+ -+ __put_user(exception_resume_pc(regs), &sc->sc_pc); -+ regs->hflags &= ~LARCH_HFLAG_BMASK; -+ -+ __put_user(0, &sc->sc_regs[0]); -+ for (i = 1; i < 32; ++i) { -+ __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); -+ } -+ -+ for (i = 0; i < 32; ++i) { -+ __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i].val64[0]); -+ } -+} -+ -+static inline void -+restore_sigcontext(CPULOONGARCHState *regs, struct target_sigcontext *sc) -+{ -+ int i; -+ -+ __get_user(regs->CSR_ERA, &sc->sc_pc); -+ -+ for (i = 1; i < 32; ++i) { -+ __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); -+ } -+ -+ for (i = 0; i < 32; ++i) { -+ __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i].val64[0]); -+ } -+} -+ -+/* -+ * Determine which stack to use.. -+ */ -+static inline abi_ulong -+get_sigframe(struct target_sigaction *ka, CPULOONGARCHState *regs, -+ size_t frame_size) -+{ -+ unsigned long sp; -+ -+ /* -+ * FPU emulator may have its own trampoline active just -+ * above the user stack, 16-bytes before the next lowest -+ * 16 byte boundary. Try to avoid trashing it. -+ */ -+ sp = target_sigsp(get_sp_from_cpustate(regs) - 32, ka); -+ -+ return (sp - frame_size) & ~7; -+} -+ -+void setup_rt_frame(int sig, struct target_sigaction *ka, -+ target_siginfo_t *info, -+ target_sigset_t *set, CPULOONGARCHState *env) -+{ -+ struct target_rt_sigframe *frame; -+ abi_ulong frame_addr; -+ int i; -+ -+ frame_addr = get_sigframe(ka, env, sizeof(*frame)); -+ trace_user_setup_rt_frame(env, frame_addr); -+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { -+ goto give_sigsegv; -+ } -+ -+ /* ori a7, $r0, TARGET_NR_rt_sigreturn */ -+ /* syscall 0 */ -+ __put_user(0x0380000b + (TARGET_NR_rt_sigreturn << 10), &frame->rs_code[0]); -+ __put_user(0x002b0000, &frame->rs_code[1]); -+ -+ tswap_siginfo(&frame->rs_info, info); -+ -+ __put_user(0, &frame->rs_uc.tuc_flags); -+ __put_user(0, &frame->rs_uc.tuc_link); -+ target_save_altstack(&frame->rs_uc.tuc_stack, env); -+ -+ setup_sigcontext(env, &frame->rs_uc.tuc_mcontext); -+ -+ for (i = 0; i < TARGET_NSIG_WORDS; i++) { -+ __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]); -+ } -+ -+ /* -+ * Arguments to signal handler: -+ * -+ * a0 = signal number -+ * a1 = pointer to siginfo_t -+ * a2 = pointer to ucontext_t -+ * -+ * $25 and PC point to the signal handler, $29 points to the -+ * struct sigframe. -+ */ -+ env->active_tc.gpr[4] = sig; -+ env->active_tc.gpr[5] = frame_addr -+ + offsetof(struct target_rt_sigframe, rs_info); -+ env->active_tc.gpr[6] = frame_addr -+ + offsetof(struct target_rt_sigframe, rs_uc); -+ env->active_tc.gpr[3] = frame_addr; -+ env->active_tc.gpr[1] = frame_addr -+ + offsetof(struct target_rt_sigframe, rs_code); -+ /* The original kernel code sets CP0_ERA to the handler -+ * since it returns to userland using ertn -+ * we cannot do this here, and we must set PC directly */ -+ env->active_tc.PC = env->active_tc.gpr[20] = ka->_sa_handler; -+ unlock_user_struct(frame, frame_addr, 1); -+ return; -+ -+give_sigsegv: -+ unlock_user_struct(frame, frame_addr, 1); -+ force_sigsegv(sig); -+} -+ -+long do_rt_sigreturn(CPULOONGARCHState *env) -+{ -+ struct target_rt_sigframe *frame; -+ abi_ulong frame_addr; -+ sigset_t blocked; -+ -+ frame_addr = env->active_tc.gpr[3]; -+ trace_user_do_rt_sigreturn(env, frame_addr); -+ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { -+ goto badframe; -+ } -+ -+ target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask); -+ set_sigmask(&blocked); -+ -+ restore_sigcontext(env, &frame->rs_uc.tuc_mcontext); -+ -+ if (do_sigaltstack(frame_addr + -+ offsetof(struct target_rt_sigframe, rs_uc.tuc_stack), -+ 0, get_sp_from_cpustate(env)) == -EFAULT) -+ goto badframe; -+ -+ env->active_tc.PC = env->CSR_ERA; -+ /* I am not sure this is right, but it seems to work -+ * maybe a problem with nested signals ? */ -+ env->CSR_ERA = 0; -+ return -TARGET_QEMU_ESIGRETURN; -+ -+badframe: -+ force_sig(TARGET_SIGSEGV); -+ return -TARGET_QEMU_ESIGRETURN; -+} -diff --git a/linux-user/loongarch64/sockbits.h b/linux-user/loongarch64/sockbits.h -new file mode 100644 -index 000000000..0e4c8f012 ---- /dev/null -+++ b/linux-user/loongarch64/sockbits.h -@@ -0,0 +1 @@ -+#include "../generic/sockbits.h" -diff --git a/linux-user/loongarch64/syscall_nr.h b/linux-user/loongarch64/syscall_nr.h -new file mode 100644 -index 000000000..a30aca8d8 ---- /dev/null -+++ b/linux-user/loongarch64/syscall_nr.h -@@ -0,0 +1,287 @@ -+#ifndef LINUX_USER_LOONGARCH_SYSCALL_NR_H -+#define LINUX_USER_LOONGARCH_SYSCALL_NR_H -+ -+#define TARGET_NR_io_setup 0 -+#define TARGET_NR_io_destroy 1 -+#define TARGET_NR_io_submit 2 -+#define TARGET_NR_io_cancel 3 -+#define TARGET_NR_io_getevents 4 -+#define TARGET_NR_setxattr 5 -+#define TARGET_NR_lsetxattr 6 -+#define TARGET_NR_fsetxattr 7 -+#define TARGET_NR_getxattr 8 -+#define TARGET_NR_lgetxattr 9 -+#define TARGET_NR_fgetxattr 10 -+#define TARGET_NR_listxattr 11 -+#define TARGET_NR_llistxattr 12 -+#define TARGET_NR_flistxattr 13 -+#define TARGET_NR_removexattr 14 -+#define TARGET_NR_lremovexattr 15 -+#define TARGET_NR_fremovexattr 16 -+#define TARGET_NR_getcwd 17 -+#define TARGET_NR_lookup_dcookie 18 -+#define TARGET_NR_eventfd2 19 -+#define TARGET_NR_epoll_create1 20 -+#define TARGET_NR_epoll_ctl 21 -+#define TARGET_NR_epoll_pwait 22 -+#define TARGET_NR_dup 23 -+#define TARGET_NR_dup3 24 -+#define TARGET_NR_fcntl 25 -+#define TARGET_NR_inotify_init1 26 -+#define TARGET_NR_inotify_add_watch 27 -+#define TARGET_NR_inotify_rm_watch 28 -+#define TARGET_NR_ioctl 29 -+#define TARGET_NR_ioprio_set 30 -+#define TARGET_NR_ioprio_get 31 -+#define TARGET_NR_flock 32 -+#define TARGET_NR_mknodat 33 -+#define TARGET_NR_mkdirat 34 -+#define TARGET_NR_unlinkat 35 -+#define TARGET_NR_symlinkat 36 -+#define TARGET_NR_linkat 37 -+#define TARGET_NR_renameat 38 -+#define TARGET_NR_umount2 39 -+#define TARGET_NR_mount 40 -+#define TARGET_NR_pivot_root 41 -+#define TARGET_NR_nfsservctl 42 -+#define TARGET_NR_statfs 43 -+#define TARGET_NR_fstatfs 44 -+#define TARGET_NR_truncate 45 -+#define TARGET_NR_ftruncate 46 -+#define TARGET_NR_fallocate 47 -+#define TARGET_NR_faccessat 48 -+#define TARGET_NR_chdir 49 -+#define TARGET_NR_fchdir 50 -+#define TARGET_NR_chroot 51 -+#define TARGET_NR_fchmod 52 -+#define TARGET_NR_fchmodat 53 -+#define TARGET_NR_fchownat 54 -+#define TARGET_NR_fchown 55 -+#define TARGET_NR_openat 56 -+#define TARGET_NR_close 57 -+#define TARGET_NR_vhangup 58 -+#define TARGET_NR_pipe2 59 -+#define TARGET_NR_quotactl 60 -+#define TARGET_NR_getdents64 61 -+#define TARGET_NR_lseek 62 -+#define TARGET_NR_read 63 -+#define TARGET_NR_write 64 -+#define TARGET_NR_readv 65 -+#define TARGET_NR_writev 66 -+#define TARGET_NR_pread64 67 -+#define TARGET_NR_pwrite64 68 -+#define TARGET_NR_preadv 69 -+#define TARGET_NR_pwritev 70 -+#define TARGET_NR_sendfile 71 -+#define TARGET_NR_pselect6 72 -+#define TARGET_NR_ppoll 73 -+#define TARGET_NR_signalfd4 74 -+#define TARGET_NR_vmsplice 75 -+#define TARGET_NR_splice 76 -+#define TARGET_NR_tee 77 -+#define TARGET_NR_readlinkat 78 -+#define TARGET_NR_newfstatat 79 -+#define TARGET_NR_fstat 80 -+#define TARGET_NR_sync 81 -+#define TARGET_NR_fsync 82 -+#define TARGET_NR_fdatasync 83 -+#define TARGET_NR_sync_file_range 84 -+#define TARGET_NR_timerfd_create 85 -+#define TARGET_NR_timerfd_settime 86 -+#define TARGET_NR_timerfd_gettime 87 -+#define TARGET_NR_utimensat 88 -+#define TARGET_NR_acct 89 -+#define TARGET_NR_capget 90 -+#define TARGET_NR_capset 91 -+#define TARGET_NR_personality 92 -+#define TARGET_NR_exit 93 -+#define TARGET_NR_exit_group 94 -+#define TARGET_NR_waitid 95 -+#define TARGET_NR_set_tid_address 96 -+#define TARGET_NR_unshare 97 -+#define TARGET_NR_futex 98 -+#define TARGET_NR_set_robust_list 99 -+#define TARGET_NR_get_robust_list 100 -+#define TARGET_NR_nanosleep 101 -+#define TARGET_NR_getitimer 102 -+#define TARGET_NR_setitimer 103 -+#define TARGET_NR_kexec_load 104 -+#define TARGET_NR_init_module 105 -+#define TARGET_NR_delete_module 106 -+#define TARGET_NR_timer_create 107 -+#define TARGET_NR_timer_gettime 108 -+#define TARGET_NR_timer_getoverrun 109 -+#define TARGET_NR_timer_settime 110 -+#define TARGET_NR_timer_delete 111 -+#define TARGET_NR_clock_settime 112 -+#define TARGET_NR_clock_gettime 113 -+#define TARGET_NR_clock_getres 114 -+#define TARGET_NR_clock_nanosleep 115 -+#define TARGET_NR_syslog 116 -+#define TARGET_NR_ptrace 117 -+#define TARGET_NR_sched_setparam 118 -+#define TARGET_NR_sched_setscheduler 119 -+#define TARGET_NR_sched_getscheduler 120 -+#define TARGET_NR_sched_getparam 121 -+#define TARGET_NR_sched_setaffinity 122 -+#define TARGET_NR_sched_getaffinity 123 -+#define TARGET_NR_sched_yield 124 -+#define TARGET_NR_sched_get_priority_max 125 -+#define TARGET_NR_sched_get_priority_min 126 -+#define TARGET_NR_sched_rr_get_interval 127 -+#define TARGET_NR_restart_syscall 128 -+#define TARGET_NR_kill 129 -+#define TARGET_NR_tkill 130 -+#define TARGET_NR_tgkill 131 -+#define TARGET_NR_sigaltstack 132 -+#define TARGET_NR_rt_sigsuspend 133 -+#define TARGET_NR_rt_sigaction 134 -+#define TARGET_NR_rt_sigprocmask 135 -+#define TARGET_NR_rt_sigpending 136 -+#define TARGET_NR_rt_sigtimedwait 137 -+#define TARGET_NR_rt_sigqueueinfo 138 -+#define TARGET_NR_rt_sigreturn 139 -+#define TARGET_NR_setpriority 140 -+#define TARGET_NR_getpriority 141 -+#define TARGET_NR_reboot 142 -+#define TARGET_NR_setregid 143 -+#define TARGET_NR_setgid 144 -+#define TARGET_NR_setreuid 145 -+#define TARGET_NR_setuid 146 -+#define TARGET_NR_setresuid 147 -+#define TARGET_NR_getresuid 148 -+#define TARGET_NR_setresgid 149 -+#define TARGET_NR_getresgid 150 -+#define TARGET_NR_setfsuid 151 -+#define TARGET_NR_setfsgid 152 -+#define TARGET_NR_times 153 -+#define TARGET_NR_setpgid 154 -+#define TARGET_NR_getpgid 155 -+#define TARGET_NR_getsid 156 -+#define TARGET_NR_setsid 157 -+#define TARGET_NR_getgroups 158 -+#define TARGET_NR_setgroups 159 -+#define TARGET_NR_uname 160 -+#define TARGET_NR_sethostname 161 -+#define TARGET_NR_setdomainname 162 -+#define TARGET_NR_getrlimit 163 -+#define TARGET_NR_setrlimit 164 -+#define TARGET_NR_getrusage 165 -+#define TARGET_NR_umask 166 -+#define TARGET_NR_prctl 167 -+#define TARGET_NR_getcpu 168 -+#define TARGET_NR_gettimeofday 169 -+#define TARGET_NR_settimeofday 170 -+#define TARGET_NR_adjtimex 171 -+#define TARGET_NR_getpid 172 -+#define TARGET_NR_getppid 173 -+#define TARGET_NR_getuid 174 -+#define TARGET_NR_geteuid 175 -+#define TARGET_NR_getgid 176 -+#define TARGET_NR_getegid 177 -+#define TARGET_NR_gettid 178 -+#define TARGET_NR_sysinfo 179 -+#define TARGET_NR_mq_open 180 -+#define TARGET_NR_mq_unlink 181 -+#define TARGET_NR_mq_timedsend 182 -+#define TARGET_NR_mq_timedreceive 183 -+#define TARGET_NR_mq_notify 184 -+#define TARGET_NR_mq_getsetattr 185 -+#define TARGET_NR_msgget 186 -+#define TARGET_NR_msgctl 187 -+#define TARGET_NR_msgrcv 188 -+#define TARGET_NR_msgsnd 189 -+#define TARGET_NR_semget 190 -+#define TARGET_NR_semctl 191 -+#define TARGET_NR_semtimedop 192 -+#define TARGET_NR_semop 193 -+#define TARGET_NR_shmget 194 -+#define TARGET_NR_shmctl 195 -+#define TARGET_NR_shmat 196 -+#define TARGET_NR_shmdt 197 -+#define TARGET_NR_socket 198 -+#define TARGET_NR_socketpair 199 -+#define TARGET_NR_bind 200 -+#define TARGET_NR_listen 201 -+#define TARGET_NR_accept 202 -+#define TARGET_NR_connect 203 -+#define TARGET_NR_getsockname 204 -+#define TARGET_NR_getpeername 205 -+#define TARGET_NR_sendto 206 -+#define TARGET_NR_recvfrom 207 -+#define TARGET_NR_setsockopt 208 -+#define TARGET_NR_getsockopt 209 -+#define TARGET_NR_shutdown 210 -+#define TARGET_NR_sendmsg 211 -+#define TARGET_NR_recvmsg 212 -+#define TARGET_NR_readahead 213 -+#define TARGET_NR_brk 214 -+#define TARGET_NR_munmap 215 -+#define TARGET_NR_mremap 216 -+#define TARGET_NR_add_key 217 -+#define TARGET_NR_request_key 218 -+#define TARGET_NR_keyctl 219 -+#define TARGET_NR_clone 220 -+#define TARGET_NR_execve 221 -+#define TARGET_NR_mmap 222 -+#define TARGET_NR_fadvise64 223 -+#define TARGET_NR_swapon 224 -+#define TARGET_NR_swapoff 225 -+#define TARGET_NR_mprotect 226 -+#define TARGET_NR_msync 227 -+#define TARGET_NR_mlock 228 -+#define TARGET_NR_munlock 229 -+#define TARGET_NR_mlockall 230 -+#define TARGET_NR_munlockall 231 -+#define TARGET_NR_mincore 232 -+#define TARGET_NR_madvise 233 -+#define TARGET_NR_remap_file_pages 234 -+#define TARGET_NR_mbind 235 -+#define TARGET_NR_get_mempolicy 236 -+#define TARGET_NR_set_mempolicy 237 -+#define TARGET_NR_migrate_pages 238 -+#define TARGET_NR_move_pages 239 -+#define TARGET_NR_rt_tgsigqueueinfo 240 -+#define TARGET_NR_perf_event_open 241 -+#define TARGET_NR_accept4 242 -+#define TARGET_NR_recvmmsg 243 -+#define TARGET_NR_arch_specific_syscall 244 -+#define TARGET_NR_wait4 260 -+#define TARGET_NR_prlimit64 261 -+#define TARGET_NR_fanotify_init 262 -+#define TARGET_NR_fanotify_mark 263 -+#define TARGET_NR_name_to_handle_at 264 -+#define TARGET_NR_open_by_handle_at 265 -+#define TARGET_NR_clock_adjtime 266 -+#define TARGET_NR_syncfs 267 -+#define TARGET_NR_setns 268 -+#define TARGET_NR_sendmmsg 269 -+#define TARGET_NR_process_vm_readv 270 -+#define TARGET_NR_process_vm_writev 271 -+#define TARGET_NR_kcmp 272 -+#define TARGET_NR_finit_module 273 -+#define TARGET_NR_sched_setattr 274 -+#define TARGET_NR_sched_getattr 275 -+#define TARGET_NR_renameat2 276 -+#define TARGET_NR_seccomp 277 -+#define TARGET_NR_getrandom 278 -+#define TARGET_NR_memfd_create 279 -+#define TARGET_NR_bpf 280 -+#define TARGET_NR_execveat 281 -+#define TARGET_NR_userfaultfd 282 -+#define TARGET_NR_membarrier 283 -+#define TARGET_NR_mlock2 284 -+#define TARGET_NR_copy_file_range 285 -+#define TARGET_NR_preadv2 286 -+#define TARGET_NR_pwritev2 287 -+#define TARGET_NR_pkey_mprotect 288 -+#define TARGET_NR_pkey_alloc 289 -+#define TARGET_NR_pkey_free 290 -+#define TARGET_NR_statx 291 -+#define TARGET_NR_io_pgetevents 292 -+#define TARGET_NR_rseq 293 -+#define TARGET_NR_kexec_file_load 294 -+ -+#define TARGET_NR_syscalls (TARGET_NR_kexec_file_load + 1) -+ -+#endif -diff --git a/linux-user/loongarch64/target_cpu.h b/linux-user/loongarch64/target_cpu.h -new file mode 100644 -index 000000000..0f6845737 ---- /dev/null -+++ b/linux-user/loongarch64/target_cpu.h -@@ -0,0 +1,45 @@ -+/* -+ * MIPS specific CPU ABI and functions for linux-user -+ * -+ * Copyright (c) 2004-2005 Jocelyn Mayer -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+#ifndef LOONGARCH_TARGET_CPU_H -+#define LOONGARCH_TARGET_CPU_H -+ -+static inline void cpu_clone_regs_child(CPULOONGARCHState *env, target_ulong newsp, -+ unsigned flags) -+{ -+ if (newsp) { -+ env->active_tc.gpr[3] = newsp; -+ } -+ env->active_tc.gpr[7] = 0; -+ env->active_tc.gpr[4] = 0; -+} -+ -+static inline void cpu_clone_regs_parent(CPULOONGARCHState *env, unsigned flags) -+{ -+} -+ -+static inline void cpu_set_tls(CPULOONGARCHState *env, target_ulong newtls) -+{ -+ env->active_tc.gpr[2] = newtls; -+} -+ -+static inline abi_ulong get_sp_from_cpustate(CPULOONGARCHState *state) -+{ -+ return state->active_tc.gpr[3]; -+} -+#endif -diff --git a/linux-user/loongarch64/target_elf.h b/linux-user/loongarch64/target_elf.h -new file mode 100644 -index 000000000..6c153d12c ---- /dev/null -+++ b/linux-user/loongarch64/target_elf.h -@@ -0,0 +1,14 @@ -+/* -+ * 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 LOONGARCH_TARGET_ELF_H -+#define LOONGARCH_TARGET_ELF_H -+static inline const char *cpu_get_model(uint32_t eflags) -+{ -+ return "Loongson-3A5000"; -+} -+#endif -diff --git a/linux-user/loongarch64/target_fcntl.h b/linux-user/loongarch64/target_fcntl.h -new file mode 100644 -index 000000000..a3d7b4606 ---- /dev/null -+++ b/linux-user/loongarch64/target_fcntl.h -@@ -0,0 +1,13 @@ -+/* -+ * 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 LOONGARCH_TARGET_FCNTL_H -+#define LOONGARCH_TARGET_FCNTL_H -+ -+#include "../generic/fcntl.h" -+ -+#endif /* LOONGARCH_TARGET_FCNTL_H */ -diff --git a/linux-user/loongarch64/target_signal.h b/linux-user/loongarch64/target_signal.h -new file mode 100644 -index 000000000..e418c8e8f ---- /dev/null -+++ b/linux-user/loongarch64/target_signal.h -@@ -0,0 +1,23 @@ -+#ifndef LOONGARCH_TARGET_SIGNAL_H -+#define LOONGARCH_TARGET_SIGNAL_H -+ -+/* this struct defines a stack used during syscall handling */ -+ -+typedef struct target_sigaltstack { -+ abi_long ss_sp; -+ abi_int ss_flags; -+ abi_ulong ss_size; -+} target_stack_t; -+ -+/* -+ * sigaltstack controls -+ */ -+#define TARGET_SS_ONSTACK 1 -+#define TARGET_SS_DISABLE 2 -+ -+#define TARGET_MINSIGSTKSZ 2048 -+#define TARGET_SIGSTKSZ 8192 -+ -+#include "../generic/signal.h" -+ -+#endif /* LOONGARCH_TARGET_SIGNAL_H */ -diff --git a/linux-user/loongarch64/target_structs.h b/linux-user/loongarch64/target_structs.h -new file mode 100644 -index 000000000..280acd097 ---- /dev/null -+++ b/linux-user/loongarch64/target_structs.h -@@ -0,0 +1,62 @@ -+/* -+ * LOONGARCH specific structures for linux-user -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+#ifndef LOONGARCH_TARGET_STRUCTS_H -+#define LOONGARCH_TARGET_STRUCTS_H -+ -+struct target_ipc_perm { -+ abi_int __key; /* Key. */ -+ abi_uint uid; /* Owner's user ID. */ -+ abi_uint gid; /* Owner's group ID. */ -+ abi_uint cuid; /* Creator's user ID. */ -+ abi_uint cgid; /* Creator's group ID. */ -+ abi_uint mode; /* Read/write permission. */ -+ abi_ushort __seq; /* Sequence number. */ -+ abi_ushort __pad1; -+ abi_ulong __unused1; -+ abi_ulong __unused2; -+}; -+ -+struct target_shmid_ds { -+ struct target_ipc_perm shm_perm; /* operation permission struct */ -+ abi_long shm_segsz; /* size of segment in bytes */ -+ abi_ulong shm_atime; /* time of last shmat() */ -+ abi_ulong shm_dtime; /* time of last shmdt() */ -+ abi_ulong shm_ctime; /* time of last change by shmctl() */ -+ abi_int shm_cpid; /* pid of creator */ -+ abi_int shm_lpid; /* pid of last shmop */ -+ abi_ulong shm_nattch; /* number of current attaches */ -+ abi_ulong __unused1; -+ abi_ulong __unused2; -+}; -+ -+#define TARGET_SEMID64_DS -+ -+/* -+ * The semid64_ds structure for the MIPS architecture. -+ * Note extra padding because this structure is passed back and forth -+ * between kernel and user space. -+ */ -+struct target_semid64_ds { -+ struct target_ipc_perm sem_perm; -+ abi_ulong sem_otime; -+ abi_ulong sem_ctime; -+ abi_ulong sem_nsems; -+ abi_ulong __unused1; -+ abi_ulong __unused2; -+}; -+ -+#endif -diff --git a/linux-user/loongarch64/target_syscall.h b/linux-user/loongarch64/target_syscall.h -new file mode 100644 -index 000000000..cb77f0708 ---- /dev/null -+++ b/linux-user/loongarch64/target_syscall.h -@@ -0,0 +1,44 @@ -+#ifndef LOONGARCH_TARGET_SYSCALL_H -+#define LOONGARCH_TARGET_SYSCALL_H -+ -+/* this struct defines the way the registers are stored on the -+ stack during a system call. */ -+ -+struct target_pt_regs { -+ /* Saved main processor registers. */ -+ target_ulong regs[32]; -+ -+ /* Saved special registers. */ -+ /* Saved special registers. */ -+ target_ulong csr_crmd; -+ target_ulong csr_prmd; -+ target_ulong csr_euen; -+ target_ulong csr_ecfg; -+ target_ulong csr_estat; -+ target_ulong csr_era; -+ target_ulong csr_badvaddr; -+ target_ulong orig_a0; -+ target_ulong __last[0]; -+}; -+ -+#define UNAME_MACHINE "loongarch" -+#define UNAME_MINIMUM_RELEASE "2.6.32" -+ -+#define TARGET_CLONE_BACKWARDS -+#define TARGET_MINSIGSTKSZ 2048 -+#define TARGET_MLOCKALL_MCL_CURRENT 1 -+#define TARGET_MLOCKALL_MCL_FUTURE 2 -+ -+#define TARGET_FORCE_SHMLBA -+ -+static inline abi_ulong target_shmlba(CPULOONGARCHState *env) -+{ -+ return 0x40000; -+} -+ -+#define TARGET_PR_SET_FP_MODE 45 -+#define TARGET_PR_GET_FP_MODE 46 -+#define TARGET_PR_FP_MODE_FR (1 << 0) -+#define TARGET_PR_FP_MODE_FRE (1 << 1) -+ -+#endif /* LOONGARCH_TARGET_SYSCALL_H */ -diff --git a/linux-user/loongarch64/termbits.h b/linux-user/loongarch64/termbits.h -new file mode 100644 -index 000000000..6c613a197 ---- /dev/null -+++ b/linux-user/loongarch64/termbits.h -@@ -0,0 +1,224 @@ -+#ifndef LINUX_USER_LOONGARCH_TERMBITS_H -+#define LINUX_USER_LOONGARCH_TERMBITS_H -+ -+#define TARGET_NCCS 19 -+ -+struct target_termios { -+ unsigned int c_iflag; /* input mode flags */ -+ unsigned int c_oflag; /* output mode flags */ -+ unsigned int c_cflag; /* control mode flags */ -+ unsigned int c_lflag; /* local mode flags */ -+ unsigned char c_line; /* line discipline */ -+ unsigned char c_cc[TARGET_NCCS]; /* control characters */ -+}; -+ -+/* c_iflag bits */ -+#define TARGET_IGNBRK 0000001 -+#define TARGET_BRKINT 0000002 -+#define TARGET_IGNPAR 0000004 -+#define TARGET_PARMRK 0000010 -+#define TARGET_INPCK 0000020 -+#define TARGET_ISTRIP 0000040 -+#define TARGET_INLCR 0000100 -+#define TARGET_IGNCR 0000200 -+#define TARGET_ICRNL 0000400 -+#define TARGET_IUCLC 0001000 -+#define TARGET_IXON 0002000 -+#define TARGET_IXANY 0004000 -+#define TARGET_IXOFF 0010000 -+#define TARGET_IMAXBEL 0020000 -+#define TARGET_IUTF8 0040000 -+ -+/* c_oflag bits */ -+#define TARGET_OPOST 0000001 -+#define TARGET_OLCUC 0000002 -+#define TARGET_ONLCR 0000004 -+#define TARGET_OCRNL 0000010 -+#define TARGET_ONOCR 0000020 -+#define TARGET_ONLRET 0000040 -+#define TARGET_OFILL 0000100 -+#define TARGET_OFDEL 0000200 -+#define TARGET_NLDLY 0000400 -+#define TARGET_NL0 0000000 -+#define TARGET_NL1 0000400 -+#define TARGET_CRDLY 0003000 -+#define TARGET_CR0 0000000 -+#define TARGET_CR1 0001000 -+#define TARGET_CR2 0002000 -+#define TARGET_CR3 0003000 -+#define TARGET_TABDLY 0014000 -+#define TARGET_TAB0 0000000 -+#define TARGET_TAB1 0004000 -+#define TARGET_TAB2 0010000 -+#define TARGET_TAB3 0014000 -+#define TARGET_XTABS 0014000 -+#define TARGET_BSDLY 0020000 -+#define TARGET_BS0 0000000 -+#define TARGET_BS1 0020000 -+#define TARGET_VTDLY 0040000 -+#define TARGET_VT0 0000000 -+#define TARGET_VT1 0040000 -+#define TARGET_FFDLY 0100000 -+#define TARGET_FF0 0000000 -+#define TARGET_FF1 0100000 -+ -+/* c_cflag bit meaning */ -+#define TARGET_CBAUD 0010017 -+#define TARGET_B0 0000000 /* hang up */ -+#define TARGET_B50 0000001 -+#define TARGET_B75 0000002 -+#define TARGET_B110 0000003 -+#define TARGET_B134 0000004 -+#define TARGET_B150 0000005 -+#define TARGET_B200 0000006 -+#define TARGET_B300 0000007 -+#define TARGET_B600 0000010 -+#define TARGET_B1200 0000011 -+#define TARGET_B1800 0000012 -+#define TARGET_B2400 0000013 -+#define TARGET_B4800 0000014 -+#define TARGET_B9600 0000015 -+#define TARGET_B19200 0000016 -+#define TARGET_B38400 0000017 -+#define TARGET_EXTA B19200 -+#define TARGET_EXTB B38400 -+#define TARGET_CSIZE 0000060 -+#define TARGET_CS5 0000000 -+#define TARGET_CS6 0000020 -+#define TARGET_CS7 0000040 -+#define TARGET_CS8 0000060 -+#define TARGET_CSTOPB 0000100 -+#define TARGET_CREAD 0000200 -+#define TARGET_PARENB 0000400 -+#define TARGET_PARODD 0001000 -+#define TARGET_HUPCL 0002000 -+#define TARGET_CLOCAL 0004000 -+#define TARGET_CBAUDEX 0010000 -+#define TARGET_B57600 0010001 -+#define TARGET_B115200 0010002 -+#define TARGET_B230400 0010003 -+#define TARGET_B460800 0010004 -+#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */ -+#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ -+#define TARGET_CRTSCTS 020000000000 /* flow control */ -+ -+/* c_lflag bits */ -+#define TARGET_ISIG 0000001 -+#define TARGET_ICANON 0000002 -+#define TARGET_XCASE 0000004 -+#define TARGET_ECHO 0000010 -+#define TARGET_ECHOE 0000020 -+#define TARGET_ECHOK 0000040 -+#define TARGET_ECHONL 0000100 -+#define TARGET_NOFLSH 0000200 -+#define TARGET_TOSTOP 0000400 -+#define TARGET_ECHOCTL 0001000 -+#define TARGET_ECHOPRT 0002000 -+#define TARGET_ECHOKE 0004000 -+#define TARGET_FLUSHO 0010000 -+#define TARGET_PENDIN 0040000 -+#define TARGET_IEXTEN 0100000 -+ -+/* c_cc character offsets */ -+#define TARGET_VINTR 0 -+#define TARGET_VQUIT 1 -+#define TARGET_VERASE 2 -+#define TARGET_VKILL 3 -+#define TARGET_VEOF 4 -+#define TARGET_VTIME 5 -+#define TARGET_VMIN 6 -+#define TARGET_VSWTC 7 -+#define TARGET_VSTART 8 -+#define TARGET_VSTOP 9 -+#define TARGET_VSUSP 10 -+#define TARGET_VEOL 11 -+#define TARGET_VREPRINT 12 -+#define TARGET_VDISCARD 13 -+#define TARGET_VWERASE 14 -+#define TARGET_VLNEXT 15 -+#define TARGET_VEOL2 16 -+ -+/* ioctls */ -+ -+#define TARGET_TCGETS 0x5401 -+#define TARGET_TCSETS 0x5402 -+#define TARGET_TCSETSW 0x5403 -+#define TARGET_TCSETSF 0x5404 -+#define TARGET_TCGETA 0x5405 -+#define TARGET_TCSETA 0x5406 -+#define TARGET_TCSETAW 0x5407 -+#define TARGET_TCSETAF 0x5408 -+#define TARGET_TCSBRK 0x5409 -+#define TARGET_TCXONC 0x540A -+#define TARGET_TCFLSH 0x540B -+ -+#define TARGET_TIOCEXCL 0x540C -+#define TARGET_TIOCNXCL 0x540D -+#define TARGET_TIOCSCTTY 0x540E -+#define TARGET_TIOCGPGRP 0x540F -+#define TARGET_TIOCSPGRP 0x5410 -+#define TARGET_TIOCOUTQ 0x5411 -+#define TARGET_TIOCSTI 0x5412 -+#define TARGET_TIOCGWINSZ 0x5413 -+#define TARGET_TIOCSWINSZ 0x5414 -+#define TARGET_TIOCMGET 0x5415 -+#define TARGET_TIOCMBIS 0x5416 -+#define TARGET_TIOCMBIC 0x5417 -+#define TARGET_TIOCMSET 0x5418 -+#define TARGET_TIOCGSOFTCAR 0x5419 -+#define TARGET_TIOCSSOFTCAR 0x541A -+#define TARGET_FIONREAD 0x541B -+#define TARGET_TIOCINQ TARGET_FIONREAD -+#define TARGET_TIOCLINUX 0x541C -+#define TARGET_TIOCCONS 0x541D -+#define TARGET_TIOCGSERIAL 0x541E -+#define TARGET_TIOCSSERIAL 0x541F -+#define TARGET_TIOCPKT 0x5420 -+#define TARGET_FIONBIO 0x5421 -+#define TARGET_TIOCNOTTY 0x5422 -+#define TARGET_TIOCSETD 0x5423 -+#define TARGET_TIOCGETD 0x5424 -+#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -+#define TARGET_TIOCTTYGSTRUCT 0x5426 /* For debugging only */ -+#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ -+#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ -+#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */ -+#define TARGET_TIOCGPTN TARGET_IOR('T', 0x30, unsigned int) -+ /* Get Pty Number (of pty-mux device) */ -+#define TARGET_TIOCSPTLCK TARGET_IOW('T', 0x31, int) -+ /* Lock/unlock Pty */ -+#define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41) -+ /* Safely open the slave */ -+ -+#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */ -+#define TARGET_FIOCLEX 0x5451 -+#define TARGET_FIOASYNC 0x5452 -+#define TARGET_TIOCSERCONFIG 0x5453 -+#define TARGET_TIOCSERGWILD 0x5454 -+#define TARGET_TIOCSERSWILD 0x5455 -+#define TARGET_TIOCGLCKTRMIOS 0x5456 -+#define TARGET_TIOCSLCKTRMIOS 0x5457 -+#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */ -+#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */ -+#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */ -+#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */ -+ -+#define TARGET_TIOCMIWAIT 0x545C -+ /* wait for a change on serial input line(s) */ -+#define TARGET_TIOCGICOUNT 0x545D -+ /* read serial port inline interrupt counts */ -+#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ -+#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ -+ -+/* Used for packet mode */ -+#define TARGET_TIOCPKT_DATA 0 -+#define TARGET_TIOCPKT_FLUSHREAD 1 -+#define TARGET_TIOCPKT_FLUSHWRITE 2 -+#define TARGET_TIOCPKT_STOP 4 -+#define TARGET_TIOCPKT_START 8 -+#define TARGET_TIOCPKT_NOSTOP 16 -+#define TARGET_TIOCPKT_DOSTOP 32 -+ -+#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */ -+ -+#endif --- -2.43.5 - diff --git a/0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch b/0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch deleted file mode 100644 index 97cb7cc..0000000 --- a/0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 501e16b4b4cf5a302363c1ae55fb4fb8e68beb8d Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Tue, 24 Aug 2021 17:31:28 +0800 -Subject: [PATCH 5/8] anolis: cpu/i386: populate CPUID 0x8000_001F when CSV is - active - -On Hygon platform, bit 30 of EAX indicates whether -this feature is supported in hardware. - -When CSV is active, CPUID 0x8000_001F provides -information for it. - -Signed-off-by: Xin Jiang -Change-Id: Ifdd2a20f7cb4a079ba918928f012e5f64f7059e6 ---- - target/i386/cpu.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index aa9e636800..970d9bf184 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -27,6 +27,7 @@ - #include "sysemu/hvf.h" - #include "kvm/kvm_i386.h" - #include "sev.h" -+#include "csv.h" - #include "qapi/error.h" - #include "qapi/qapi-visit-machine.h" - #include "qapi/qmp/qerror.h" -@@ -5769,6 +5770,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - if (sev_enabled()) { - *eax = 0x2; - *eax |= sev_es_enabled() ? 0x8 : 0; -+ *eax |= csv_enabled() ? 0x40000000 : 0; /* bit 30 for CSV */ - *ebx = sev_get_cbit_position() & 0x3f; /* EBX[5:0] */ - *ebx |= (sev_get_reduced_phys_bits() & 0x3f) << 6; /* EBX[11:6] */ - } --- -2.17.1 - diff --git a/0006-Add-disas-gdb.patch b/0006-Add-disas-gdb.patch deleted file mode 100644 index 97e9a6d..0000000 --- a/0006-Add-disas-gdb.patch +++ /dev/null @@ -1,3183 +0,0 @@ -From dbf0724c5c9e7928f0007e6a5e0009cabba90457 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Fri, 19 Aug 2022 23:51:12 -0400 -Subject: [PATCH 06/28] Add disas gdb. - -Change-Id: If41c0fc8aa128796e342319c7673fab3ccbf3913 -Signed-off-by: lixianglai ---- - .../devices/loongarch64-softmmu/default.mak | 154 + - configs/targets/loongarch64-softmmu.mak | 4 + - disas/loongarch.c | 2748 +++++++++++++++++ - disas/meson.build | 1 + - gdb-xml/loongarch-base32.xml | 43 + - gdb-xml/loongarch-base64.xml | 43 + - gdb-xml/loongarch-fpu32.xml | 52 + - gdb-xml/loongarch-fpu64.xml | 57 + - 8 files changed, 3102 insertions(+) - create mode 100644 configs/devices/loongarch64-softmmu/default.mak - create mode 100644 configs/targets/loongarch64-softmmu.mak - create mode 100644 disas/loongarch.c - create mode 100644 gdb-xml/loongarch-base32.xml - create mode 100644 gdb-xml/loongarch-base64.xml - create mode 100644 gdb-xml/loongarch-fpu32.xml - create mode 100644 gdb-xml/loongarch-fpu64.xml - -diff --git a/configs/devices/loongarch64-softmmu/default.mak b/configs/devices/loongarch64-softmmu/default.mak -new file mode 100644 -index 000000000..fcb7e45dd ---- /dev/null -+++ b/configs/devices/loongarch64-softmmu/default.mak -@@ -0,0 +1,154 @@ -+# Default configuration for loongarch-softmmu -+ -+CONFIG_PCI=y -+CONFIG_ACPI_PCI=y -+# For now, CONFIG_IDE_CORE requires ISA, so we enable it here -+CONFIG_ISA_BUS=y -+CONFIG_VIRTIO_PCI=y -+ -+CONFIG_VGA_PCI=y -+CONFIG_ACPI_SMBUS=y -+#CONFIG_VHOST_USER_SCSI=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) -+CONFIG_VHOST_USER_SCSI=y -+#CONFIG_VHOST_USER_BLK=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) -+CONFIG_VHOST_USER_BLK=y -+CONFIG_VIRTIO=y -+CONFIG_VIRTIO_BALLOON=y -+CONFIG_VIRTIO_BLK=y -+CONFIG_VIRTIO_CRYPTO=y -+CONFIG_VIRTIO_GPU=y -+CONFIG_VIRTIO_INPUT=y -+CONFIG_VIRTIO_NET=y -+CONFIG_VIRTIO_RNG=y -+CONFIG_SCSI=y -+CONFIG_VIRTIO_SCSI=y -+CONFIG_VIRTIO_SERIAL=y -+ -+CONFIG_USB_UHCI=y -+CONFIG_USB_OHCI=y -+CONFIG_USB_OHCI_PCI=y -+CONFIG_USB_XHCI=y -+CONFIG_USB_XHCI_NEC=y -+CONFIG_NE2000_PCI=y -+CONFIG_EEPRO100_PCI=y -+CONFIG_PCNET_PCI=y -+CONFIG_PCNET_COMMON=y -+CONFIG_AC97=y -+CONFIG_HDA=y -+CONFIG_ES1370=y -+CONFIG_SCSI=y -+CONFIG_LSI_SCSI_PCI=y -+CONFIG_VMW_PVSCSI_SCSI_PCI=y -+CONFIG_MEGASAS_SCSI_PCI=y -+CONFIG_MPTSAS_SCSI_PCI=y -+CONFIG_RTL8139_PCI=y -+CONFIG_E1000_PCI=y -+CONFIG_IDE_CORE=y -+CONFIG_IDE_QDEV=y -+CONFIG_IDE_PCI=y -+CONFIG_AHCI=y -+CONFIG_AHCI_ICH9=y -+CONFIG_ESP=y -+CONFIG_ESP_PCI=y -+CONFIG_SERIAL=y -+CONFIG_SERIAL_ISA=y -+CONFIG_SERIAL_PCI=y -+CONFIG_CAN_BUS=y -+CONFIG_CAN_SJA1000=y -+CONFIG_CAN_PCI=y -+CONFIG_USB_UHCI=y -+CONFIG_USB_OHCI=y -+CONFIG_USB_XHCI=y -+CONFIG_USB_XHCI_NEC=y -+CONFIG_NE2000_PCI=y -+CONFIG_EEPRO100_PCI=y -+CONFIG_PCNET_PCI=y -+CONFIG_PCNET_COMMON=y -+CONFIG_AC97=y -+CONFIG_HDA=y -+CONFIG_ES1370=y -+CONFIG_SCSI=y -+CONFIG_LSI_SCSI_PCI=y -+CONFIG_VMW_PVSCSI_SCSI_PCI=y -+CONFIG_MEGASAS_SCSI_PCI=y -+CONFIG_MPTSAS_SCSI_PCI=y -+CONFIG_RTL8139_PCI=y -+CONFIG_E1000_PCI=y -+CONFIG_IDE_CORE=y -+CONFIG_IDE_QDEV=y -+CONFIG_IDE_PCI=y -+CONFIG_AHCI=y -+CONFIG_ESP=y -+CONFIG_ESP_PCI=y -+CONFIG_SERIAL=y -+CONFIG_SERIAL_ISA=y -+CONFIG_SERIAL_PCI=y -+CONFIG_CAN_BUS=y -+CONFIG_CAN_SJA1000=y -+CONFIG_CAN_PCI=y -+ -+CONFIG_SPICE=y -+CONFIG_QXL=y -+CONFIG_ESP=y -+CONFIG_SCSI=y -+CONFIG_VGA_ISA=y -+CONFIG_VGA_ISA_MM=y -+CONFIG_VGA_CIRRUS=y -+CONFIG_VMWARE_VGA=y -+CONFIG_VIRTIO_VGA=y -+CONFIG_SERIAL=y -+CONFIG_SERIAL_ISA=y -+CONFIG_PARALLEL=y -+CONFIG_I8254=y -+CONFIG_PCSPK=y -+CONFIG_PCKBD=y -+CONFIG_FDC=y -+CONFIG_ACPI=y -+CONFIG_ACPI_MEMORY_HOTPLUG=y -+CONFIG_ACPI_NVDIMM=y -+CONFIG_ACPI_CPU_HOTPLUG=y -+CONFIG_APM=y -+CONFIG_I8257=y -+CONFIG_PIIX4=y -+CONFIG_IDE_ISA=y -+CONFIG_IDE_PIIX=y -+#CONFIG_NE2000_ISA=y -+CONFIG_MIPSNET=y -+CONFIG_PFLASH_CFI01=y -+CONFIG_I8259=y -+CONFIG_MC146818RTC=y -+CONFIG_ISA_TESTDEV=y -+CONFIG_EMPTY_SLOT=y -+CONFIG_I2C=y -+CONFIG_DIMM=y -+CONFIG_MEM_DEVICE=y -+ -+# Arch Specified CONFIG defines -+CONFIG_IDE_VIA=y -+CONFIG_VT82C686=y -+CONFIG_RC4030=y -+CONFIG_DP8393X=y -+CONFIG_DS1225Y=y -+CONFIG_FITLOADER=y -+CONFIG_SMBIOS=y -+ -+CONFIG_PCIE_PORT=y -+CONFIG_I82801B11=y -+CONFIG_XIO3130=y -+CONFIG_PCI_EXPRESS=y -+CONFIG_MSI_NONBROKEN=y -+CONFIG_IOH3420=y -+CONFIG_SD=y -+CONFIG_SDHCI=y -+CONFIG_VIRTFS=y -+CONFIG_VIRTIO_9P=y -+CONFIG_USB_EHCI=y -+CONFIG_USB_EHCI_PCI=y -+CONFIG_USB_EHCI_SYSBUS=y -+CONFIG_USB_STORAGE_BOT=y -+CONFIG_TPM_EMULATOR=y -+CONFIG_TPM_TIS=y -+CONFIG_PLATFORM_BUS=y -+CONFIG_TPM_TIS_SYSBUS=y -+CONFIG_ACPI_LOONGARCH=y -+CONFIG_LS7A_RTC=y -diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak -new file mode 100644 -index 000000000..dc5ab3966 ---- /dev/null -+++ b/configs/targets/loongarch64-softmmu.mak -@@ -0,0 +1,4 @@ -+TARGET_ARCH=loongarch64 -+TARGET_SUPPORTS_MTTCG=y -+TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu64.xml -+ -diff --git a/disas/loongarch.c b/disas/loongarch.c -new file mode 100644 -index 000000000..14dd131e2 ---- /dev/null -+++ b/disas/loongarch.c -@@ -0,0 +1,2748 @@ -+/* -+ * QEMU Loongarch Disassembler -+ * -+ * Copyright (c) 2020-2021. -+ * Author: Song Gao, gaosong@loongson.cn -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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 . -+ */ -+ -+#include "qemu/osdep.h" -+#include "disas/dis-asm.h" -+ -+#define INSNLEN 4 -+ -+/* types */ -+ -+typedef uint16_t la_opcode; -+ -+/* enums */ -+ -+typedef enum { -+ la_op_illegal = 0, -+ la_op_gr2scr = 1, -+ la_op_scr2gr = 2, -+ la_op_clo_w = 3, -+ la_op_clz_w = 4, -+ la_op_cto_w = 5, -+ la_op_ctz_w = 6, -+ la_op_clo_d = 7, -+ la_op_clz_d = 8, -+ la_op_cto_d = 9, -+ la_op_ctz_d = 10, -+ la_op_revb_2h = 11, -+ la_op_revb_4h = 12, -+ la_op_revb_2w = 13, -+ la_op_revb_d = 14, -+ la_op_revh_2w = 15, -+ la_op_revh_d = 16, -+ la_op_bitrev_4b = 17, -+ la_op_bitrev_8b = 18, -+ la_op_bitrev_w = 19, -+ la_op_bitrev_d = 20, -+ la_op_ext_w_h = 21, -+ la_op_ext_w_b = 22, -+ la_op_rdtime_d = 23, -+ la_op_cpucfg = 24, -+ la_op_asrtle_d = 25, -+ la_op_asrtgt_d = 26, -+ la_op_alsl_w = 27, -+ la_op_alsl_wu = 28, -+ la_op_bytepick_w = 29, -+ la_op_bytepick_d = 30, -+ la_op_add_w = 31, -+ la_op_add_d = 32, -+ la_op_sub_w = 33, -+ la_op_sub_d = 34, -+ la_op_slt = 35, -+ la_op_sltu = 36, -+ la_op_maskeqz = 37, -+ la_op_masknez = 38, -+ la_op_nor = 39, -+ la_op_and = 40, -+ la_op_or = 41, -+ la_op_xor = 42, -+ la_op_orn = 43, -+ la_op_andn = 44, -+ la_op_sll_w = 45, -+ la_op_srl_w = 46, -+ la_op_sra_w = 47, -+ la_op_sll_d = 48, -+ la_op_srl_d = 49, -+ la_op_sra_d = 50, -+ la_op_rotr_w = 51, -+ la_op_rotr_d = 52, -+ la_op_mul_w = 53, -+ la_op_mulh_w = 54, -+ la_op_mulh_wu = 55, -+ la_op_mul_d = 56, -+ la_op_mulh_d = 57, -+ la_op_mulh_du = 58, -+ la_op_mulw_d_w = 59, -+ la_op_mulw_d_wu = 60, -+ la_op_div_w = 61, -+ la_op_mod_w = 62, -+ la_op_div_wu = 63, -+ la_op_mod_wu = 64, -+ la_op_div_d = 65, -+ la_op_mod_d = 66, -+ la_op_div_du = 67, -+ la_op_mod_du = 68, -+ la_op_crc_w_b_w = 69, -+ la_op_crc_w_h_w = 70, -+ la_op_crc_w_w_w = 71, -+ la_op_crc_w_d_w = 72, -+ la_op_crcc_w_b_w = 73, -+ la_op_crcc_w_h_w = 74, -+ la_op_crcc_w_w_w = 75, -+ la_op_crcc_w_d_w = 76, -+ la_op_break = 77, -+ la_op_dbcl = 78, -+ la_op_syscall = 79, -+ la_op_alsl_d = 80, -+ la_op_slli_w = 81, -+ la_op_slli_d = 82, -+ la_op_srli_w = 83, -+ la_op_srli_d = 84, -+ la_op_srai_w = 85, -+ la_op_srai_d = 86, -+ la_op_rotri_w = 87, -+ la_op_rotri_d = 88, -+ la_op_bstrins_w = 89, -+ la_op_bstrpick_w = 90, -+ la_op_bstrins_d = 91, -+ la_op_bstrpick_d = 92, -+ la_op_fadd_s = 93, -+ la_op_fadd_d = 94, -+ la_op_fsub_s = 95, -+ la_op_fsub_d = 96, -+ la_op_fmul_s = 97, -+ la_op_fmul_d = 98, -+ la_op_fdiv_s = 99, -+ la_op_fdiv_d = 100, -+ la_op_fmax_s = 101, -+ la_op_fmax_d = 102, -+ la_op_fmin_s = 103, -+ la_op_fmin_d = 104, -+ la_op_fmaxa_s = 105, -+ la_op_fmaxa_d = 106, -+ la_op_fmina_s = 107, -+ la_op_fmina_d = 108, -+ la_op_fscaleb_s = 109, -+ la_op_fscaleb_d = 110, -+ la_op_fcopysign_s = 111, -+ la_op_fcopysign_d = 112, -+ la_op_fabs_s = 113, -+ la_op_fabs_d = 114, -+ la_op_fneg_s = 115, -+ la_op_fneg_d = 116, -+ la_op_flogb_s = 117, -+ la_op_flogb_d = 118, -+ la_op_fclass_s = 119, -+ la_op_fclass_d = 120, -+ la_op_fsqrt_s = 121, -+ la_op_fsqrt_d = 122, -+ la_op_frecip_s = 123, -+ la_op_frecip_d = 124, -+ la_op_frsqrt_s = 125, -+ la_op_frsqrt_d = 126, -+ la_op_fmov_s = 127, -+ la_op_fmov_d = 128, -+ la_op_movgr2fr_w = 129, -+ la_op_movgr2fr_d = 130, -+ la_op_movgr2frh_w = 131, -+ la_op_movfr2gr_s = 132, -+ la_op_movfr2gr_d = 133, -+ la_op_movfrh2gr_s = 134, -+ la_op_movgr2fcsr = 135, -+ la_op_movfcsr2gr = 136, -+ la_op_movfr2cf = 137, -+ la_op_movcf2fr = 138, -+ la_op_movgr2cf = 139, -+ la_op_movcf2gr = 140, -+ la_op_fcvt_s_d = 141, -+ la_op_fcvt_d_s = 142, -+ -+ la_op_ftintrm_w_s = 143, -+ la_op_ftintrm_w_d = 144, -+ la_op_ftintrm_l_s = 145, -+ la_op_ftintrm_l_d = 146, -+ la_op_ftintrp_w_s = 147, -+ la_op_ftintrp_w_d = 148, -+ la_op_ftintrp_l_s = 149, -+ la_op_ftintrp_l_d = 150, -+ la_op_ftintrz_w_s = 151, -+ la_op_ftintrz_w_d = 152, -+ la_op_ftintrz_l_s = 153, -+ la_op_ftintrz_l_d = 154, -+ la_op_ftintrne_w_s = 155, -+ la_op_ftintrne_w_d = 156, -+ la_op_ftintrne_l_s = 157, -+ la_op_ftintrne_l_d = 158, -+ la_op_ftint_w_s = 159, -+ la_op_ftint_w_d = 160, -+ la_op_ftint_l_s = 161, -+ la_op_ftint_l_d = 162, -+ la_op_ffint_s_w = 163, -+ la_op_ffint_s_l = 164, -+ la_op_ffint_d_w = 165, -+ la_op_ffint_d_l = 166, -+ la_op_frint_s = 167, -+ la_op_frint_d = 168, -+ -+ la_op_slti = 169, -+ la_op_sltui = 170, -+ la_op_addi_w = 171, -+ la_op_addi_d = 172, -+ la_op_lu52i_d = 173, -+ la_op_addi = 174, -+ la_op_ori = 175, -+ la_op_xori = 176, -+ -+ la_op_csrxchg = 177, -+ la_op_cacop = 178, -+ la_op_lddir = 179, -+ la_op_ldpte = 180, -+ la_op_iocsrrd_b = 181, -+ la_op_iocsrrd_h = 182, -+ la_op_iocsrrd_w = 183, -+ la_op_iocsrrd_d = 184, -+ la_op_iocsrwr_b = 185, -+ la_op_iocsrwr_h = 186, -+ la_op_iocsrwr_w = 187, -+ la_op_iocsrwr_d = 188, -+ la_op_tlbclr = 189, -+ la_op_tlbflush = 190, -+ la_op_tlbsrch = 191, -+ la_op_tlbrd = 192, -+ la_op_tlbwr = 193, -+ la_op_tlbfill = 194, -+ la_op_ertn = 195, -+ la_op_idle = 196, -+ la_op_invtlb = 197, -+ -+ la_op_fmadd_s = 198, -+ la_op_fmadd_d = 199, -+ la_op_fmsub_s = 200, -+ la_op_fmsub_d = 201, -+ la_op_fnmadd_s = 202, -+ la_op_fnmadd_d = 203, -+ la_op_fnmsub_s = 204, -+ la_op_fnmsub_d = 205, -+ la_op_fcmp_cond_s = 206, -+ la_op_fcmp_cond_d = 207, -+ la_op_fsel = 208, -+ la_op_addu16i_d = 209, -+ la_op_lu12i_w = 210, -+ la_op_lu32i_d = 211, -+ la_op_pcaddi = 212, -+ la_op_pcalau12i = 213, -+ la_op_pcaddu12i = 214, -+ la_op_pcaddu18i = 215, -+ -+ la_op_ll_w = 216, -+ la_op_sc_w = 217, -+ la_op_ll_d = 218, -+ la_op_sc_d = 219, -+ la_op_ldptr_w = 220, -+ la_op_stptr_w = 221, -+ la_op_ldptr_d = 222, -+ la_op_stptr_d = 223, -+ la_op_ld_b = 224, -+ la_op_ld_h = 225, -+ la_op_ld_w = 226, -+ la_op_ld_d = 227, -+ la_op_st_b = 228, -+ la_op_st_h = 229, -+ la_op_st_w = 230, -+ la_op_st_d = 231, -+ la_op_ld_bu = 232, -+ la_op_ld_hu = 233, -+ la_op_ld_wu = 234, -+ la_op_preld = 235, -+ la_op_fld_s = 236, -+ la_op_fst_s = 237, -+ la_op_fld_d = 238, -+ la_op_fst_d = 239, -+ la_op_ldl_w = 240, -+ la_op_ldr_w = 241, -+ la_op_ldl_d = 242, -+ la_op_ldr_d = 243, -+ la_op_stl_d = 244, -+ la_op_str_d = 245, -+ la_op_ldx_b = 246, -+ la_op_ldx_h = 247, -+ la_op_ldx_w = 248, -+ la_op_ldx_d = 249, -+ la_op_stx_b = 250, -+ la_op_stx_h = 251, -+ la_op_stx_w = 252, -+ la_op_stx_d = 253, -+ la_op_ldx_bu = 254, -+ la_op_ldx_hu = 255, -+ la_op_ldx_wu = 256, -+ la_op_fldx_s = 257, -+ la_op_fldx_d = 258, -+ la_op_fstx_s = 259, -+ la_op_fstx_d = 260, -+ -+ la_op_amswap_w = 261, -+ la_op_amswap_d = 262, -+ la_op_amadd_w = 263, -+ la_op_amadd_d = 264, -+ la_op_amand_w = 265, -+ la_op_amand_d = 266, -+ la_op_amor_w = 267, -+ la_op_amor_d = 268, -+ la_op_amxor_w = 269, -+ la_op_amxor_d = 270, -+ la_op_ammax_w = 271, -+ la_op_ammax_d = 272, -+ la_op_ammin_w = 273, -+ la_op_ammin_d = 274, -+ la_op_ammax_wu = 275, -+ la_op_ammax_du = 276, -+ la_op_ammin_wu = 277, -+ la_op_ammin_du = 278, -+ la_op_amswap_db_w = 279, -+ la_op_amswap_db_d = 280, -+ la_op_amadd_db_w = 281, -+ la_op_amadd_db_d = 282, -+ la_op_amand_db_w = 283, -+ la_op_amand_db_d = 284, -+ la_op_amor_db_w = 285, -+ la_op_amor_db_d = 286, -+ la_op_amxor_db_w = 287, -+ la_op_amxor_db_d = 288, -+ la_op_ammax_db_w = 289, -+ la_op_ammax_db_d = 290, -+ la_op_ammin_db_w = 291, -+ la_op_ammin_db_d = 292, -+ la_op_ammax_db_wu = 293, -+ la_op_ammax_db_du = 294, -+ la_op_ammin_db_wu = 295, -+ la_op_ammin_db_du = 296, -+ la_op_dbar = 297, -+ la_op_ibar = 298, -+ la_op_fldgt_s = 299, -+ la_op_fldgt_d = 300, -+ la_op_fldle_s = 301, -+ la_op_fldle_d = 302, -+ la_op_fstgt_s = 303, -+ la_op_fstgt_d = 304, -+ ls_op_fstle_s = 305, -+ la_op_fstle_d = 306, -+ la_op_ldgt_b = 307, -+ la_op_ldgt_h = 308, -+ la_op_ldgt_w = 309, -+ la_op_ldgt_d = 310, -+ la_op_ldle_b = 311, -+ la_op_ldle_h = 312, -+ la_op_ldle_w = 313, -+ la_op_ldle_d = 314, -+ la_op_stgt_b = 315, -+ la_op_stgt_h = 316, -+ la_op_stgt_w = 317, -+ la_op_stgt_d = 318, -+ la_op_stle_b = 319, -+ la_op_stle_h = 320, -+ la_op_stle_w = 321, -+ la_op_stle_d = 322, -+ la_op_beqz = 323, -+ la_op_bnez = 324, -+ la_op_bceqz = 325, -+ la_op_bcnez = 326, -+ la_op_jirl = 327, -+ la_op_b = 328, -+ la_op_bl = 329, -+ la_op_beq = 330, -+ la_op_bne = 331, -+ la_op_blt = 332, -+ la_op_bge = 333, -+ la_op_bltu = 334, -+ la_op_bgeu = 335, -+ -+ /* vz insn */ -+ la_op_hvcl = 336, -+ -+} la_op; -+ -+typedef enum { -+ la_codec_illegal, -+ la_codec_empty, -+ la_codec_2r, -+ la_codec_2r_u5, -+ la_codec_2r_u6, -+ la_codec_2r_2bw, -+ la_codec_2r_2bd, -+ la_codec_3r, -+ la_codec_3r_rd0, -+ la_codec_3r_sa2, -+ la_codec_3r_sa3, -+ la_codec_4r, -+ la_codec_r_im20, -+ la_codec_2r_im16, -+ la_codec_2r_im14, -+ la_codec_2r_im12, -+ la_codec_im5_r_im12, -+ la_codec_2r_im8, -+ la_codec_r_sd, -+ la_codec_r_sj, -+ la_codec_r_cd, -+ la_codec_r_cj, -+ la_codec_r_seq, -+ la_codec_code, -+ la_codec_whint, -+ la_codec_invtlb, -+ la_codec_r_ofs21, -+ la_codec_cj_ofs21, -+ la_codec_ofs26, -+ la_codec_cond, -+ la_codec_sel, -+ -+} la_codec; -+ -+#define la_fmt_illegal "nte" -+#define la_fmt_empty "nt" -+#define la_fmt_sd_rj "ntA,1" -+#define la_fmt_rd_sj "nt0,B" -+#define la_fmt_rd_rj "nt0,1" -+#define la_fmt_rj_rk "nt1,2" -+#define la_fmt_rj_seq "nt1,x" -+#define la_fmt_rd_si20 "nt0,i(x)" -+#define la_fmt_rd_rj_ui5 "nt0,1,C" -+#define la_fmt_rd_rj_ui6 "nt0,1.C" -+#define la_fmt_rd_rj_level "nt0,1,x" -+#define la_fmt_rd_rj_msbw_lsbw "nt0,1,C,D" -+#define la_fmt_rd_rj_msbd_lsbd "nt0,1,C,D" -+#define la_fmt_rd_rj_si12 "nt0,1,i(x)" -+#define la_fmt_hint_rj_si12 "ntE,1,i(x)" -+#define la_fmt_rd_rj_csr "nt0,1,x" -+#define la_fmt_rd_rj_si14 "nt0,1,i(x)" -+#define la_fmt_rd_rj_si16 "nt0,1,i(x)" -+#define la_fmt_rd_rj_rk "nt0,1,2" -+#define la_fmt_fd_rj_rk "nt3,1,2" -+#define la_fmt_rd_rj_rk_sa2 "nt0,1,2,D" -+#define la_fmt_rd_rj_rk_sa3 "nt0,1,2,D" -+#define la_fmt_fd_rj "nt3,1" -+#define la_fmt_rd_fj "nt0,4" -+#define la_fmt_fd_fj "nt3,4" -+#define la_fmt_fd_fj_si12 "nt3,4,i(x)" -+#define la_fmt_fcsrd_rj "ntF,1" -+#define la_fmt_rd_fcsrs "nt0,G" -+#define la_fmt_cd_fj "ntH,4" -+#define la_fmt_fd_cj "nt3,I" -+#define la_fmt_fd_fj_fk "nt3,4,5" -+#define la_fmt_code "ntJ" -+#define la_fmt_whint "ntx" -+#define la_fmt_invtlb "ntx,1,2" /* op,rj,rk */ -+#define la_fmt_offs26 "nto(X)p" -+#define la_fmt_rj_offs21 "nt1,o(X)p" -+#define la_fmt_cj_offs21 "ntQ,o(X)p" -+#define la_fmt_rd_rj_offs16 "nt0,1,o(X)" -+#define la_fmt_rj_rd_offs16 "nt1,0,o(X)p" -+#define la_fmt_s_cd_fj_fk "K.stH,4,5" -+#define la_fmt_d_cd_fj_fk "K.dtH,4,5" -+#define la_fmt_fd_fj_fk_fa "nt3,4,5,6" -+#define la_fmt_fd_fj_fk_ca "nt3,4,5,L" -+#define la_fmt_cop_rj_si12 "ntM,1,i(x)" -+ -+/* structures */ -+ -+typedef struct { -+ uint32_t pc; -+ uint32_t insn; -+ int32_t imm; -+ int32_t imm2; -+ uint16_t op; -+ uint16_t code; -+ uint8_t codec; -+ uint8_t r1; -+ uint8_t r2; -+ uint8_t r3; -+ uint8_t r4; -+ uint8_t bit; -+} la_decode; -+ -+typedef struct { -+ const char * const name; -+ const la_codec codec; -+ const char * const format; -+} la_opcode_data; -+ -+/* reg names */ -+ -+const char * const loongarch_r_normal_name[32] = { -+ "$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", "$r27", "$r28", "$r29", "$r30", "$r31", -+}; -+ -+const char * const loongarch_f_normal_name[32] = { -+ "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", -+ "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", -+ "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", -+ "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", -+}; -+ -+const char * const loongarch_cr_normal_name[4] = { -+ "$scr0", "$scr1", "$scr2", "$scr3", -+}; -+ -+const char * const loongarch_c_normal_name[8] = { -+ "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7", -+}; -+ -+/* instruction data */ -+ -+const la_opcode_data opcode_data[] = { -+ { "illegal", la_codec_illegal, la_fmt_illegal }, -+ { "gr2scr", la_codec_r_sd, la_fmt_sd_rj }, -+ { "scr2gr", la_codec_r_sj, la_fmt_rd_sj }, -+ { "clo.w", la_codec_2r, la_fmt_rd_rj }, -+ { "clz.w", la_codec_2r, la_fmt_rd_rj }, -+ { "cto.w", la_codec_2r, la_fmt_rd_rj }, -+ { "ctz.w", la_codec_2r, la_fmt_rd_rj }, -+ { "clo.d", la_codec_2r, la_fmt_rd_rj }, -+ { "clz.d", la_codec_2r, la_fmt_rd_rj }, -+ { "cto.d", la_codec_2r, la_fmt_rd_rj }, -+ { "ctz_d", la_codec_2r, la_fmt_rd_rj }, -+ { "revb.2h", la_codec_2r, la_fmt_rd_rj }, -+ { "revb.4h", la_codec_2r, la_fmt_rd_rj }, -+ { "revb.2w", la_codec_2r, la_fmt_rd_rj }, -+ { "revb.d", la_codec_2r, la_fmt_rd_rj }, -+ { "revh.2w", la_codec_2r, la_fmt_rd_rj }, -+ { "revh.d", la_codec_2r, la_fmt_rd_rj }, -+ { "bitrev.4b", la_codec_2r, la_fmt_rd_rj }, -+ { "bitrev.8b", la_codec_2r, la_fmt_rd_rj }, -+ { "bitrev.w", la_codec_2r, la_fmt_rd_rj }, -+ { "bitrev.d", la_codec_2r, la_fmt_rd_rj }, -+ { "ext.w.h", la_codec_2r, la_fmt_rd_rj }, -+ { "ext.w.b", la_codec_2r, la_fmt_rd_rj }, -+ { "rdtime.d", la_codec_2r, la_fmt_rd_rj }, -+ { "cpucfg", la_codec_2r, la_fmt_rd_rj }, -+ { "asrtle.d", la_codec_3r_rd0, la_fmt_rj_rk }, -+ { "asrtgt.d", la_codec_3r_rd0, la_fmt_rj_rk }, -+ { "alsl.w", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, -+ { "alsl.wu", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, -+ { "bytepick.w", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, -+ { "bytepick.d", la_codec_3r_sa3, la_fmt_rd_rj_rk_sa3 }, -+ { "add.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "add.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sub.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sub.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "slt", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sltu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "maskeqz", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "masknez", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "nor", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "and", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "or", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "xor", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "orn", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "andn", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sll.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "srl.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sra.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sll.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "srl.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sra.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "rotr.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "rotr.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mul.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mulh.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mulh.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mul.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mulh.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mulh.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mulw.d.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mulw.d.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "div.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mod.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "div.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mod.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "div.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mod.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "div.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mod.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crc.w.b.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crc.w.h.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crc.w.w.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crc.w.d.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crcc.w.b.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crcc.w.h.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crcc.w.w.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crcc.w.d.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "break", la_codec_code, la_fmt_code }, -+ { "dbcl", la_codec_code, la_fmt_code }, -+ { "syscall", la_codec_code, la_fmt_code }, -+ { "alsl.d", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, -+ { "slli.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, -+ { "slli.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, -+ { "srli.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, -+ { "srli.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, -+ { "srai.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, -+ { "srai.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, -+ { "rotri.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, -+ { "rotri.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, -+ { "bstrins.w", la_codec_2r_2bw, la_fmt_rd_rj_msbw_lsbw }, -+ { "bstrpick.w", la_codec_2r_2bw, la_fmt_rd_rj_msbw_lsbw }, -+ { "bstrins.d", la_codec_2r_2bd, la_fmt_rd_rj_msbd_lsbd }, -+ { "bstrpick.d", la_codec_2r_2bd, la_fmt_rd_rj_msbd_lsbd }, -+ { "fadd.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fadd.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fsub.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fsub.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmul.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmul.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fdiv.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fdiv.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmax.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmax.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmin.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmin.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmaxa.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmaxa.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmina.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmina.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fscaleb.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fscaleb.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fcopysign.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fcopysign.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fabs.s", la_codec_2r, la_fmt_fd_fj }, -+ { "fabs.d", la_codec_2r, la_fmt_fd_fj }, -+ { "fneg.s", la_codec_2r, la_fmt_fd_fj }, -+ { "fneg.d", la_codec_2r, la_fmt_fd_fj }, -+ { "flogb.s", la_codec_2r, la_fmt_fd_fj }, -+ { "flogb.d", la_codec_2r, la_fmt_fd_fj }, -+ { "fclass.s", la_codec_2r, la_fmt_fd_fj }, -+ { "fclass.d", la_codec_2r, la_fmt_fd_fj }, -+ { "fsqrt.s", la_codec_2r, la_fmt_fd_fj }, -+ { "fsqrt.d", la_codec_2r, la_fmt_fd_fj }, -+ { "frecip.s", la_codec_2r, la_fmt_fd_fj }, -+ { "frecip.d", la_codec_2r, la_fmt_fd_fj }, -+ { "frsqrt.s", la_codec_2r, la_fmt_fd_fj }, -+ { "frsqrt.d", la_codec_2r, la_fmt_fd_fj }, -+ { "fmov.s", la_codec_2r, la_fmt_fd_fj }, -+ { "fmov.d", la_codec_2r, la_fmt_fd_fj }, -+ { "movgr2fr.w", la_codec_2r, la_fmt_fd_rj }, -+ { "movgr2fr.d", la_codec_2r, la_fmt_fd_rj }, -+ { "movgr2frh.w", la_codec_2r, la_fmt_fd_rj }, -+ { "movfr2gr.s", la_codec_2r, la_fmt_rd_fj }, -+ { "movfr2gr.d", la_codec_2r, la_fmt_rd_fj }, -+ { "movfrh2gr.s", la_codec_2r, la_fmt_rd_fj }, -+ { "movgr2fcsr", la_codec_2r, la_fmt_fcsrd_rj }, -+ { "movfcsr2gr", la_codec_2r, la_fmt_rd_fcsrs }, -+ { "movfr2cf", la_codec_r_cd, la_fmt_cd_fj }, -+ { "movcf2fr", la_codec_r_cj, la_fmt_fd_cj }, -+ { "movgr2cf", la_codec_r_cd, la_fmt_cd_fj }, -+ { "movcf2gr", la_codec_r_cj, la_fmt_fd_cj }, -+ { "fcvt.s.d", la_codec_2r, la_fmt_fd_fj }, -+ { "fcvt.d.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrm.w.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrm.w.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrm.l.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrm.l.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrp.w.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrp.w.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrp.l.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrp.l.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrz.w.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrz.w.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrz.l.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrz.l.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrne.w.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrne.w.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrne.l.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrne.l.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftint.w.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftint.w.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftint.l.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftint.l.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ffint.s.w", la_codec_2r, la_fmt_fd_fj }, -+ { "ffint.s.l", la_codec_2r, la_fmt_fd_fj }, -+ { "ffint.d.w", la_codec_2r, la_fmt_fd_fj }, -+ { "ffint.d.l", la_codec_2r, la_fmt_fd_fj }, -+ { "frint.s", la_codec_2r, la_fmt_fd_fj }, -+ { "frint.d", la_codec_2r, la_fmt_fd_fj }, -+ { "slti", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "sltui", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "addi.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "addi.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "lu52i.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "addi", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ori", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "xori", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "csrxchg", la_codec_2r_im14, la_fmt_rd_rj_csr }, -+ { "cacop", la_codec_im5_r_im12, la_fmt_cop_rj_si12 }, -+ { "lddir", la_codec_2r_im8, la_fmt_rd_rj_level }, -+ { "ldpte", la_codec_r_seq, la_fmt_rj_seq }, -+ { "iocsrrd.b", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrrd.h", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrrd.w", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrrd.d", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrwr.b", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrwr.h", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrwr.w", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrwr.d", la_codec_2r, la_fmt_rd_rj }, -+ { "tlbclr", la_codec_empty, la_fmt_empty }, -+ { "tlbflush", la_codec_empty, la_fmt_empty }, -+ { "tlbsrch", la_codec_empty, la_fmt_empty }, -+ { "tlbrd", la_codec_empty, la_fmt_empty }, -+ { "tlbwr", la_codec_empty, la_fmt_empty }, -+ { "tlbfill", la_codec_empty, la_fmt_empty }, -+ { "ertn", la_codec_empty, la_fmt_empty }, -+ { "idle", la_codec_whint, la_fmt_whint }, -+ { "invtlb", la_codec_invtlb, la_fmt_invtlb }, -+ { "fmadd.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fmadd.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fmsub.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fmsub.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fnmadd.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fnmadd.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fnmsub.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fnmsub.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fcmp.cond.s", la_codec_cond, la_fmt_s_cd_fj_fk }, -+ { "fcmp.cond.d", la_codec_cond, la_fmt_d_cd_fj_fk }, -+ { "fsel", la_codec_sel, la_fmt_fd_fj_fk_ca }, -+ { "addu16i.d", la_codec_2r_im16, la_fmt_rd_rj_si16 }, -+ { "lu12i.w", la_codec_r_im20, la_fmt_rd_si20 }, -+ { "lu32i.d", la_codec_r_im20, la_fmt_rd_si20 }, -+ { "pcaddi", la_codec_r_im20, la_fmt_rd_si20 }, -+ { "pcalau12i", la_codec_r_im20, la_fmt_rd_si20 }, -+ { "pcaddu12i", la_codec_r_im20, la_fmt_rd_si20 }, -+ { "pcaddu18i", la_codec_r_im20, la_fmt_rd_si20 }, -+ { "ll.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "sc.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "ll.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "sc.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "ldptr.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "stptr.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "ldptr.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "stptr.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "ld.b", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ld.h", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ld.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ld.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "st.b", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "st.h", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "st.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "st.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ld.bu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ld.hu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ld.wu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "preld", la_codec_2r_im12, la_fmt_hint_rj_si12 }, -+ { "fld.s", la_codec_2r_im12, la_fmt_fd_fj_si12 }, -+ { "fst.s", la_codec_2r_im12, la_fmt_fd_fj_si12 }, -+ { "fld.d", la_codec_2r_im12, la_fmt_fd_fj_si12 }, -+ { "fst.d", la_codec_2r_im12, la_fmt_fd_fj_si12 }, -+ { "ldl.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ldr.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ldl.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ldr.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "stl.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "str.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ldx.b", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldx.h", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldx.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldx.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stx.b", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stx.h", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stx.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stx.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldx.bu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldx.hu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldx.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "fldx.s", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fldx.d", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fstx.s", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fstx.d", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "amswap.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amswap.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amadd.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amadd.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amand.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amand.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amor.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amor.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amxor.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amxor.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amswap.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amswap.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amadd.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amadd.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amand.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amand.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amor.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amor.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amxor.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amxor.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.db.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.db.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.db.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.db.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "dbar", la_codec_whint, la_fmt_whint }, -+ { "ibar", la_codec_whint, la_fmt_whint }, -+ { "fldgt.s", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fldgt.d", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fldle.s", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fldle.d", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fstgt.s", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fstgt.d", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fstle.s", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fstle.d", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "ldgt.b", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldgt.h", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldgt.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldgt.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldle.b", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldle.h", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldle.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldle.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stgt.b", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stgt.h", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stgt.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stgt.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stle.b", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stle.h", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stle.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stle.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "beqz", la_codec_r_ofs21, la_fmt_rj_offs21 }, -+ { "bnez", la_codec_r_ofs21, la_fmt_rj_offs21 }, -+ { "bceqz", la_codec_cj_ofs21, la_fmt_cj_offs21 }, -+ { "bcnez", la_codec_cj_ofs21, la_fmt_cj_offs21 }, -+ { "jirl", la_codec_2r_im16, la_fmt_rd_rj_offs16 }, -+ { "b", la_codec_ofs26, la_fmt_offs26 }, -+ { "bl", la_codec_ofs26, la_fmt_offs26 }, -+ { "beq", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, -+ { "bne", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, -+ { "blt", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, -+ { "bge", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, -+ { "bltu", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, -+ { "bgeu", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, -+ -+ /* vz insn */ -+ { "hvcl", la_codec_code, la_fmt_code }, -+ -+}; -+ -+ -+/* decode opcode */ -+ -+static void decode_insn_opcode(la_decode *dec) -+{ -+ uint32_t insn = dec->insn; -+ uint16_t op = la_op_illegal; -+ switch ((insn >> 26) & 0x3f) { -+ case 0x0: -+ switch ((insn >> 22) & 0xf) { -+ case 0x0: -+ switch ((insn >> 18) & 0xf) { -+ case 0x0: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x2: -+ switch ((insn >> 2) & 0x7) { -+ case 0x0: -+ op = la_op_gr2scr; -+ break; -+ } -+ break; -+ case 0x3: -+ switch ((insn >> 7) & 0x7) { -+ case 0x0: -+ op = la_op_scr2gr; -+ break; -+ } -+ break; -+ case 0x4: -+ op = la_op_clo_w; -+ break; -+ case 0x5: -+ op = la_op_clz_w; -+ break; -+ case 0x6: -+ op = la_op_cto_w; -+ break; -+ case 0x7: -+ op = la_op_ctz_w; -+ break; -+ case 0x8: -+ op = la_op_clo_d; -+ break; -+ case 0x9: -+ op = la_op_clz_d; -+ break; -+ case 0xa: -+ op = la_op_cto_d; -+ break; -+ case 0xb: -+ op = la_op_ctz_d; -+ break; -+ case 0xc: -+ op = la_op_revb_2h; -+ break; -+ case 0xd: -+ op = la_op_revb_4h; -+ break; -+ case 0xe: -+ op = la_op_revb_2w; -+ break; -+ case 0xf: -+ op = la_op_revb_d; -+ break; -+ case 0x10: -+ op = la_op_revh_2w; -+ break; -+ case 0x11: -+ op = la_op_revh_d; -+ break; -+ case 0x12: -+ op = la_op_bitrev_4b; -+ break; -+ case 0x13: -+ op = la_op_bitrev_8b; -+ break; -+ case 0x14: -+ op = la_op_bitrev_w; -+ break; -+ case 0x15: -+ op = la_op_bitrev_d; -+ break; -+ case 0x16: -+ op = la_op_ext_w_h; -+ break; -+ case 0x17: -+ op = la_op_ext_w_b; -+ break; -+ case 0x1a: -+ op = la_op_rdtime_d; -+ break; -+ case 0x1b: -+ op = la_op_cpucfg; -+ break; -+ } -+ break; -+ case 0x2: -+ switch (insn & 0x0000001f) { -+ case 0x00000000: -+ op = la_op_asrtle_d; -+ break; -+ } -+ break; -+ case 0x3: -+ switch (insn & 0x0000001f) { -+ case 0x00000000: -+ op = la_op_asrtgt_d; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x1: -+ switch ((insn >> 17) & 0x1) { -+ case 0x0: -+ op = la_op_alsl_w; -+ break; -+ case 0x1: -+ op = la_op_alsl_wu; -+ break; -+ } -+ break; -+ case 0x2: -+ switch ((insn >> 17) & 0x1) { -+ case 0x0: -+ op = la_op_bytepick_w; -+ break; -+ } -+ break; -+ case 0x3: -+ op = la_op_bytepick_d; -+ break; -+ case 0x4: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ op = la_op_add_w; -+ break; -+ case 0x1: -+ op = la_op_add_d; -+ break; -+ case 0x2: -+ op = la_op_sub_w; -+ break; -+ case 0x3: -+ op = la_op_sub_d; -+ break; -+ case 0x4: -+ op = la_op_slt; -+ break; -+ case 0x5: -+ op = la_op_sltu; -+ break; -+ case 0x6: -+ op = la_op_maskeqz; -+ break; -+ case 0x7: -+ op = la_op_masknez; -+ break; -+ } -+ break; -+ case 0x5: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ op = la_op_nor; -+ break; -+ case 0x1: -+ op = la_op_and; -+ break; -+ case 0x2: -+ op = la_op_or; -+ break; -+ case 0x3: -+ op = la_op_xor; -+ break; -+ case 0x4: -+ op = la_op_orn; -+ break; -+ case 0x5: -+ op = la_op_andn; -+ break; -+ case 0x6: -+ op = la_op_sll_w; -+ break; -+ case 0x7: -+ op = la_op_srl_w; -+ break; -+ } -+ break; -+ case 0x6: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ op = la_op_sra_w; -+ break; -+ case 0x1: -+ op = la_op_sll_d; -+ break; -+ case 0x2: -+ op = la_op_srl_d; -+ break; -+ case 0x3: -+ op = la_op_sra_d; -+ break; -+ case 0x6: -+ op = la_op_rotr_w; -+ break; -+ case 0x7: -+ op = la_op_rotr_d; -+ break; -+ } -+ break; -+ case 0x7: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ op = la_op_mul_w; -+ break; -+ case 0x1: -+ op = la_op_mulh_w; -+ break; -+ case 0x2: -+ op = la_op_mulh_wu; -+ break; -+ case 0x3: -+ op = la_op_mul_d; -+ break; -+ case 0x4: -+ op = la_op_mulh_d; -+ break; -+ case 0x5: -+ op = la_op_mulh_du; -+ break; -+ case 0x6: -+ op = la_op_mulw_d_w; -+ break; -+ case 0x7: -+ op = la_op_mulw_d_wu; -+ break; -+ } -+ break; -+ case 0x8: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ op = la_op_div_w; -+ break; -+ case 0x1: -+ op = la_op_mod_w; -+ break; -+ case 0x2: -+ op = la_op_div_wu; -+ break; -+ case 0x3: -+ op = la_op_mod_wu; -+ break; -+ case 0x4: -+ op = la_op_div_d; -+ break; -+ case 0x5: -+ op = la_op_mod_d; -+ break; -+ case 0x6: -+ op = la_op_div_du; -+ break; -+ case 0x7: -+ op = la_op_mod_du; -+ break; -+ } -+ break; -+ case 0x9: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ op = la_op_crc_w_b_w; -+ break; -+ case 0x1: -+ op = la_op_crc_w_h_w; -+ break; -+ case 0x2: -+ op = la_op_crc_w_w_w; -+ break; -+ case 0x3: -+ op = la_op_crc_w_d_w; -+ break; -+ case 0x4: -+ op = la_op_crcc_w_b_w; -+ break; -+ case 0x5: -+ op = la_op_crcc_w_h_w; -+ break; -+ case 0x6: -+ op = la_op_crcc_w_w_w; -+ break; -+ case 0x7: -+ op = la_op_crcc_w_d_w; -+ break; -+ } -+ break; -+ case 0xa: -+ switch ((insn >> 15) & 0x7) { -+ case 0x4: -+ op = la_op_break; -+ break; -+ case 0x5: -+ op = la_op_dbcl; -+ break; -+ case 0x6: -+ op = la_op_syscall; -+ break; -+ case 0x7: -+ op = la_op_hvcl; -+ break; -+ } -+ break; -+ case 0xb: -+ switch ((insn >> 17) & 0x1) { -+ case 0x0: -+ op = la_op_alsl_d; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x1: -+ switch ((insn >> 21) & 0x1) { -+ case 0x0: -+ switch ((insn >> 16) & 0x1f) { -+ case 0x0: -+ switch ((insn >> 15) & 0x1) { -+ case 0x1: -+ op = la_op_slli_w; -+ break; -+ } -+ break; -+ case 0x1: -+ op = la_op_slli_d; -+ break; -+ case 0x4: -+ switch ((insn >> 15) & 0x1) { -+ case 0x1: -+ op = la_op_srli_w; -+ break; -+ } -+ break; -+ case 0x5: -+ op = la_op_srli_d; -+ break; -+ case 0x8: -+ switch ((insn >> 15) & 0x1) { -+ case 0x1: -+ op = la_op_srai_w; -+ break; -+ } -+ break; -+ case 0x9: -+ op = la_op_srai_d; -+ break; -+ case 0xc: -+ switch ((insn >> 15) & 0x1) { -+ case 0x1: -+ op = la_op_rotri_w; -+ break; -+ } -+ break; -+ case 0xd: -+ op = la_op_rotri_d; -+ break; -+ } -+ break; -+ case 0x1: -+ switch ((insn >> 15) & 0x1) { -+ case 0x0: -+ op = la_op_bstrins_w; -+ break; -+ case 0x1: -+ op = la_op_bstrpick_w; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x2: -+ op = la_op_bstrins_d; -+ break; -+ case 0x3: -+ op = la_op_bstrpick_d; -+ break; -+ case 0x4: -+ switch ((insn >> 15) & 0x7f) { -+ case 0x1: -+ op = la_op_fadd_s; -+ break; -+ case 0x2: -+ op = la_op_fadd_d; -+ break; -+ case 0x5: -+ op = la_op_fsub_s; -+ break; -+ case 0x6: -+ op = la_op_fsub_d; -+ break; -+ case 0x9: -+ op = la_op_fmul_s; -+ break; -+ case 0xa: -+ op = la_op_fmul_d; -+ break; -+ case 0xd: -+ op = la_op_fdiv_s; -+ break; -+ case 0xe: -+ op = la_op_fdiv_d; -+ break; -+ case 0x11: -+ op = la_op_fmax_s; -+ break; -+ case 0x12: -+ op = la_op_fmax_d; -+ break; -+ case 0x15: -+ op = la_op_fmin_s; -+ break; -+ case 0x16: -+ op = la_op_fmin_d; -+ break; -+ case 0x19: -+ op = la_op_fmaxa_s; -+ break; -+ case 0x1a: -+ op = la_op_fmaxa_d; -+ break; -+ case 0x1d: -+ op = la_op_fmina_s; -+ break; -+ case 0x1e: -+ op = la_op_fmina_d; -+ break; -+ case 0x21: -+ op = la_op_fscaleb_s; -+ break; -+ case 0x22: -+ op = la_op_fscaleb_d; -+ break; -+ case 0x25: -+ op = la_op_fcopysign_s; -+ break; -+ case 0x26: -+ op = la_op_fcopysign_d; -+ break; -+ case 0x28: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x1: -+ op = la_op_fabs_s; -+ break; -+ case 0x2: -+ op = la_op_fabs_d; -+ break; -+ case 0x5: -+ op = la_op_fneg_s; -+ break; -+ case 0x6: -+ op = la_op_fneg_d; -+ break; -+ case 0x9: -+ op = la_op_flogb_s; -+ break; -+ case 0xa: -+ op = la_op_flogb_d; -+ break; -+ case 0xd: -+ op = la_op_fclass_s; -+ break; -+ case 0xe: -+ op = la_op_fclass_d; -+ break; -+ case 0x11: -+ op = la_op_fsqrt_s; -+ break; -+ case 0x12: -+ op = la_op_fsqrt_d; -+ break; -+ case 0x15: -+ op = la_op_frecip_s; -+ break; -+ case 0x16: -+ op = la_op_frecip_d; -+ break; -+ case 0x19: -+ op = la_op_frsqrt_s; -+ break; -+ case 0x1a: -+ op = la_op_frsqrt_d; -+ break; -+ } -+ break; -+ case 0x29: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x5: -+ op = la_op_fmov_s; -+ break; -+ case 0x6: -+ op = la_op_fmov_d; -+ break; -+ case 0x9: -+ op = la_op_movgr2fr_w; -+ break; -+ case 0xa: -+ op = la_op_movgr2fr_d; -+ break; -+ case 0xb: -+ op = la_op_movgr2frh_w; -+ break; -+ case 0xd: -+ op = la_op_movfr2gr_s; -+ break; -+ case 0xe: -+ op = la_op_movfr2gr_d; -+ break; -+ case 0xf: -+ op = la_op_movfrh2gr_s; -+ break; -+ case 0x10: -+ op = la_op_movgr2fcsr; -+ break; -+ case 0x12: -+ op = la_op_movfcsr2gr; -+ break; -+ case 0x14: -+ switch ((insn >> 3) & 0x3) { -+ case 0x0: -+ op = la_op_movfr2cf; -+ break; -+ } -+ break; -+ case 0x15: -+ switch ((insn >> 8) & 0x3) { -+ case 0x0: -+ op = la_op_movcf2fr; -+ break; -+ } -+ break; -+ case 0x16: -+ switch ((insn >> 3) & 0x3) { -+ case 0x0: -+ op = la_op_movgr2cf; -+ break; -+ } -+ break; -+ case 0x17: -+ switch ((insn >> 8) & 0x3) { -+ case 0x0: -+ op = la_op_movcf2gr; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x32: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x6: -+ op = la_op_fcvt_s_d; -+ break; -+ case 0x9: -+ op = la_op_fcvt_d_s; -+ break; -+ } -+ break; -+ case 0x34: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x1: -+ op = la_op_ftintrm_w_s; -+ break; -+ case 0x2: -+ op = la_op_ftintrm_w_d; -+ break; -+ case 0x9: -+ op = la_op_ftintrm_l_s; -+ break; -+ case 0xa: -+ op = la_op_ftintrm_l_d; -+ break; -+ case 0x11: -+ op = la_op_ftintrp_w_s; -+ break; -+ case 0x12: -+ op = la_op_ftintrp_w_d; -+ break; -+ case 0x19: -+ op = la_op_ftintrp_l_s; -+ break; -+ case 0x1a: -+ op = la_op_ftintrp_l_d; -+ break; -+ } -+ break; -+ case 0x35: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x1: -+ op = la_op_ftintrz_w_s; -+ break; -+ case 0x2: -+ op = la_op_ftintrz_w_d; -+ break; -+ case 0x9: -+ op = la_op_ftintrz_l_s; -+ break; -+ case 0xa: -+ op = la_op_ftintrz_l_d; -+ break; -+ case 0x11: -+ op = la_op_ftintrne_w_s; -+ break; -+ case 0x12: -+ op = la_op_ftintrne_w_d; -+ break; -+ case 0x19: -+ op = la_op_ftintrne_l_s; -+ break; -+ case 0x1a: -+ op = la_op_ftintrne_l_d; -+ break; -+ } -+ break; -+ case 0x36: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x1: -+ op = la_op_ftint_w_s; -+ break; -+ case 0x2: -+ op = la_op_ftint_w_d; -+ break; -+ case 0x9: -+ op = la_op_ftint_l_s; -+ break; -+ case 0xa: -+ op = la_op_ftint_l_d; -+ break; -+ } -+ break; -+ case 0x3a: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x4: -+ op = la_op_ffint_s_w; -+ break; -+ case 0x6: -+ op = la_op_ffint_s_l; -+ break; -+ case 0x8: -+ op = la_op_ffint_d_w; -+ break; -+ case 0xa: -+ op = la_op_ffint_d_l; -+ break; -+ } -+ break; -+ case 0x3c: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x11: -+ op = la_op_frint_s; -+ break; -+ case 0x12: -+ op = la_op_frint_d; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x8: -+ op = la_op_slti; -+ break; -+ case 0x9: -+ op = la_op_sltui; -+ break; -+ case 0xa: -+ op = la_op_addi_w; -+ break; -+ case 0xb: -+ op = la_op_addi_d; -+ break; -+ case 0xc: -+ op = la_op_lu52i_d; -+ break; -+ case 0xd: -+ op = la_op_addi; -+ break; -+ case 0xe: -+ op = la_op_ori; -+ break; -+ case 0xf: -+ op = la_op_xori; -+ break; -+ } -+ break; -+ case 0x1: -+ switch ((insn >> 24) & 0x3) { -+ case 0x0: -+ op = la_op_csrxchg; -+ break; -+ case 0x2: -+ switch ((insn >> 22) & 0x3) { -+ case 0x0: -+ op = la_op_cacop; -+ break; -+ case 0x1: -+ switch ((insn >> 18) & 0xf) { -+ case 0x0: -+ op = la_op_lddir; -+ break; -+ case 0x1: -+ switch (insn & 0x0000001f) { -+ case 0x00000000: -+ op = la_op_ldpte; -+ break; -+ } -+ break; -+ case 0x2: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x0: -+ op = la_op_iocsrrd_b; -+ break; -+ case 0x1: -+ op = la_op_iocsrrd_h; -+ break; -+ case 0x2: -+ op = la_op_iocsrrd_w; -+ break; -+ case 0x3: -+ op = la_op_iocsrrd_d; -+ break; -+ case 0x4: -+ op = la_op_iocsrwr_b; -+ break; -+ case 0x5: -+ op = la_op_iocsrwr_h; -+ break; -+ case 0x6: -+ op = la_op_iocsrwr_w; -+ break; -+ case 0x7: -+ op = la_op_iocsrwr_d; -+ break; -+ case 0x8: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_tlbclr; -+ break; -+ } -+ break; -+ case 0x9: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_tlbflush; -+ break; -+ } -+ break; -+ case 0xa: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_tlbsrch; -+ break; -+ } -+ break; -+ case 0xb: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_tlbrd; -+ break; -+ } -+ break; -+ case 0xc: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_tlbwr; -+ break; -+ } -+ break; -+ case 0xd: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_tlbfill; -+ break; -+ } -+ break; -+ case 0xe: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_ertn; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x1: -+ op = la_op_idle; -+ break; -+ case 0x3: -+ op = la_op_invtlb; -+ break; -+ } -+ break; -+ } -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x2: -+ switch ((insn >> 20) & 0x3f) { -+ case 0x1: -+ op = la_op_fmadd_s; -+ break; -+ case 0x2: -+ op = la_op_fmadd_d; -+ break; -+ case 0x5: -+ op = la_op_fmsub_s; -+ break; -+ case 0x6: -+ op = la_op_fmsub_d; -+ break; -+ case 0x9: -+ op = la_op_fnmadd_s; -+ break; -+ case 0xa: -+ op = la_op_fnmadd_d; -+ break; -+ case 0xd: -+ op = la_op_fnmsub_s; -+ break; -+ case 0xe: -+ op = la_op_fnmsub_d; -+ break; -+ } -+ break; -+ case 0x3: -+ switch ((insn >> 20) & 0x3f) { -+ case 0x1: -+ switch ((insn >> 3) & 0x3) { -+ case 0x0: -+ op = la_op_fcmp_cond_s; -+ break; -+ } -+ break; -+ case 0x2: -+ switch ((insn >> 3) & 0x3) { -+ case 0x0: -+ op = la_op_fcmp_cond_d; -+ break; -+ } -+ break; -+ case 0x10: -+ switch ((insn >> 18) & 0x3) { -+ case 0x0: -+ op = la_op_fsel; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x4: -+ op = la_op_addu16i_d; -+ break; -+ case 0x5: -+ switch ((insn >> 25) & 0x1) { -+ case 0x0: -+ op = la_op_lu12i_w; -+ break; -+ case 0x1: -+ op = la_op_lu32i_d; -+ break; -+ } -+ break; -+ case 0x6: -+ switch ((insn >> 25) & 0x1) { -+ case 0x0: -+ op = la_op_pcaddi; -+ break; -+ case 0x1: -+ op = la_op_pcalau12i; -+ break; -+ } -+ break; -+ case 0x7: -+ switch ((insn >> 25) & 0x1) { -+ case 0x0: -+ op = la_op_pcaddu12i; -+ break; -+ case 0x1: -+ op = la_op_pcaddu18i; -+ break; -+ } -+ break; -+ case 0x8: -+ switch ((insn >> 24) & 0x3) { -+ case 0x0: -+ op = la_op_ll_w; -+ break; -+ case 0x1: -+ op = la_op_sc_w; -+ break; -+ case 0x2: -+ op = la_op_ll_d; -+ break; -+ case 0x3: -+ op = la_op_sc_d; -+ break; -+ } -+ break; -+ case 0x9: -+ switch ((insn >> 24) & 0x3) { -+ case 0x0: -+ op = la_op_ldptr_w; -+ break; -+ case 0x1: -+ op = la_op_stptr_w; -+ break; -+ case 0x2: -+ op = la_op_ldptr_d; -+ break; -+ case 0x3: -+ op = la_op_stptr_d; -+ break; -+ } -+ break; -+ case 0xa: -+ switch ((insn >> 22) & 0xf) { -+ case 0x0: -+ op = la_op_ld_b; -+ break; -+ case 0x1: -+ op = la_op_ld_h; -+ break; -+ case 0x2: -+ op = la_op_ld_w; -+ break; -+ case 0x3: -+ op = la_op_ld_d; -+ break; -+ case 0x4: -+ op = la_op_st_b; -+ break; -+ case 0x5: -+ op = la_op_st_h; -+ break; -+ case 0x6: -+ op = la_op_st_w; -+ break; -+ case 0x7: -+ op = la_op_st_d; -+ break; -+ case 0x8: -+ op = la_op_ld_bu; -+ break; -+ case 0x9: -+ op = la_op_ld_hu; -+ break; -+ case 0xa: -+ op = la_op_ld_wu; -+ break; -+ case 0xb: -+ op = la_op_preld; -+ break; -+ case 0xc: -+ op = la_op_fld_s; -+ break; -+ case 0xd: -+ op = la_op_fst_s; -+ break; -+ case 0xe: -+ op = la_op_fld_d; -+ break; -+ case 0xf: -+ op = la_op_fst_d; -+ break; -+ } -+ break; -+ case 0xb: -+ switch ((insn >> 22) & 0xf) { -+ case 0x8: -+ op = la_op_ldl_w; -+ break; -+ case 0x9: -+ op = la_op_ldr_w; -+ break; -+ case 0xa: -+ op = la_op_ldl_d; -+ break; -+ case 0xb: -+ op = la_op_ldr_d; -+ break; -+ case 0xe: -+ op = la_op_stl_d; -+ break; -+ case 0xf: -+ op = la_op_str_d; -+ break; -+ } -+ break; -+ case 0xe: -+ switch ((insn >> 15) & 0x7ff) { -+ case 0x0: -+ op = la_op_ldx_b; -+ break; -+ case 0x8: -+ op = la_op_ldx_h; -+ break; -+ case 0x10: -+ op = la_op_ldx_w; -+ break; -+ case 0x18: -+ op = la_op_ldx_d; -+ break; -+ case 0x20: -+ op = la_op_stx_b; -+ break; -+ case 0x28: -+ op = la_op_stx_h; -+ break; -+ case 0x30: -+ op = la_op_stx_w; -+ break; -+ case 0x38: -+ op = la_op_stx_d; -+ break; -+ case 0x40: -+ op = la_op_ldx_bu; -+ break; -+ case 0x48: -+ op = la_op_ldx_hu; -+ break; -+ case 0x50: -+ op = la_op_ldx_wu; -+ break; -+ case 0x60: -+ op = la_op_fldx_s; -+ break; -+ case 0x68: -+ op = la_op_fldx_d; -+ break; -+ case 0x70: -+ op = la_op_fstx_s; -+ break; -+ case 0x78: -+ op = la_op_fstx_d; -+ break; -+ case 0xc0: -+ op = la_op_amswap_w; -+ break; -+ case 0xc1: -+ op = la_op_amswap_d; -+ break; -+ case 0xc2: -+ op = la_op_amadd_w; -+ break; -+ case 0xc3: -+ op = la_op_amadd_d; -+ break; -+ case 0xc4: -+ op = la_op_amand_w; -+ break; -+ case 0xc5: -+ op = la_op_amand_d; -+ break; -+ case 0xc6: -+ op = la_op_amor_w; -+ break; -+ case 0xc7: -+ op = la_op_amor_d; -+ break; -+ case 0xc8: -+ op = la_op_amxor_w; -+ break; -+ case 0xc9: -+ op = la_op_amxor_d; -+ break; -+ case 0xca: -+ op = la_op_ammax_w; -+ break; -+ case 0xcb: -+ op = la_op_ammax_d; -+ break; -+ case 0xcc: -+ op = la_op_ammin_w; -+ break; -+ case 0xcd: -+ op = la_op_ammin_d; -+ break; -+ case 0xce: -+ op = la_op_ammax_wu; -+ break; -+ case 0xcf: -+ op = la_op_ammax_du; -+ break; -+ case 0xd0: -+ op = la_op_ammin_wu; -+ break; -+ case 0xd1: -+ op = la_op_ammin_du; -+ break; -+ case 0xd2: -+ op = la_op_amswap_db_w; -+ break; -+ case 0xd3: -+ op = la_op_amswap_db_d; -+ break; -+ case 0xd4: -+ op = la_op_amadd_db_w; -+ break; -+ case 0xd5: -+ op = la_op_amadd_db_d; -+ break; -+ case 0xd6: -+ op = la_op_amand_db_w; -+ break; -+ case 0xd7: -+ op = la_op_amand_db_d; -+ break; -+ case 0xd8: -+ op = la_op_amor_db_w; -+ break; -+ case 0xd9: -+ op = la_op_amor_db_d; -+ break; -+ case 0xda: -+ op = la_op_amxor_db_w; -+ break; -+ case 0xdb: -+ op = la_op_amxor_db_d; -+ break; -+ case 0xdc: -+ op = la_op_ammax_db_w; -+ break; -+ case 0xdd: -+ op = la_op_ammax_db_d; -+ break; -+ case 0xde: -+ op = la_op_ammin_db_w; -+ break; -+ case 0xdf: -+ op = la_op_ammin_db_d; -+ break; -+ case 0xe0: -+ op = la_op_ammax_db_wu; -+ break; -+ case 0xe1: -+ op = la_op_ammax_db_du; -+ break; -+ case 0xe2: -+ op = la_op_ammin_db_wu; -+ break; -+ case 0xe3: -+ op = la_op_ammin_db_du; -+ break; -+ case 0xe4: -+ op = la_op_dbar; -+ break; -+ case 0xe5: -+ op = la_op_ibar; -+ break; -+ case 0xe8: -+ op = la_op_fldgt_s; -+ break; -+ case 0xe9: -+ op = la_op_fldgt_d; -+ break; -+ case 0xea: -+ op = la_op_fldle_s; -+ break; -+ case 0xeb: -+ op = la_op_fldle_d; -+ break; -+ case 0xec: -+ op = la_op_fstgt_s; -+ break; -+ case 0xed: -+ op = la_op_fstgt_d; -+ break; -+ case 0xee: -+ op = ls_op_fstle_s; -+ break; -+ case 0xef: -+ op = la_op_fstle_d; -+ break; -+ case 0xf0: -+ op = la_op_ldgt_b; -+ break; -+ case 0xf1: -+ op = la_op_ldgt_h; -+ break; -+ case 0xf2: -+ op = la_op_ldgt_w; -+ break; -+ case 0xf3: -+ op = la_op_ldgt_d; -+ break; -+ case 0xf4: -+ op = la_op_ldle_b; -+ break; -+ case 0xf5: -+ op = la_op_ldle_h; -+ break; -+ case 0xf6: -+ op = la_op_ldle_w; -+ break; -+ case 0xf7: -+ op = la_op_ldle_d; -+ break; -+ case 0xf8: -+ op = la_op_stgt_b; -+ break; -+ case 0xf9: -+ op = la_op_stgt_h; -+ break; -+ case 0xfa: -+ op = la_op_stgt_w; -+ break; -+ case 0xfb: -+ op = la_op_stgt_d; -+ break; -+ case 0xfc: -+ op = la_op_stle_b; -+ break; -+ case 0xfd: -+ op = la_op_stle_h; -+ break; -+ case 0xfe: -+ op = la_op_stle_w; -+ break; -+ case 0xff: -+ op = la_op_stle_d; -+ break; -+ } -+ break; -+ case 0x10: -+ op = la_op_beqz; -+ break; -+ case 0x11: -+ op = la_op_bnez; -+ break; -+ case 0x12: -+ switch ((insn >> 8) & 0x3) { -+ case 0x0: -+ op = la_op_bceqz; -+ break; -+ case 0x1: -+ op = la_op_bcnez; -+ break; -+ } -+ break; -+ case 0x13: -+ op = la_op_jirl; -+ break; -+ case 0x14: -+ op = la_op_b; -+ break; -+ case 0x15: -+ op = la_op_bl; -+ break; -+ case 0x16: -+ op = la_op_beq; -+ break; -+ case 0x17: -+ op = la_op_bne; -+ break; -+ case 0x18: -+ op = la_op_blt; -+ break; -+ case 0x19: -+ op = la_op_bge; -+ break; -+ case 0x1a: -+ op = la_op_bltu; -+ break; -+ case 0x1b: -+ op = la_op_bgeu; -+ break; -+ default: -+ op = la_op_illegal; -+ break; -+ } -+ dec->op = op; -+} -+ -+/* operand extractors */ -+ -+#define IM_5 5 -+#define IM_8 8 -+#define IM_12 12 -+#define IM_14 14 -+#define IM_15 15 -+#define IM_16 16 -+#define IM_20 20 -+#define IM_21 21 -+#define IM_26 26 -+ -+static uint32_t operand_r1(uint32_t insn) -+{ -+ return insn & 0x1f; -+} -+ -+static uint32_t operand_r2(uint32_t insn) -+{ -+ return (insn >> 5) & 0x1f; -+} -+ -+static uint32_t operand_r3(uint32_t insn) -+{ -+ return (insn >> 10) & 0x1f; -+} -+ -+static uint32_t operand_r4(uint32_t insn) -+{ -+ return (insn >> 15) & 0x1f; -+} -+ -+static uint32_t operand_u6(uint32_t insn) -+{ -+ return (insn >> 10) & 0x3f; -+} -+ -+static uint32_t operand_bw1(uint32_t insn) -+{ -+ return (insn >> 10) & 0x1f; -+} -+ -+static uint32_t operand_bw2(uint32_t insn) -+{ -+ return (insn >> 16) & 0x1f; -+} -+ -+static uint32_t operand_bd1(uint32_t insn) -+{ -+ return (insn >> 10) & 0x3f; -+} -+ -+static uint32_t operand_bd2(uint32_t insn) -+{ -+ return (insn >> 16) & 0x3f; -+} -+ -+static uint32_t operand_sa2(uint32_t insn) -+{ -+ return (insn >> 15) & 0x3; -+} -+ -+static uint32_t operand_sa3(uint32_t insn) -+{ -+ return (insn >> 15) & 0x3; -+} -+ -+static int32_t operand_im20(uint32_t insn) -+{ -+ int32_t imm = (int32_t)((insn >> 5) & 0xfffff); -+ return imm > (1 << 19) ? imm - (1 << 20) : imm; -+} -+ -+static int32_t operand_im16(uint32_t insn) -+{ -+ int32_t imm = (int32_t)((insn >> 10) & 0xffff); -+ return imm > (1 << 15) ? imm - (1 << 16) : imm; -+} -+ -+static int32_t operand_im14(uint32_t insn) -+{ -+ int32_t imm = (int32_t)((insn >> 10) & 0x3fff); -+ return imm > (1 << 13) ? imm - (1 << 14) : imm; -+} -+ -+static int32_t operand_im12(uint32_t insn) -+{ -+ int32_t imm = (int32_t)((insn >> 10) & 0xfff); -+ return imm > (1 << 11) ? imm - (1 << 12) : imm; -+} -+ -+static int32_t operand_im8(uint32_t insn) -+{ -+ int32_t imm = (int32_t)((insn >> 10) & 0xff); -+ return imm > (1 << 7) ? imm - (1 << 8) : imm; -+} -+ -+static uint32_t operand_sd(uint32_t insn) -+{ -+ return insn & 0x3; -+} -+ -+static uint32_t operand_sj(uint32_t insn) -+{ -+ return (insn >> 5) & 0x3; -+} -+ -+static uint32_t operand_cd(uint32_t insn) -+{ -+ return insn & 0x7; -+} -+ -+static uint32_t operand_cj(uint32_t insn) -+{ -+ return (insn >> 5) & 0x7; -+} -+ -+static uint32_t operand_code(uint32_t insn) -+{ -+ return insn & 0x7fff; -+} -+ -+static int32_t operand_whint(uint32_t insn) -+{ -+ int32_t imm = (int32_t)(insn & 0x7fff); -+ return imm > (1 << 14) ? imm - (1 << 15) : imm; -+} -+ -+static int32_t operand_invop(uint32_t insn) -+{ -+ int32_t imm = (int32_t)(insn & 0x1f); -+ return imm > (1 << 4) ? imm - (1 << 5) : imm; -+} -+ -+static int32_t operand_ofs21(uint32_t insn) -+{ -+ int32_t imm = (((int32_t)insn & 0x1f) << 16) | -+ ((insn >> 10) & 0xffff); -+ return imm > (1 << 20) ? imm - (1 << 21) : imm; -+} -+ -+static int32_t operand_ofs26(uint32_t insn) -+{ -+ int32_t imm = (((int32_t)insn & 0x3ff) << 16) | -+ ((insn >> 10) & 0xffff); -+ return imm > (1 << 25) ? imm - (1 << 26) : imm; -+} -+ -+static uint32_t operand_fcond(uint32_t insn) -+{ -+ return (insn >> 15) & 0x1f; -+} -+ -+static uint32_t operand_sel(uint32_t insn) -+{ -+ return (insn >> 15) & 0x7; -+} -+ -+/* decode operands */ -+ -+static void decode_insn_operands(la_decode *dec) -+{ -+ uint32_t insn = dec->insn; -+ dec->codec = opcode_data[dec->op].codec; -+ switch (dec->codec) { -+ case la_codec_illegal: -+ case la_codec_empty: -+ break; -+ case la_codec_2r: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ break; -+ case la_codec_2r_u5: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ break; -+ case la_codec_2r_u6: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_u6(insn); -+ break; -+ case la_codec_2r_2bw: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_bw1(insn); -+ dec->r4 = operand_bw2(insn); -+ break; -+ case la_codec_2r_2bd: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_bd1(insn); -+ dec->r4 = operand_bd2(insn); -+ break; -+ case la_codec_3r: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ break; -+ case la_codec_3r_rd0: -+ dec->r1 = 0; -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ break; -+ case la_codec_3r_sa2: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ dec->r4 = operand_sa2(insn); -+ break; -+ case la_codec_3r_sa3: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ dec->r4 = operand_sa3(insn); -+ break; -+ case la_codec_4r: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ dec->r4 = operand_r4(insn); -+ break; -+ case la_codec_r_im20: -+ dec->r1 = operand_r1(insn); -+ dec->imm = operand_im20(insn); -+ dec->bit = IM_20; -+ break; -+ case la_codec_2r_im16: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->imm = operand_im16(insn); -+ dec->bit = IM_16; -+ break; -+ case la_codec_2r_im14: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->imm = operand_im14(insn); -+ dec->bit = IM_14; -+ break; -+ case la_codec_im5_r_im12: -+ dec->imm2 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->imm = operand_im12(insn); -+ dec->bit = IM_12; -+ break; -+ case la_codec_2r_im12: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->imm = operand_im12(insn); -+ dec->bit = IM_12; -+ break; -+ case la_codec_2r_im8: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->imm = operand_im8(insn); -+ dec->bit = IM_8; -+ break; -+ case la_codec_r_sd: -+ dec->r1 = operand_sd(insn); -+ dec->r2 = operand_r2(insn); -+ break; -+ case la_codec_r_sj: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_sj(insn); -+ break; -+ case la_codec_r_cd: -+ dec->r1 = operand_cd(insn); -+ dec->r2 = operand_r2(insn); -+ break; -+ case la_codec_r_cj: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_cj(insn); -+ break; -+ case la_codec_r_seq: -+ dec->r1 = 0; -+ dec->r2 = operand_r1(insn); -+ dec->imm = operand_im8(insn); -+ dec->bit = IM_8; -+ break; -+ case la_codec_code: -+ dec->code = operand_code(insn); -+ break; -+ case la_codec_whint: -+ dec->imm = operand_whint(insn); -+ dec->bit = IM_15; -+ break; -+ case la_codec_invtlb: -+ dec->imm = operand_invop(insn); -+ dec->bit = IM_5; -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ break; -+ case la_codec_r_ofs21: -+ dec->imm = operand_ofs21(insn); -+ dec->bit = IM_21; -+ dec->r2 = operand_r2(insn); -+ break; -+ case la_codec_cj_ofs21: -+ dec->imm = operand_ofs21(insn); -+ dec->bit = IM_21; -+ dec->r2 = operand_cj(insn); -+ break; -+ case la_codec_ofs26: -+ dec->imm = operand_ofs26(insn); -+ dec->bit = IM_26; -+ break; -+ case la_codec_cond: -+ dec->r1 = operand_cd(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ dec->r4 = operand_fcond(insn); -+ break; -+ case la_codec_sel: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ dec->r4 = operand_sel(insn); -+ break; -+ } -+} -+ -+/* format instruction */ -+ -+static void append(char *s1, const char *s2, size_t n) -+{ -+ size_t l1 = strlen(s1); -+ if (n - l1 - 1 > 0) { -+ strncat(s1, s2, n - l1); -+ } -+} -+ -+static void format_insn(char *buf, size_t buflen, size_t tab, la_decode *dec) -+{ -+ char tmp[16]; -+ const char *fmt; -+ -+ fmt = opcode_data[dec->op].format; -+ while (*fmt) { -+ switch (*fmt) { -+ case 'n': /* name */ -+ append(buf, opcode_data[dec->op].name, buflen); -+ break; -+ case 's': -+ append(buf, "s", buflen); -+ break; -+ case 'd': -+ append(buf, "d", buflen); -+ break; -+ case 'e': /* illegal */ -+ snprintf(tmp, sizeof(tmp), "%x", dec->insn); -+ append(buf, tmp, buflen); -+ break; -+ case 't': -+ while (strlen(buf) < tab) { -+ append(buf, " ", buflen); -+ } -+ break; -+ case '(': -+ append(buf, "(", buflen); -+ break; -+ case ',': -+ append(buf, ",", buflen); -+ break; -+ case '.': -+ append(buf, ".", buflen); -+ break; -+ case ')': -+ append(buf, ")", buflen); -+ break; -+ case '0': /* rd */ -+ append(buf, loongarch_r_normal_name[dec->r1], buflen); -+ break; -+ case '1': /* rj */ -+ append(buf, loongarch_r_normal_name[dec->r2], buflen); -+ break; -+ case '2': /* rk */ -+ append(buf, loongarch_r_normal_name[dec->r3], buflen); -+ break; -+ case '3': /* fd */ -+ append(buf, loongarch_f_normal_name[dec->r1], buflen); -+ break; -+ case '4': /* fj */ -+ append(buf, loongarch_f_normal_name[dec->r2], buflen); -+ break; -+ case '5': /* fk */ -+ append(buf, loongarch_f_normal_name[dec->r3], buflen); -+ break; -+ case '6': /* fa */ -+ append(buf, loongarch_f_normal_name[dec->r4], buflen); -+ break; -+ case 'A': /* sd */ -+ append(buf, loongarch_cr_normal_name[dec->r1], buflen); -+ break; -+ case 'B': /* sj */ -+ append(buf, loongarch_cr_normal_name[dec->r2], buflen); -+ break; -+ case 'C': /* r3 */ -+ snprintf(tmp, sizeof(tmp), "%x", dec->r3); -+ append(buf, tmp, buflen); -+ break; -+ case 'D': /* r4 */ -+ snprintf(tmp, sizeof(tmp), "%x", dec->r4); -+ append(buf, tmp, buflen); -+ break; -+ case 'E': /* r1 */ -+ snprintf(tmp, sizeof(tmp), "%x", dec->r1); -+ append(buf, tmp, buflen); -+ break; -+ case 'F': /* fcsrd */ -+ append(buf, loongarch_r_normal_name[dec->r1], buflen); -+ break; -+ case 'G': /* fcsrs */ -+ append(buf, loongarch_r_normal_name[dec->r2], buflen); -+ break; -+ case 'H': /* cd */ -+ append(buf, loongarch_c_normal_name[dec->r1], buflen); -+ break; -+ case 'I': /* cj */ -+ append(buf, loongarch_c_normal_name[dec->r2], buflen); -+ break; -+ case 'J': /* code */ -+ snprintf(tmp, sizeof(tmp), "0x%x", dec->code); -+ append(buf, tmp, buflen); -+ break; -+ case 'K': /* cond */ -+ switch (dec->r4) { -+ case 0x0: -+ append(buf, "caf", buflen); -+ break; -+ case 0x1: -+ append(buf, "saf", buflen); -+ break; -+ case 0x2: -+ append(buf, "clt", buflen); -+ break; -+ case 0x3: -+ append(buf, "slt", buflen); -+ break; -+ case 0x4: -+ append(buf, "ceq", buflen); -+ break; -+ case 0x5: -+ append(buf, "seq", buflen); -+ break; -+ case 0x6: -+ append(buf, "cle", buflen); -+ break; -+ case 0x7: -+ append(buf, "sle", buflen); -+ break; -+ case 0x8: -+ append(buf, "cun", buflen); -+ break; -+ case 0x9: -+ append(buf, "sun", buflen); -+ break; -+ case 0xA: -+ append(buf, "cult", buflen); -+ break; -+ case 0xB: -+ append(buf, "sult", buflen); -+ break; -+ case 0xC: -+ append(buf, "cueq", buflen); -+ break; -+ case 0xD: -+ append(buf, "sueq", buflen); -+ break; -+ case 0xE: -+ append(buf, "cule", buflen); -+ break; -+ case 0xF: -+ append(buf, "sule", buflen); -+ break; -+ case 0x10: -+ append(buf, "cne", buflen); -+ break; -+ case 0x11: -+ append(buf, "sne", buflen); -+ break; -+ case 0x14: -+ append(buf, "cor", buflen); -+ break; -+ case 0x15: -+ append(buf, "sor", buflen); -+ break; -+ case 0x18: -+ append(buf, "cune", buflen); -+ break; -+ case 0x19: -+ append(buf, "sune", buflen); -+ break; -+ } -+ break; -+ case 'L': /* ca */ -+ append(buf, loongarch_c_normal_name[dec->r4], buflen); -+ break; -+ case 'M': /* cop */ -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm2) & 0x1f); -+ append(buf, tmp, buflen); -+ break; -+ case 'i': /* sixx d */ -+ snprintf(tmp, sizeof(tmp), "%d", dec->imm); -+ append(buf, tmp, buflen); -+ break; -+ case 'o': /* offset */ -+ snprintf(tmp, sizeof(tmp), "%d", (dec->imm) << 2); -+ append(buf, tmp, buflen); -+ break; -+ case 'x': /* sixx x */ -+ switch (dec->bit) { -+ case IM_5: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x1f); -+ append(buf, tmp, buflen); -+ break; -+ case IM_8: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_12: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xfff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_14: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x3fff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_15: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x7fff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_16: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xffff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_20: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xfffff); -+ append(buf, tmp, buflen); -+ break; -+ default: -+ snprintf(tmp, sizeof(tmp), "0x%x", dec->imm); -+ append(buf, tmp, buflen); -+ break; -+ } -+ break; -+ case 'X': /* offset x*/ -+ switch (dec->bit) { -+ case IM_16: -+ snprintf(tmp, sizeof(tmp), "0x%x", -+ ((dec->imm) << 2) & 0xffff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_21: -+ snprintf(tmp, sizeof(tmp), "0x%x", -+ ((dec->imm) << 2) & 0x1fffff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_26: -+ snprintf(tmp, sizeof(tmp), "0x%x", -+ ((dec->imm) << 2) & 0x3ffffff); -+ append(buf, tmp, buflen); -+ break; -+ default: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) << 2); -+ append(buf, tmp, buflen); -+ break; -+ } -+ break; -+ case 'p': /* pc */ -+ snprintf(tmp, sizeof(tmp), " # 0x%"PRIx32"", -+ dec->pc + ((dec->imm) << 2)); -+ append(buf, tmp, buflen); -+ break; -+ default: -+ break; -+ } -+ fmt++; -+ } -+} -+ -+ -+/* disassemble instruction */ -+ -+static void -+disasm_insn(char *buf, size_t buflen, bfd_vma pc, unsigned long int insn) -+{ -+ la_decode dec = { 0 }; -+ dec.pc = pc; -+ dec.insn = insn; -+ decode_insn_opcode(&dec); -+ decode_insn_operands(&dec); -+ format_insn(buf, buflen, 16, &dec); -+} -+ -+int -+print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info) -+{ -+ char buf[128] = { 0 }; -+ bfd_byte buffer[INSNLEN]; -+ unsigned long insn; -+ int status; -+ -+ status = (*info->read_memory_func)(memaddr, buffer, INSNLEN, info); -+ if (status == 0) { -+ insn = (uint32_t) bfd_getl32(buffer); -+ (*info->fprintf_func)(info->stream, "%08" PRIx64 " ", insn); -+ } else { -+ (*info->memory_error_func)(status, memaddr, info); -+ return -1; -+ } -+ disasm_insn(buf, sizeof(buf), memaddr, insn); -+ (*info->fprintf_func)(info->stream, "\t%s", buf); -+ return INSNLEN; -+} -diff --git a/disas/meson.build b/disas/meson.build -index 449f99e1d..06a69d9d7 100644 ---- a/disas/meson.build -+++ b/disas/meson.build -@@ -12,6 +12,7 @@ common_ss.add(when: 'CONFIG_I386_DIS', if_true: files('i386.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_LOONGARCH_DIS', if_true: files('loongarch.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/gdb-xml/loongarch-base32.xml b/gdb-xml/loongarch-base32.xml -new file mode 100644 -index 000000000..04891e023 ---- /dev/null -+++ b/gdb-xml/loongarch-base32.xml -@@ -0,0 +1,43 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/gdb-xml/loongarch-base64.xml b/gdb-xml/loongarch-base64.xml -new file mode 100644 -index 000000000..6308fb6ec ---- /dev/null -+++ b/gdb-xml/loongarch-base64.xml -@@ -0,0 +1,43 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/gdb-xml/loongarch-fpu32.xml b/gdb-xml/loongarch-fpu32.xml -new file mode 100644 -index 000000000..a5b4d80e6 ---- /dev/null -+++ b/gdb-xml/loongarch-fpu32.xml -@@ -0,0 +1,52 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/gdb-xml/loongarch-fpu64.xml b/gdb-xml/loongarch-fpu64.xml -new file mode 100644 -index 000000000..74ab55a01 ---- /dev/null -+++ b/gdb-xml/loongarch-fpu64.xml -@@ -0,0 +1,57 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ --- -2.43.5 - diff --git a/0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch b/0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch deleted file mode 100644 index af4851e..0000000 --- a/0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch +++ /dev/null @@ -1,35 +0,0 @@ -From e25884e4e0ee839b591836ae33681ac9a52883ce Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Wed, 25 Aug 2021 12:36:00 +0800 -Subject: [PATCH 6/8] anolis: csv/i386: CSV guest do not need - register/unregister guest secure memory - -CSV guest memory is allocated by firmware in secure processor -from dedicated memory reserved upon system boot up, -consequently it is not necessary to add notifier to pin/unpin memory. - -Signed-off-by: Xin Jiang -Change-Id: I10d5b5ee8dbc3a1bf9ed1935c006c61a094f1e8d ---- - target/i386/sev.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 73a794ef74..36669bbdf4 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -973,7 +973,10 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - goto err; - } - -- ram_block_notifier_add(&sev_ram_notifier); -+ /* CSV guest needs no notifier to reg/unreg memory */ -+ if (!csv_enabled()) { -+ ram_block_notifier_add(&sev_ram_notifier); -+ } - qemu_add_machine_init_done_notifier(&sev_machine_done_notify); - qemu_add_vm_change_state_handler(sev_vm_state_change, sev); - --- -2.17.1 - diff --git a/0007-Modify-kvm-cpu-vga-qapi.patch b/0007-Modify-kvm-cpu-vga-qapi.patch deleted file mode 100644 index 7c09b0a..0000000 --- a/0007-Modify-kvm-cpu-vga-qapi.patch +++ /dev/null @@ -1,477 +0,0 @@ -From 42c6c2a89fa44100141cd2b7e178f965d1b8f80f Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Sat, 20 Aug 2022 02:18:41 -0400 -Subject: [PATCH 07/28] Modify kvm cpu vga qapi. - -Change-Id: I7923af804bdbe6d44d3f521df1859aa081afceba -Signed-off-by: lixianglai -Signed-off-by: Mao Bibo ---- - hw/acpi/cpu.c | 11 ++++++ - hw/loongarch/iocsr.c | 2 ++ - hw/loongarch/larch_3a.c | 18 +++++----- - hw/meson.build | 1 + - include/disas/dis-asm.h | 1 + - include/elf.h | 2 ++ - include/hw/loongarch/larch.h | 1 - - include/qemu/osdep.h | 3 ++ - include/sysemu/arch_init.h | 1 + - linux-headers/linux/kvm.h | 23 +++++++++++++ - linux-user/elfload.c | 67 ++++++++++++++++++++++++++++++++++++ - linux-user/meson.build | 1 + - linux-user/qemu.h | 2 +- - linux-user/syscall.c | 3 ++ - linux-user/syscall_defs.h | 9 ++--- - meson.build | 1 + - pc-bios/meson.build | 1 + - qapi/machine-target.json | 6 ++-- - qapi/machine.json | 2 +- - qapi/misc-target.json | 1 + - 20 files changed, 138 insertions(+), 18 deletions(-) - -diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c -index b20903ea3..cd73fab65 100644 ---- a/hw/acpi/cpu.c -+++ b/hw/acpi/cpu.c -@@ -371,14 +371,25 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, - aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0)); - - crs = aml_resource_template(); -+#ifdef __loongarch__ -+ aml_append(crs, aml_memory32_fixed(io_base, -+ ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE)); -+#else - aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1, - ACPI_CPU_HOTPLUG_REG_LEN)); -+#endif - aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs)); - - /* declare CPU hotplug MMIO region with related access fields */ -+#ifdef __loongarch__ -+ aml_append(cpu_ctrl_dev, -+ aml_operation_region("PRST", AML_SYSTEM_MEMORY, aml_int(io_base), -+ ACPI_CPU_HOTPLUG_REG_LEN)); -+#else - aml_append(cpu_ctrl_dev, - aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base), - ACPI_CPU_HOTPLUG_REG_LEN)); -+#endif - - field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, - AML_WRITE_AS_ZEROS); -diff --git a/hw/loongarch/iocsr.c b/hw/loongarch/iocsr.c -index 14521c2d5..60daafd6e 100644 ---- a/hw/loongarch/iocsr.c -+++ b/hw/loongarch/iocsr.c -@@ -59,6 +59,7 @@ enum { - IOCSR_MAX - }; - -+#ifdef CONFIG_KVM - static uint32_t iocsr_array[IOCSR_MAX] = { - [IOCSR_FEATURES] = LOONGARCH_IOCSR_FEATURES, - [IOCSR_VENDOR] = LOONGARCH_IOCSR_VENDOR, -@@ -66,6 +67,7 @@ static uint32_t iocsr_array[IOCSR_MAX] = { - [IOCSR_NODECNT] = LOONGARCH_IOCSR_NODECNT, - [IOCSR_MISC_FUNC] = LOONGARCH_IOCSR_MISC_FUNC, - }; -+#endif - - - #define TYPE_IOCSR "iocsr" -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -index 3db269274..3194a822c 100644 ---- a/hw/loongarch/larch_3a.c -+++ b/hw/loongarch/larch_3a.c -@@ -846,7 +846,7 @@ static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg, - if (0 < initrd_size) { - if (initrd_size > highram_size) { - error_report("initrd size is too big, should below %ld MB", -- highram_size / S_1MiB); -+ highram_size / MiB); - /*prevent write io memory address space*/ - exit(1); - } -@@ -1033,7 +1033,9 @@ static void *ls3a_intctl_init(MachineState *machine, CPULOONGARCHState *env[]) - SysBusDevice *busdev; - MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *iomem = NULL; -+#ifdef CONFIG_KVM - int i; -+#endif - - s = g_malloc0(sizeof(ls3a_intctlstate)); - -@@ -1214,8 +1216,6 @@ static void loongarch_build_smbios(LoongarchMachineState *lsms) - product = "Loongarch-3A5K-7A1000-TCG"; - } - -- host_cpufreq = get_host_cpu_freq(); -- - smbios_set_defaults("Loongson", product, lsmc->cpu_name, false, - true, NULL, NULL, SMBIOS_ENTRY_POINT_30); - -@@ -1672,15 +1672,15 @@ static void ls3a5k_init(MachineState *args) - - offset += lowram_size; - if (nb_numa_nodes > 0) { -- highram_size = numa_info[0].node_mem - S_256MiB; -- if (numa_info[0].node_mem > S_1GiB) { -- memmap_size = numa_info[0].node_mem - S_1GiB; -+ highram_size = numa_info[0].node_mem - 256 * MiB; -+ if (numa_info[0].node_mem > GiB) { -+ memmap_size = numa_info[0].node_mem - GiB; - la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); - } - } else { -- highram_size = ram_size - S_256MiB; -- if (ram_size > S_1GiB) { -- memmap_size = ram_size - S_1GiB; -+ highram_size = ram_size - 256 * MiB; -+ if (ram_size > GiB) { -+ memmap_size = ram_size - GiB; - la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); - } - } -diff --git a/hw/meson.build b/hw/meson.build -index b3366c888..f224f8ad2 100644 ---- a/hw/meson.build -+++ b/hw/meson.build -@@ -17,6 +17,7 @@ subdir('intc') - subdir('ipack') - subdir('ipmi') - subdir('isa') -+subdir('loongarch') - subdir('mem') - subdir('misc') - subdir('net') -diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h -index 08e1beec8..95b93f100 100644 ---- a/include/disas/dis-asm.h -+++ b/include/disas/dis-asm.h -@@ -461,6 +461,7 @@ int print_insn_riscv32 (bfd_vma, disassemble_info*); - int print_insn_riscv64 (bfd_vma, disassemble_info*); - int print_insn_rx(bfd_vma, disassemble_info *); - int print_insn_hexagon(bfd_vma, disassemble_info *); -+int print_insn_loongarch (bfd_vma, disassemble_info*); - - #ifdef CONFIG_CAPSTONE - bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size); -diff --git a/include/elf.h b/include/elf.h -index 4edab8e5a..c614bfb12 100644 ---- a/include/elf.h -+++ b/include/elf.h -@@ -182,6 +182,8 @@ typedef struct mips_elf_abiflags_v0 { - - #define EM_NANOMIPS 249 /* Wave Computing nanoMIPS */ - -+#define EM_LOONGARCH 258 /* Loongarch */ -+ - /* - * This is an interim value that we will use until the committee comes - * up with a final number. -diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h -index 0886ed52a..62e2830e2 100644 ---- a/include/hw/loongarch/larch.h -+++ b/include/hw/loongarch/larch.h -@@ -159,5 +159,4 @@ bool loongarch_is_acpi_enabled(LoongarchMachineState *vms); - void ls7a_madt_cpu_entry(AcpiDeviceIf *adev, int uid, - const CPUArchIdList *apic_ids, GArray *entry, bool force_enabled); - void slave_cpu_reset(void *opaque); --extern uint64_t host_cpufreq; - #endif -diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h -index 60718fc34..903475bb2 100644 ---- a/include/qemu/osdep.h -+++ b/include/qemu/osdep.h -@@ -533,6 +533,9 @@ static inline void qemu_cleanup_generic_vfree(void *p) - Valgrind does not support alignments larger than 1 MiB, - therefore we need special code which handles running on Valgrind. */ - # define QEMU_VMALLOC_ALIGN (512 * 4096) -+#elif defined(__linux__) && defined(__loongarch__) -+ /* Use 32 MiB alignment so transparent hugepages can be used by KVM. */ -+# define QEMU_VMALLOC_ALIGN (qemu_real_host_page_size * qemu_real_host_page_size / 8) - #elif defined(__linux__) && defined(__s390x__) - /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */ - # define QEMU_VMALLOC_ALIGN (256 * 4096) -diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h -index 70c579560..62d1a4b92 100644 ---- a/include/sysemu/arch_init.h -+++ b/include/sysemu/arch_init.h -@@ -24,6 +24,7 @@ enum { - QEMU_ARCH_RX = (1 << 20), - QEMU_ARCH_AVR = (1 << 21), - QEMU_ARCH_HEXAGON = (1 << 22), -+ QEMU_ARCH_LOONGARCH64 = (1 << 23), - }; - - extern const uint32_t arch_type; -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index c65930288..0e50d3749 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2115,6 +2115,29 @@ struct kvm_stats_desc { - char name[]; - }; - -+#ifdef __loongarch__ -+struct kvm_loongarch_vcpu_state { -+ __u8 online_vcpus; -+ __u8 is_migrate; -+ __u32 cpu_freq; -+ __u32 count_ctl; -+ __u64 pending_exceptions; -+ __u64 pending_exceptions_clr; -+ __u64 core_ext_ioisr[4]; -+}; -+ -+#define KVM_CAP_LOONGARCH_FPU 165 -+#define KVM_CAP_LOONGARCH_LSX 166 -+#define KVM_CAP_LOONGARCH_VZ 167 -+#define KVM_REG_LOONGARCH 0x8000000000000000ULL -+#define KVM_LARCH_GET_VCPU_STATE _IOR(KVMIO, 0xc0, struct kvm_loongarch_vcpu_state) -+#define KVM_LARCH_SET_VCPU_STATE _IOW(KVMIO, 0xc1, struct kvm_loongarch_vcpu_state) -+#define KVM_LARCH_GET_CPUCFG _IOR(KVMIO, 0xc2, struct kvm_cpucfg) -+#define KVM_LOONGARCH_GET_IOCSR _IOR(KVMIO, 0xc3, struct kvm_iocsr_entry) -+#define KVM_LOONGARCH_SET_IOCSR _IOW(KVMIO, 0xc4, struct kvm_iocsr_entry) -+#define KVM_LARCH_SET_CPUCFG _IOR(KVMIO, 0xc5, struct kvm_cpucfg) -+#endif -+ - #define KVM_GET_STATS_FD _IO(KVMIO, 0xce) - - /* Available with KVM_CAP_XSAVE2 */ -diff --git a/linux-user/elfload.c b/linux-user/elfload.c -index 767f54c76..9fb632780 100644 ---- a/linux-user/elfload.c -+++ b/linux-user/elfload.c -@@ -1041,6 +1041,73 @@ static uint32_t get_elf_hwcap(void) - - #endif /* TARGET_MIPS */ - -+#ifdef TARGET_LOONGARCH64 -+ -+#define ELF_START_MMAP 0x80000000 -+ -+#define ELF_CLASS ELFCLASS64 -+#define ELF_ARCH EM_LOONGARCH -+ -+#define elf_check_arch(x) ((x) == EM_LOONGARCH) -+ -+static inline void init_thread(struct target_pt_regs *regs, -+ struct image_info *infop) -+{ -+ regs->csr_crmd = 2 << 3; -+ regs->csr_era = infop->entry; -+ regs->regs[3] = infop->start_stack; -+} -+ -+/* See linux kernel: arch/mips/include/asm/elf.h. */ -+#define ELF_NREG 45 -+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG]; -+ -+/* See linux kernel: arch/loongarch/include/uapi/asm/reg.h */ -+enum { -+ TARGET_EF_R0 = 0, -+ TARGET_EF_R26 = TARGET_EF_R0 + 26, -+ TARGET_EF_R27 = TARGET_EF_R0 + 27, -+ TARGET_EF_CSR_ERA = TARGET_EF_R0 + 32, -+ TARGET_EF_CSR_BADV = TARGET_EF_R0 + 33, -+ TARGET_EF_CSR_CRMD = TARGET_EF_R0 + 34, -+ TARGET_EF_CSR_ESTAT = TARGET_EF_R0 + 38 -+}; -+ -+/* See linux kernel: arch/loongarch/kernel/process.c:elf_dump_regs. */ -+static void elf_core_copy_regs(target_elf_gregset_t *regs, -+ const CPULOONGARCHState *env) -+{ -+ int i; -+ -+ for (i = 0; i < TARGET_EF_R0; i++) { -+ (*regs)[i] = 0; -+ } -+ (*regs)[TARGET_EF_R0] = 0; -+ -+ for (i = 1; i < ARRAY_SIZE(env->active_tc.gpr); i++) { -+ (*regs)[TARGET_EF_R0 + i] = tswapreg(env->active_tc.gpr[i]); -+ } -+ -+ (*regs)[TARGET_EF_R26] = 0; -+ (*regs)[TARGET_EF_R27] = 0; -+ (*regs)[TARGET_EF_CSR_ERA] = tswapreg(env->active_tc.PC); -+ (*regs)[TARGET_EF_CSR_BADV] = tswapreg(env->CSR_BADV); -+ (*regs)[TARGET_EF_CSR_CRMD] = tswapreg(env->CSR_CRMD); -+ (*regs)[TARGET_EF_CSR_ESTAT] = tswapreg(env->CSR_ESTAT); -+} -+ -+#define USE_ELF_CORE_DUMP -+#define ELF_EXEC_PAGESIZE 4096 -+ -+#define ELF_HWCAP get_elf_hwcap() -+ -+static uint32_t get_elf_hwcap(void) -+{ -+ return 0; -+} -+ -+#endif /* TARGET_LOONGARCH64 */ -+ - #ifdef TARGET_MICROBLAZE - - #define ELF_START_MMAP 0x80000000 -diff --git a/linux-user/meson.build b/linux-user/meson.build -index bf62c13e3..195f9e83a 100644 ---- a/linux-user/meson.build -+++ b/linux-user/meson.build -@@ -39,3 +39,4 @@ subdir('sh4') - subdir('sparc') - subdir('x86_64') - subdir('xtensa') -+subdir('loongarch64') -diff --git a/linux-user/qemu.h b/linux-user/qemu.h -index 5c713fa8a..66ddb25d1 100644 ---- a/linux-user/qemu.h -+++ b/linux-user/qemu.h -@@ -61,7 +61,7 @@ struct image_info { - /* For target-specific processing of NT_GNU_PROPERTY_TYPE_0. */ - uint32_t note_flags; - --#ifdef TARGET_MIPS -+#if defined(TARGET_MIPS) || defined(TARGET_LOONGARCH64) - int fp_abi; - int interp_fp_abi; - #endif -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index f1cfcc810..729131ecd 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -1614,6 +1614,9 @@ static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, - #elif defined(TARGET_MIPS) - ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1]; - return host_pipe[0]; -+#elif defined(TARGET_LOONGARCH64) -+ ((CPULOONGARCHState *)cpu_env)->active_tc.gpr[5] = host_pipe[1]; -+ return host_pipe[0]; - #elif defined(TARGET_SH4) - ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1]; - return host_pipe[0]; -diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h -index 0b1397593..7e2915d53 100644 ---- a/linux-user/syscall_defs.h -+++ b/linux-user/syscall_defs.h -@@ -74,7 +74,7 @@ - || defined(TARGET_M68K) || defined(TARGET_CRIS) \ - || defined(TARGET_S390X) || defined(TARGET_OPENRISC) \ - || defined(TARGET_NIOS2) || defined(TARGET_RISCV) \ -- || defined(TARGET_XTENSA) -+ || defined(TARGET_XTENSA) || defined(TARGET_LOONGARCH64) - - #define TARGET_IOC_SIZEBITS 14 - #define TARGET_IOC_DIRBITS 2 -@@ -450,7 +450,7 @@ struct target_dirent64 { - #define TARGET_SIG_IGN ((abi_long)1) /* ignore signal */ - #define TARGET_SIG_ERR ((abi_long)-1) /* error return from signal */ - --#ifdef TARGET_MIPS -+#if defined(TARGET_MIPS) || defined(TARGET_LOONGARCH64) - #define TARGET_NSIG 128 - #else - #define TARGET_NSIG 64 -@@ -2133,7 +2133,7 @@ struct target_stat64 { - abi_ulong __unused5; - }; - --#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || defined(TARGET_RISCV) -+#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || defined(TARGET_RISCV) || defined(TARGET_LOONGARCH64) - - /* These are the asm-generic versions of the stat and stat64 structures */ - -@@ -2161,7 +2161,7 @@ struct target_stat { - unsigned int __unused5; - }; - --#if !defined(TARGET_RISCV64) -+#if !(defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)) - #define TARGET_HAS_STRUCT_STAT64 - struct target_stat64 { - uint64_t st_dev; -@@ -2331,6 +2331,7 @@ struct target_statfs64 { - }; - #elif (defined(TARGET_PPC64) || defined(TARGET_X86_64) || \ - defined(TARGET_SPARC64) || defined(TARGET_AARCH64) || \ -+ defined(TARGET_LOONGARCH64) || \ - defined(TARGET_RISCV)) && !defined(TARGET_ABI32) - struct target_statfs { - abi_long f_type; -diff --git a/meson.build b/meson.build -index 5f6ba86db..fc2dc58f3 100644 ---- a/meson.build -+++ b/meson.build -@@ -1814,6 +1814,7 @@ disassemblers = { - 'sh4' : ['CONFIG_SH4_DIS'], - 'sparc' : ['CONFIG_SPARC_DIS'], - 'xtensa' : ['CONFIG_XTENSA_DIS'], -+ 'loongarch64' : ['CONFIG_LOONGARCH_DIS'], - } - if link_language == 'cpp' - disassemblers += { -diff --git a/pc-bios/meson.build b/pc-bios/meson.build -index b40ff3f2b..a09ca4d03 100644 ---- a/pc-bios/meson.build -+++ b/pc-bios/meson.build -@@ -83,6 +83,7 @@ blobs = files( - 'opensbi-riscv32-generic-fw_dynamic.elf', - 'opensbi-riscv64-generic-fw_dynamic.elf', - 'npcm7xx_bootrom.bin', -+ 'loongarch_bios.bin', - ) - - if get_option('install_blobs') -diff --git a/qapi/machine-target.json b/qapi/machine-target.json -index f5ec4bc17..682dc86b4 100644 ---- a/qapi/machine-target.json -+++ b/qapi/machine-target.json -@@ -324,7 +324,8 @@ - 'TARGET_ARM', - 'TARGET_I386', - 'TARGET_S390X', -- 'TARGET_MIPS' ] } } -+ 'TARGET_MIPS', -+ 'TARGET_LOONGARCH64' ] } } - - ## - # @query-cpu-definitions: -@@ -340,4 +341,5 @@ - 'TARGET_ARM', - 'TARGET_I386', - 'TARGET_S390X', -- 'TARGET_MIPS' ] } } -+ 'TARGET_MIPS', -+ 'TARGET_LOONGARCH64' ] } } -diff --git a/qapi/machine.json b/qapi/machine.json -index a9f33d0f2..cd47b8d6b 100644 ---- a/qapi/machine.json -+++ b/qapi/machine.json -@@ -34,7 +34,7 @@ - 'mips64el', 'mipsel', 'nios2', 'or1k', 'ppc', - 'ppc64', 'riscv32', 'riscv64', 'rx', 's390x', 'sh4', - 'sh4eb', 'sparc', 'sparc64', 'tricore', -- 'x86_64', 'xtensa', 'xtensaeb' ] } -+ 'x86_64', 'xtensa', 'xtensaeb', 'loongarch64' ] } - - ## - # @CpuS390State: -diff --git a/qapi/misc-target.json b/qapi/misc-target.json -index ede905244..2cf4fa418 100644 ---- a/qapi/misc-target.json -+++ b/qapi/misc-target.json -@@ -33,6 +33,7 @@ - 'TARGET_PPC64', - 'TARGET_S390X', - 'TARGET_SH4', -+ 'TARGET_LOONGARCH64', - 'TARGET_SPARC' ] } } - - ## --- -2.43.5 - diff --git a/0007-anolis-target-i386-csv-load-initial-image-to-private.patch b/0007-anolis-target-i386-csv-load-initial-image-to-private.patch deleted file mode 100644 index a40bcfe..0000000 --- a/0007-anolis-target-i386-csv-load-initial-image-to-private.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 2df9c321195bd47485867e1d821913f1f3c21fc2 Mon Sep 17 00:00:00 2001 -From: Xin Jiang -Date: Fri, 25 Aug 2023 14:51:16 +0800 -Subject: [PATCH 7/8] anolis: target/i386: csv: load initial image to private - memory - -The initial image of CSV guest should be loaded into private memory -before guest boot. - -Add APIs to implement the image load. - -Signed-off-by: Xin Jiang -Change-Id: I708e7521bfe079216c0e0aea619a9c6bb1d7af04 ---- - hw/i386/pc_sysfw.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c -index c8b17af953..84aad306dc 100644 ---- a/hw/i386/pc_sysfw.c -+++ b/hw/i386/pc_sysfw.c -@@ -38,6 +38,7 @@ - #include "hw/block/flash.h" - #include "sysemu/kvm.h" - #include "sev.h" -+#include "csv.h" - - #define FLASH_SECTOR_SIZE 4096 - -@@ -208,7 +209,10 @@ static void pc_system_flash_map(PCMachineState *pcms, - exit(1); - } - -- sev_encrypt_flash(flash_ptr, flash_size, &error_fatal); -+ if (csv_enabled()) -+ csv_load_data(flash_mem->addr, flash_ptr, flash_size, &error_fatal); -+ else -+ sev_encrypt_flash(flash_ptr, flash_size, &error_fatal); - } - } - } --- -2.17.1 - diff --git a/0008-Modify-compile-script.patch b/0008-Modify-compile-script.patch deleted file mode 100644 index bcf14cc..0000000 --- a/0008-Modify-compile-script.patch +++ /dev/null @@ -1,36 +0,0 @@ -From c46de76fc41792974d0e1c9896f89ab257cae345 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 22 Aug 2022 08:22:03 -0400 -Subject: [PATCH 08/28] Modify compile script. - -Change-Id: I8573477d64f5974092001869d7aa9bb093f347e8 -Signed-off-by: lixianglai ---- - meson.build | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/meson.build b/meson.build -index fc2dc58f3..c0fb5788f 100644 ---- a/meson.build -+++ b/meson.build -@@ -56,7 +56,7 @@ python = import('python').find_installation() - - supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux'] - supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64', -- 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64'] -+ 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64', 'loongarch64'] - - cpu = host_machine.cpu_family() - -@@ -77,6 +77,8 @@ elif cpu in ['ppc', 'ppc64'] - kvm_targets = ['ppc-softmmu', 'ppc64-softmmu'] - elif cpu in ['mips', 'mips64'] - kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu'] -+elif cpu == 'loongarch64' -+ kvm_targets = ['loongarch64-softmmu'] - else - kvm_targets = [] - endif --- -2.43.5 - diff --git a/0008-anolis-vga-force-full-update-for-CSV-guest.patch b/0008-anolis-vga-force-full-update-for-CSV-guest.patch deleted file mode 100644 index 40842ec..0000000 --- a/0008-anolis-vga-force-full-update-for-CSV-guest.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 42d8658a8868721a0c4fb08295a8957e9fdc96c6 Mon Sep 17 00:00:00 2001 -From: Xin Jiang -Date: Thu, 13 Jul 2023 09:35:10 +0800 -Subject: [PATCH 8/8] anolis: vga: force full update for CSV guest - -As CSV's NPT(nested page table) is managed by firmware, VMM is hard -to track the dirty pages of vga buffer. Although VMM could perform -a command to firmware to update read/write attribute of vga buffer -in NPT, it costs more time due to communication between VMM and -firmware. So the simplest method is to fully update vga buffer -always. - -Signed-off-by: Xin Jiang -Change-Id: I51ff00440483011fb9088a75005644beb378f8dd ---- - hw/display/vga.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/hw/display/vga.c b/hw/display/vga.c -index 9d1f66af40..be4282a2f5 100644 ---- a/hw/display/vga.c -+++ b/hw/display/vga.c -@@ -36,6 +36,9 @@ - #include "migration/vmstate.h" - #include "trace.h" - -+#include "target/i386/sev.h" -+#include "target/i386/csv.h" -+ - //#define DEBUG_VGA_MEM - //#define DEBUG_VGA_REG - -@@ -1779,6 +1782,11 @@ static void vga_update_display(void *opaque) - s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); - full_update = 1; - } -+ -+ /* Force to full update in CSV guest. */ -+ if (csv_enabled()) -+ full_update = 1; -+ - switch(graphic_mode) { - case GMODE_TEXT: - vga_draw_text(s, full_update); --- -2.17.1 - diff --git a/0009-Add-loongarch64-rh-devices.mak.patch b/0009-Add-loongarch64-rh-devices.mak.patch deleted file mode 100644 index a06c1f0..0000000 --- a/0009-Add-loongarch64-rh-devices.mak.patch +++ /dev/null @@ -1,3227 +0,0 @@ -From 89fb9c8e0ca11e311417981d46768642d1f8e6d2 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Wed, 24 Aug 2022 22:56:29 -0400 -Subject: [PATCH 09/28] Add loongarch64-rh-devices.mak. - -Change-Id: I375face82c0aa68c053254b879267830d6981756 -Signed-off-by: lixianglai ---- - .../loongarch64-rh-devices.mak | 155 ++ - configure | 5 + - meson.build | 2 + - pc-bios/meson.build | 1 + - tcg/loongarch64/tcg-insn-defs.c.inc | 979 +++++++++ - tcg/loongarch64/tcg-target-con-set.h | 31 + - tcg/loongarch64/tcg-target-con-str.h | 28 + - tcg/loongarch64/tcg-target.c.inc | 1744 +++++++++++++++++ - tcg/loongarch64/tcg-target.h | 178 ++ - 9 files changed, 3123 insertions(+) - create mode 100644 configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak - create mode 100644 tcg/loongarch64/tcg-insn-defs.c.inc - create mode 100644 tcg/loongarch64/tcg-target-con-set.h - create mode 100644 tcg/loongarch64/tcg-target-con-str.h - create mode 100644 tcg/loongarch64/tcg-target.c.inc - create mode 100644 tcg/loongarch64/tcg-target.h - -diff --git a/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak -new file mode 100644 -index 000000000..e7b5bdc8e ---- /dev/null -+++ b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak -@@ -0,0 +1,155 @@ -+ -+include ../rh-virtio.mak -+# Default configuration for loongarch-softmmu -+ -+CONFIG_PCI=y -+CONFIG_ACPI_PCI=y -+# For now, CONFIG_IDE_CORE requires ISA, so we enable it here -+CONFIG_ISA_BUS=y -+CONFIG_VIRTIO_PCI=y -+ -+CONFIG_VGA_PCI=y -+CONFIG_ACPI_SMBUS=y -+#CONFIG_VHOST_USER_SCSI=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) -+CONFIG_VHOST_USER_SCSI=y -+#CONFIG_VHOST_USER_BLK=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) -+CONFIG_VHOST_USER_BLK=y -+CONFIG_VIRTIO=y -+CONFIG_VIRTIO_BALLOON=y -+CONFIG_VIRTIO_BLK=y -+CONFIG_VIRTIO_CRYPTO=y -+CONFIG_VIRTIO_GPU=y -+CONFIG_VIRTIO_INPUT=y -+CONFIG_VIRTIO_NET=y -+CONFIG_VIRTIO_RNG=y -+CONFIG_SCSI=y -+CONFIG_VIRTIO_SCSI=y -+CONFIG_VIRTIO_SERIAL=y -+ -+CONFIG_USB_UHCI=y -+CONFIG_USB_OHCI=y -+CONFIG_USB_OHCI_PCI=y -+CONFIG_USB_XHCI=y -+CONFIG_USB_XHCI_NEC=y -+CONFIG_NE2000_PCI=y -+CONFIG_EEPRO100_PCI=y -+CONFIG_PCNET_PCI=y -+CONFIG_PCNET_COMMON=y -+CONFIG_AC97=y -+CONFIG_HDA=y -+CONFIG_ES1370=y -+CONFIG_SCSI=y -+CONFIG_LSI_SCSI_PCI=y -+CONFIG_VMW_PVSCSI_SCSI_PCI=y -+CONFIG_MEGASAS_SCSI_PCI=y -+CONFIG_MPTSAS_SCSI_PCI=y -+CONFIG_RTL8139_PCI=y -+CONFIG_E1000_PCI=y -+CONFIG_IDE_CORE=y -+CONFIG_IDE_QDEV=y -+CONFIG_IDE_PCI=y -+CONFIG_AHCI=y -+CONFIG_AHCI_ICH9=y -+CONFIG_ESP=y -+CONFIG_ESP_PCI=y -+CONFIG_SERIAL=y -+CONFIG_SERIAL_ISA=y -+CONFIG_SERIAL_PCI=y -+CONFIG_CAN_BUS=y -+CONFIG_CAN_SJA1000=y -+CONFIG_CAN_PCI=y -+CONFIG_USB_UHCI=y -+CONFIG_USB_OHCI=y -+CONFIG_USB_XHCI=y -+CONFIG_USB_XHCI_NEC=y -+CONFIG_NE2000_PCI=y -+CONFIG_EEPRO100_PCI=y -+CONFIG_PCNET_PCI=y -+CONFIG_PCNET_COMMON=y -+CONFIG_AC97=y -+CONFIG_HDA=y -+CONFIG_ES1370=y -+CONFIG_SCSI=y -+CONFIG_LSI_SCSI_PCI=y -+CONFIG_VMW_PVSCSI_SCSI_PCI=y -+CONFIG_MEGASAS_SCSI_PCI=y -+CONFIG_MPTSAS_SCSI_PCI=y -+CONFIG_RTL8139_PCI=y -+CONFIG_E1000_PCI=y -+CONFIG_IDE_CORE=y -+CONFIG_IDE_QDEV=y -+CONFIG_IDE_PCI=y -+CONFIG_AHCI=y -+CONFIG_ESP=y -+CONFIG_ESP_PCI=y -+CONFIG_SERIAL=y -+CONFIG_SERIAL_ISA=y -+CONFIG_SERIAL_PCI=y -+CONFIG_CAN_BUS=y -+CONFIG_CAN_SJA1000=y -+CONFIG_CAN_PCI=y -+ -+CONFIG_SPICE=y -+CONFIG_QXL=y -+CONFIG_ESP=y -+CONFIG_SCSI=y -+CONFIG_VGA_ISA=y -+CONFIG_VGA_ISA_MM=y -+CONFIG_VGA_CIRRUS=y -+CONFIG_VMWARE_VGA=y -+CONFIG_VIRTIO_VGA=y -+CONFIG_SERIAL_ISA=y -+CONFIG_PARALLEL=y -+CONFIG_I8254=y -+CONFIG_PCSPK=y -+CONFIG_PCKBD=y -+CONFIG_FDC=y -+CONFIG_ACPI=y -+CONFIG_ACPI_MEMORY_HOTPLUG=y -+CONFIG_ACPI_NVDIMM=y -+CONFIG_ACPI_CPU_HOTPLUG=y -+CONFIG_APM=y -+CONFIG_I8257=y -+CONFIG_PIIX4=y -+CONFIG_IDE_ISA=y -+CONFIG_IDE_PIIX=y -+#CONFIG_NE2000_ISA=y -+CONFIG_MIPSNET=y -+CONFIG_PFLASH_CFI01=y -+CONFIG_I8259=y -+CONFIG_MC146818RTC=y -+CONFIG_ISA_TESTDEV=y -+CONFIG_EMPTY_SLOT=y -+CONFIG_I2C=y -+CONFIG_DIMM=y -+CONFIG_MEM_DEVICE=y -+ -+# Arch Specified CONFIG defines -+CONFIG_IDE_VIA=y -+CONFIG_VT82C686=y -+CONFIG_RC4030=y -+CONFIG_DP8393X=y -+CONFIG_DS1225Y=y -+CONFIG_FITLOADER=y -+CONFIG_SMBIOS=y -+ -+CONFIG_PCIE_PORT=y -+CONFIG_I82801B11=y -+CONFIG_XIO3130=y -+CONFIG_PCI_EXPRESS=y -+CONFIG_MSI_NONBROKEN=y -+CONFIG_IOH3420=y -+CONFIG_SD=y -+CONFIG_SDHCI=y -+CONFIG_VIRTFS=y -+CONFIG_VIRTIO_9P=y -+CONFIG_USB_EHCI=y -+CONFIG_USB_EHCI_PCI=y -+CONFIG_USB_EHCI_SYSBUS=y -+CONFIG_USB_STORAGE_BOT=y -+CONFIG_TPM_EMULATOR=y -+CONFIG_TPM_TIS=y -+CONFIG_PLATFORM_BUS=y -+CONFIG_TPM_TIS_SYSBUS=y -+CONFIG_ACPI_LOONGARCH=y -+CONFIG_LS7A_RTC=y -diff --git a/configure b/configure -index 48c21775f..1f932f7ee 100755 ---- a/configure -+++ b/configure -@@ -581,6 +581,8 @@ elif check_define __arm__ ; then - cpu="arm" - elif check_define __aarch64__ ; then - cpu="aarch64" -+elif check_define __loongarch__ ; then -+ cpu="loongarch64" - else - cpu=$(uname -m) - fi -@@ -606,6 +608,9 @@ case "$cpu" in - aarch64) - cpu="aarch64" - ;; -+ loongarch64) -+ cpu="loongarch64" -+ ;; - mips*) - cpu="mips" - ;; -diff --git a/meson.build b/meson.build -index c0fb5788f..c5fdb7856 100644 ---- a/meson.build -+++ b/meson.build -@@ -361,6 +361,8 @@ if not get_option('tcg').disabled() - tcg_arch = 'i386' - elif config_host['ARCH'] == 'ppc64' - tcg_arch = 'ppc' -+ elif config_host['ARCH'] == 'loongarch64' -+ tcg_arch = 'loongarch64' - endif - add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch, - language: ['c', 'cpp', 'objc']) -diff --git a/pc-bios/meson.build b/pc-bios/meson.build -index a09ca4d03..60009bd89 100644 ---- a/pc-bios/meson.build -+++ b/pc-bios/meson.build -@@ -84,6 +84,7 @@ blobs = files( - 'opensbi-riscv64-generic-fw_dynamic.elf', - 'npcm7xx_bootrom.bin', - 'loongarch_bios.bin', -+ 'loongarch_vars.bin', - ) - - if get_option('install_blobs') -diff --git a/tcg/loongarch64/tcg-insn-defs.c.inc b/tcg/loongarch64/tcg-insn-defs.c.inc -new file mode 100644 -index 000000000..d16257185 ---- /dev/null -+++ b/tcg/loongarch64/tcg-insn-defs.c.inc -@@ -0,0 +1,979 @@ -+/* SPDX-License-Identifier: MIT */ -+/* -+ * LoongArch instruction formats, opcodes, and encoders for TCG use. -+ * -+ * This file is auto-generated by genqemutcgdefs from -+ * https://github.com/loongson-community/loongarch-opcodes, -+ * from commit 961f0c60f5b63e574d785995600c71ad5413fdc4. -+ * DO NOT EDIT. -+ */ -+ -+typedef enum { -+ OPC_CLZ_W = 0x00001400, -+ OPC_CTZ_W = 0x00001c00, -+ OPC_CLZ_D = 0x00002400, -+ OPC_CTZ_D = 0x00002c00, -+ OPC_REVB_2H = 0x00003000, -+ OPC_REVB_2W = 0x00003800, -+ OPC_REVB_D = 0x00003c00, -+ OPC_SEXT_H = 0x00005800, -+ OPC_SEXT_B = 0x00005c00, -+ OPC_ADD_W = 0x00100000, -+ OPC_ADD_D = 0x00108000, -+ OPC_SUB_W = 0x00110000, -+ OPC_SUB_D = 0x00118000, -+ OPC_SLT = 0x00120000, -+ OPC_SLTU = 0x00128000, -+ OPC_MASKEQZ = 0x00130000, -+ OPC_MASKNEZ = 0x00138000, -+ OPC_NOR = 0x00140000, -+ OPC_AND = 0x00148000, -+ OPC_OR = 0x00150000, -+ OPC_XOR = 0x00158000, -+ OPC_ORN = 0x00160000, -+ OPC_ANDN = 0x00168000, -+ OPC_SLL_W = 0x00170000, -+ OPC_SRL_W = 0x00178000, -+ OPC_SRA_W = 0x00180000, -+ OPC_SLL_D = 0x00188000, -+ OPC_SRL_D = 0x00190000, -+ OPC_SRA_D = 0x00198000, -+ OPC_ROTR_W = 0x001b0000, -+ OPC_ROTR_D = 0x001b8000, -+ OPC_MUL_W = 0x001c0000, -+ OPC_MULH_W = 0x001c8000, -+ OPC_MULH_WU = 0x001d0000, -+ OPC_MUL_D = 0x001d8000, -+ OPC_MULH_D = 0x001e0000, -+ OPC_MULH_DU = 0x001e8000, -+ OPC_DIV_W = 0x00200000, -+ OPC_MOD_W = 0x00208000, -+ OPC_DIV_WU = 0x00210000, -+ OPC_MOD_WU = 0x00218000, -+ OPC_DIV_D = 0x00220000, -+ OPC_MOD_D = 0x00228000, -+ OPC_DIV_DU = 0x00230000, -+ OPC_MOD_DU = 0x00238000, -+ OPC_SLLI_W = 0x00408000, -+ OPC_SLLI_D = 0x00410000, -+ OPC_SRLI_W = 0x00448000, -+ OPC_SRLI_D = 0x00450000, -+ OPC_SRAI_W = 0x00488000, -+ OPC_SRAI_D = 0x00490000, -+ OPC_ROTRI_W = 0x004c8000, -+ OPC_ROTRI_D = 0x004d0000, -+ OPC_BSTRINS_W = 0x00600000, -+ OPC_BSTRPICK_W = 0x00608000, -+ OPC_BSTRINS_D = 0x00800000, -+ OPC_BSTRPICK_D = 0x00c00000, -+ OPC_SLTI = 0x02000000, -+ OPC_SLTUI = 0x02400000, -+ OPC_ADDI_W = 0x02800000, -+ OPC_ADDI_D = 0x02c00000, -+ OPC_CU52I_D = 0x03000000, -+ OPC_ANDI = 0x03400000, -+ OPC_ORI = 0x03800000, -+ OPC_XORI = 0x03c00000, -+ OPC_LU12I_W = 0x14000000, -+ OPC_CU32I_D = 0x16000000, -+ OPC_PCADDU2I = 0x18000000, -+ OPC_PCALAU12I = 0x1a000000, -+ OPC_PCADDU12I = 0x1c000000, -+ OPC_PCADDU18I = 0x1e000000, -+ OPC_LD_B = 0x28000000, -+ OPC_LD_H = 0x28400000, -+ OPC_LD_W = 0x28800000, -+ OPC_LD_D = 0x28c00000, -+ OPC_ST_B = 0x29000000, -+ OPC_ST_H = 0x29400000, -+ OPC_ST_W = 0x29800000, -+ OPC_ST_D = 0x29c00000, -+ OPC_LD_BU = 0x2a000000, -+ OPC_LD_HU = 0x2a400000, -+ OPC_LD_WU = 0x2a800000, -+ OPC_LDX_B = 0x38000000, -+ OPC_LDX_H = 0x38040000, -+ OPC_LDX_W = 0x38080000, -+ OPC_LDX_D = 0x380c0000, -+ OPC_STX_B = 0x38100000, -+ OPC_STX_H = 0x38140000, -+ OPC_STX_W = 0x38180000, -+ OPC_STX_D = 0x381c0000, -+ OPC_LDX_BU = 0x38200000, -+ OPC_LDX_HU = 0x38240000, -+ OPC_LDX_WU = 0x38280000, -+ OPC_DBAR = 0x38720000, -+ OPC_JIRL = 0x4c000000, -+ OPC_B = 0x50000000, -+ OPC_BL = 0x54000000, -+ OPC_BEQ = 0x58000000, -+ OPC_BNE = 0x5c000000, -+ OPC_BGT = 0x60000000, -+ OPC_BLE = 0x64000000, -+ OPC_BGTU = 0x68000000, -+ OPC_BLEU = 0x6c000000, -+} LoongArchInsn; -+ -+static int32_t __attribute__((unused)) -+encode_d_slot(LoongArchInsn opc, uint32_t d) -+{ -+ return opc | d; -+} -+ -+static int32_t __attribute__((unused)) -+encode_dj_slots(LoongArchInsn opc, uint32_t d, uint32_t j) -+{ -+ return opc | d | j << 5; -+} -+ -+static int32_t __attribute__((unused)) -+encode_djk_slots(LoongArchInsn opc, uint32_t d, uint32_t j, uint32_t k) -+{ -+ return opc | d | j << 5 | k << 10; -+} -+ -+static int32_t __attribute__((unused)) -+encode_djkm_slots(LoongArchInsn opc, uint32_t d, uint32_t j, uint32_t k, -+ uint32_t m) -+{ -+ return opc | d | j << 5 | k << 10 | m << 16; -+} -+ -+static int32_t __attribute__((unused)) -+encode_dk_slots(LoongArchInsn opc, uint32_t d, uint32_t k) -+{ -+ return opc | d | k << 10; -+} -+ -+static int32_t __attribute__((unused)) -+encode_dj_insn(LoongArchInsn opc, TCGReg d, TCGReg j) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ return encode_dj_slots(opc, d, j); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djk_insn(LoongArchInsn opc, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(k >= 0 && k <= 0x1f); -+ return encode_djk_slots(opc, d, j, k); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djsk12_insn(LoongArchInsn opc, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(sk12 >= -0x800 && sk12 <= 0x7ff); -+ return encode_djk_slots(opc, d, j, sk12 & 0xfff); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djsk16_insn(LoongArchInsn opc, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(sk16 >= -0x8000 && sk16 <= 0x7fff); -+ return encode_djk_slots(opc, d, j, sk16 & 0xffff); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djuk12_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk12) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(uk12 <= 0xfff); -+ return encode_djk_slots(opc, d, j, uk12); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djuk5_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk5) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(uk5 <= 0x1f); -+ return encode_djk_slots(opc, d, j, uk5); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djuk5um5_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk5, -+ uint32_t um5) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(uk5 <= 0x1f); -+ tcg_debug_assert(um5 <= 0x1f); -+ return encode_djkm_slots(opc, d, j, uk5, um5); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djuk6_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk6) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(uk6 <= 0x3f); -+ return encode_djk_slots(opc, d, j, uk6); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djuk6um6_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk6, -+ uint32_t um6) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(uk6 <= 0x3f); -+ tcg_debug_assert(um6 <= 0x3f); -+ return encode_djkm_slots(opc, d, j, uk6, um6); -+} -+ -+static int32_t __attribute__((unused)) -+encode_dsj20_insn(LoongArchInsn opc, TCGReg d, int32_t sj20) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(sj20 >= -0x80000 && sj20 <= 0x7ffff); -+ return encode_dj_slots(opc, d, sj20 & 0xfffff); -+} -+ -+static int32_t __attribute__((unused)) -+encode_sd10k16_insn(LoongArchInsn opc, int32_t sd10k16) -+{ -+ tcg_debug_assert(sd10k16 >= -0x2000000 && sd10k16 <= 0x1ffffff); -+ return encode_dk_slots(opc, (sd10k16 >> 16) & 0x3ff, sd10k16 & 0xffff); -+} -+ -+static int32_t __attribute__((unused)) -+encode_ud15_insn(LoongArchInsn opc, uint32_t ud15) -+{ -+ tcg_debug_assert(ud15 <= 0x7fff); -+ return encode_d_slot(opc, ud15); -+} -+ -+/* Emits the `clz.w d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_clz_w(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_CLZ_W, d, j)); -+} -+ -+/* Emits the `ctz.w d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ctz_w(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_CTZ_W, d, j)); -+} -+ -+/* Emits the `clz.d d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_clz_d(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_CLZ_D, d, j)); -+} -+ -+/* Emits the `ctz.d d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ctz_d(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_CTZ_D, d, j)); -+} -+ -+/* Emits the `revb.2h d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_revb_2h(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_REVB_2H, d, j)); -+} -+ -+/* Emits the `revb.2w d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_revb_2w(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_REVB_2W, d, j)); -+} -+ -+/* Emits the `revb.d d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_revb_d(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_REVB_D, d, j)); -+} -+ -+/* Emits the `sext.h d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sext_h(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_SEXT_H, d, j)); -+} -+ -+/* Emits the `sext.b d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sext_b(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_SEXT_B, d, j)); -+} -+ -+/* Emits the `add.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_add_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_ADD_W, d, j, k)); -+} -+ -+/* Emits the `add.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_add_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_ADD_D, d, j, k)); -+} -+ -+/* Emits the `sub.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sub_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SUB_W, d, j, k)); -+} -+ -+/* Emits the `sub.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sub_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SUB_D, d, j, k)); -+} -+ -+/* Emits the `slt d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_slt(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SLT, d, j, k)); -+} -+ -+/* Emits the `sltu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sltu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SLTU, d, j, k)); -+} -+ -+/* Emits the `maskeqz d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_maskeqz(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MASKEQZ, d, j, k)); -+} -+ -+/* Emits the `masknez d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_masknez(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MASKNEZ, d, j, k)); -+} -+ -+/* Emits the `nor d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_nor(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_NOR, d, j, k)); -+} -+ -+/* Emits the `and d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_and(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_AND, d, j, k)); -+} -+ -+/* Emits the `or d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_or(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_OR, d, j, k)); -+} -+ -+/* Emits the `xor d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_xor(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_XOR, d, j, k)); -+} -+ -+/* Emits the `orn d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_orn(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_ORN, d, j, k)); -+} -+ -+/* Emits the `andn d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_andn(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_ANDN, d, j, k)); -+} -+ -+/* Emits the `sll.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sll_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SLL_W, d, j, k)); -+} -+ -+/* Emits the `srl.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_srl_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SRL_W, d, j, k)); -+} -+ -+/* Emits the `sra.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sra_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SRA_W, d, j, k)); -+} -+ -+/* Emits the `sll.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sll_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SLL_D, d, j, k)); -+} -+ -+/* Emits the `srl.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_srl_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SRL_D, d, j, k)); -+} -+ -+/* Emits the `sra.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sra_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SRA_D, d, j, k)); -+} -+ -+/* Emits the `rotr.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_rotr_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_ROTR_W, d, j, k)); -+} -+ -+/* Emits the `rotr.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_rotr_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_ROTR_D, d, j, k)); -+} -+ -+/* Emits the `mul.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mul_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MUL_W, d, j, k)); -+} -+ -+/* Emits the `mulh.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mulh_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MULH_W, d, j, k)); -+} -+ -+/* Emits the `mulh.wu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mulh_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MULH_WU, d, j, k)); -+} -+ -+/* Emits the `mul.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mul_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MUL_D, d, j, k)); -+} -+ -+/* Emits the `mulh.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mulh_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MULH_D, d, j, k)); -+} -+ -+/* Emits the `mulh.du d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mulh_du(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MULH_DU, d, j, k)); -+} -+ -+/* Emits the `div.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_div_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_DIV_W, d, j, k)); -+} -+ -+/* Emits the `mod.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mod_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MOD_W, d, j, k)); -+} -+ -+/* Emits the `div.wu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_div_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_DIV_WU, d, j, k)); -+} -+ -+/* Emits the `mod.wu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mod_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MOD_WU, d, j, k)); -+} -+ -+/* Emits the `div.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_div_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_DIV_D, d, j, k)); -+} -+ -+/* Emits the `mod.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mod_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MOD_D, d, j, k)); -+} -+ -+/* Emits the `div.du d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_div_du(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_DIV_DU, d, j, k)); -+} -+ -+/* Emits the `mod.du d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mod_du(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MOD_DU, d, j, k)); -+} -+ -+/* Emits the `slli.w d, j, uk5` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_slli_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) -+{ -+ tcg_out32(s, encode_djuk5_insn(OPC_SLLI_W, d, j, uk5)); -+} -+ -+/* Emits the `slli.d d, j, uk6` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_slli_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) -+{ -+ tcg_out32(s, encode_djuk6_insn(OPC_SLLI_D, d, j, uk6)); -+} -+ -+/* Emits the `srli.w d, j, uk5` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_srli_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) -+{ -+ tcg_out32(s, encode_djuk5_insn(OPC_SRLI_W, d, j, uk5)); -+} -+ -+/* Emits the `srli.d d, j, uk6` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_srli_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) -+{ -+ tcg_out32(s, encode_djuk6_insn(OPC_SRLI_D, d, j, uk6)); -+} -+ -+/* Emits the `srai.w d, j, uk5` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_srai_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) -+{ -+ tcg_out32(s, encode_djuk5_insn(OPC_SRAI_W, d, j, uk5)); -+} -+ -+/* Emits the `srai.d d, j, uk6` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_srai_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) -+{ -+ tcg_out32(s, encode_djuk6_insn(OPC_SRAI_D, d, j, uk6)); -+} -+ -+/* Emits the `rotri.w d, j, uk5` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_rotri_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) -+{ -+ tcg_out32(s, encode_djuk5_insn(OPC_ROTRI_W, d, j, uk5)); -+} -+ -+/* Emits the `rotri.d d, j, uk6` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_rotri_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) -+{ -+ tcg_out32(s, encode_djuk6_insn(OPC_ROTRI_D, d, j, uk6)); -+} -+ -+/* Emits the `bstrins.w d, j, uk5, um5` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bstrins_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5, -+ uint32_t um5) -+{ -+ tcg_out32(s, encode_djuk5um5_insn(OPC_BSTRINS_W, d, j, uk5, um5)); -+} -+ -+/* Emits the `bstrpick.w d, j, uk5, um5` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bstrpick_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5, -+ uint32_t um5) -+{ -+ tcg_out32(s, encode_djuk5um5_insn(OPC_BSTRPICK_W, d, j, uk5, um5)); -+} -+ -+/* Emits the `bstrins.d d, j, uk6, um6` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bstrins_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6, -+ uint32_t um6) -+{ -+ tcg_out32(s, encode_djuk6um6_insn(OPC_BSTRINS_D, d, j, uk6, um6)); -+} -+ -+/* Emits the `bstrpick.d d, j, uk6, um6` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bstrpick_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6, -+ uint32_t um6) -+{ -+ tcg_out32(s, encode_djuk6um6_insn(OPC_BSTRPICK_D, d, j, uk6, um6)); -+} -+ -+/* Emits the `slti d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_slti(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_SLTI, d, j, sk12)); -+} -+ -+/* Emits the `sltui d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sltui(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_SLTUI, d, j, sk12)); -+} -+ -+/* Emits the `addi.w d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_addi_w(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_ADDI_W, d, j, sk12)); -+} -+ -+/* Emits the `addi.d d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_addi_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_ADDI_D, d, j, sk12)); -+} -+ -+/* Emits the `cu52i.d d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_cu52i_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_CU52I_D, d, j, sk12)); -+} -+ -+/* Emits the `andi d, j, uk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_andi(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12) -+{ -+ tcg_out32(s, encode_djuk12_insn(OPC_ANDI, d, j, uk12)); -+} -+ -+/* Emits the `ori d, j, uk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ori(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12) -+{ -+ tcg_out32(s, encode_djuk12_insn(OPC_ORI, d, j, uk12)); -+} -+ -+/* Emits the `xori d, j, uk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_xori(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12) -+{ -+ tcg_out32(s, encode_djuk12_insn(OPC_XORI, d, j, uk12)); -+} -+ -+/* Emits the `lu12i.w d, sj20` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_lu12i_w(TCGContext *s, TCGReg d, int32_t sj20) -+{ -+ tcg_out32(s, encode_dsj20_insn(OPC_LU12I_W, d, sj20)); -+} -+ -+/* Emits the `cu32i.d d, sj20` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_cu32i_d(TCGContext *s, TCGReg d, int32_t sj20) -+{ -+ tcg_out32(s, encode_dsj20_insn(OPC_CU32I_D, d, sj20)); -+} -+ -+/* Emits the `pcaddu2i d, sj20` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_pcaddu2i(TCGContext *s, TCGReg d, int32_t sj20) -+{ -+ tcg_out32(s, encode_dsj20_insn(OPC_PCADDU2I, d, sj20)); -+} -+ -+/* Emits the `pcalau12i d, sj20` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_pcalau12i(TCGContext *s, TCGReg d, int32_t sj20) -+{ -+ tcg_out32(s, encode_dsj20_insn(OPC_PCALAU12I, d, sj20)); -+} -+ -+/* Emits the `pcaddu12i d, sj20` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_pcaddu12i(TCGContext *s, TCGReg d, int32_t sj20) -+{ -+ tcg_out32(s, encode_dsj20_insn(OPC_PCADDU12I, d, sj20)); -+} -+ -+/* Emits the `pcaddu18i d, sj20` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_pcaddu18i(TCGContext *s, TCGReg d, int32_t sj20) -+{ -+ tcg_out32(s, encode_dsj20_insn(OPC_PCADDU18I, d, sj20)); -+} -+ -+/* Emits the `ld.b d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_b(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_B, d, j, sk12)); -+} -+ -+/* Emits the `ld.h d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_h(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_H, d, j, sk12)); -+} -+ -+/* Emits the `ld.w d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_w(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_W, d, j, sk12)); -+} -+ -+/* Emits the `ld.d d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_D, d, j, sk12)); -+} -+ -+/* Emits the `st.b d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_st_b(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_ST_B, d, j, sk12)); -+} -+ -+/* Emits the `st.h d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_st_h(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_ST_H, d, j, sk12)); -+} -+ -+/* Emits the `st.w d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_st_w(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_ST_W, d, j, sk12)); -+} -+ -+/* Emits the `st.d d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_st_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_ST_D, d, j, sk12)); -+} -+ -+/* Emits the `ld.bu d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_bu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_BU, d, j, sk12)); -+} -+ -+/* Emits the `ld.hu d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_hu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_HU, d, j, sk12)); -+} -+ -+/* Emits the `ld.wu d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_wu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_WU, d, j, sk12)); -+} -+ -+/* Emits the `ldx.b d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_b(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_B, d, j, k)); -+} -+ -+/* Emits the `ldx.h d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_h(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_H, d, j, k)); -+} -+ -+/* Emits the `ldx.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_W, d, j, k)); -+} -+ -+/* Emits the `ldx.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_D, d, j, k)); -+} -+ -+/* Emits the `stx.b d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_stx_b(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_STX_B, d, j, k)); -+} -+ -+/* Emits the `stx.h d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_stx_h(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_STX_H, d, j, k)); -+} -+ -+/* Emits the `stx.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_stx_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_STX_W, d, j, k)); -+} -+ -+/* Emits the `stx.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_stx_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_STX_D, d, j, k)); -+} -+ -+/* Emits the `ldx.bu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_bu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_BU, d, j, k)); -+} -+ -+/* Emits the `ldx.hu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_hu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_HU, d, j, k)); -+} -+ -+/* Emits the `ldx.wu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_WU, d, j, k)); -+} -+ -+/* Emits the `dbar ud15` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_dbar(TCGContext *s, uint32_t ud15) -+{ -+ tcg_out32(s, encode_ud15_insn(OPC_DBAR, ud15)); -+} -+ -+/* Emits the `jirl d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_jirl(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_JIRL, d, j, sk16)); -+} -+ -+/* Emits the `b sd10k16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_b(TCGContext *s, int32_t sd10k16) -+{ -+ tcg_out32(s, encode_sd10k16_insn(OPC_B, sd10k16)); -+} -+ -+/* Emits the `bl sd10k16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bl(TCGContext *s, int32_t sd10k16) -+{ -+ tcg_out32(s, encode_sd10k16_insn(OPC_BL, sd10k16)); -+} -+ -+/* Emits the `beq d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_beq(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_BEQ, d, j, sk16)); -+} -+ -+/* Emits the `bne d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bne(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_BNE, d, j, sk16)); -+} -+ -+/* Emits the `bgt d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bgt(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_BGT, d, j, sk16)); -+} -+ -+/* Emits the `ble d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ble(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_BLE, d, j, sk16)); -+} -+ -+/* Emits the `bgtu d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bgtu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_BGTU, d, j, sk16)); -+} -+ -+/* Emits the `bleu d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bleu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_BLEU, d, j, sk16)); -+} -+ -+/* End of generated code. */ -diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h -new file mode 100644 -index 000000000..349c67268 ---- /dev/null -+++ b/tcg/loongarch64/tcg-target-con-set.h -@@ -0,0 +1,31 @@ -+/* SPDX-License-Identifier: MIT */ -+/* -+ * Define LoongArch target-specific constraint sets. -+ * -+ * Copyright (c) 2021 WANG Xuerui -+ * -+ * Based on tcg/riscv/tcg-target-con-set.h -+ * -+ * Copyright (c) 2021 Linaro -+ */ -+ -+/* -+ * C_On_Im(...) defines a constraint set with outputs and inputs. -+ * Each operand should be a sequence of constraint letters as defined by -+ * tcg-target-con-str.h; the constraint combination is inclusive or. -+ */ -+C_O0_I1(r) -+C_O0_I2(rZ, r) -+C_O0_I2(rZ, rZ) -+C_O0_I2(LZ, L) -+C_O1_I1(r, r) -+C_O1_I1(r, L) -+C_O1_I2(r, r, rC) -+C_O1_I2(r, r, ri) -+C_O1_I2(r, r, rI) -+C_O1_I2(r, r, rU) -+C_O1_I2(r, r, rW) -+C_O1_I2(r, r, rZ) -+C_O1_I2(r, 0, rZ) -+C_O1_I2(r, rZ, rN) -+C_O1_I2(r, rZ, rZ) -diff --git a/tcg/loongarch64/tcg-target-con-str.h b/tcg/loongarch64/tcg-target-con-str.h -new file mode 100644 -index 000000000..c3986a4fd ---- /dev/null -+++ b/tcg/loongarch64/tcg-target-con-str.h -@@ -0,0 +1,28 @@ -+/* SPDX-License-Identifier: MIT */ -+/* -+ * Define LoongArch target-specific operand constraints. -+ * -+ * Copyright (c) 2021 WANG Xuerui -+ * -+ * Based on tcg/riscv/tcg-target-con-str.h -+ * -+ * Copyright (c) 2021 Linaro -+ */ -+ -+/* -+ * Define constraint letters for register sets: -+ * REGS(letter, register_mask) -+ */ -+REGS('r', ALL_GENERAL_REGS) -+REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS) -+ -+/* -+ * Define constraint letters for constants: -+ * CONST(letter, TCG_CT_CONST_* bit set) -+ */ -+CONST('I', TCG_CT_CONST_S12) -+CONST('N', TCG_CT_CONST_N12) -+CONST('U', TCG_CT_CONST_U12) -+CONST('Z', TCG_CT_CONST_ZERO) -+CONST('C', TCG_CT_CONST_C12) -+CONST('W', TCG_CT_CONST_WSZ) -diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc -new file mode 100644 -index 000000000..9b53549ed ---- /dev/null -+++ b/tcg/loongarch64/tcg-target.c.inc -@@ -0,0 +1,1744 @@ -+/* -+ * Tiny Code Generator for QEMU -+ * -+ * Copyright (c) 2021 WANG Xuerui -+ * -+ * Based on tcg/riscv/tcg-target.c.inc -+ * -+ * Copyright (c) 2018 SiFive, Inc -+ * Copyright (c) 2008-2009 Arnaud Patard -+ * Copyright (c) 2009 Aurelien Jarno -+ * Copyright (c) 2008 Fabrice Bellard -+ * -+ * 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 "../tcg-ldst.c.inc" -+ -+#ifdef CONFIG_DEBUG_TCG -+static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { -+ "zero", -+ "ra", -+ "tp", -+ "sp", -+ "a0", -+ "a1", -+ "a2", -+ "a3", -+ "a4", -+ "a5", -+ "a6", -+ "a7", -+ "t0", -+ "t1", -+ "t2", -+ "t3", -+ "t4", -+ "t5", -+ "t6", -+ "t7", -+ "t8", -+ "r21", /* reserved in the LP64* ABI, hence no ABI name */ -+ "s9", -+ "s0", -+ "s1", -+ "s2", -+ "s3", -+ "s4", -+ "s5", -+ "s6", -+ "s7", -+ "s8" -+}; -+#endif -+ -+static const int tcg_target_reg_alloc_order[] = { -+ /* Registers preserved across calls */ -+ /* TCG_REG_S0 reserved for TCG_AREG0 */ -+ TCG_REG_S1, -+ TCG_REG_S2, -+ TCG_REG_S3, -+ TCG_REG_S4, -+ TCG_REG_S5, -+ TCG_REG_S6, -+ TCG_REG_S7, -+ TCG_REG_S8, -+ TCG_REG_S9, -+ -+ /* Registers (potentially) clobbered across calls */ -+ TCG_REG_T0, -+ TCG_REG_T1, -+ TCG_REG_T2, -+ TCG_REG_T3, -+ TCG_REG_T4, -+ TCG_REG_T5, -+ TCG_REG_T6, -+ TCG_REG_T7, -+ TCG_REG_T8, -+ -+ /* Argument registers, opposite order of allocation. */ -+ TCG_REG_A7, -+ TCG_REG_A6, -+ TCG_REG_A5, -+ TCG_REG_A4, -+ TCG_REG_A3, -+ TCG_REG_A2, -+ TCG_REG_A1, -+ TCG_REG_A0, -+}; -+ -+static const int tcg_target_call_iarg_regs[] = { -+ TCG_REG_A0, -+ TCG_REG_A1, -+ TCG_REG_A2, -+ TCG_REG_A3, -+ TCG_REG_A4, -+ TCG_REG_A5, -+ TCG_REG_A6, -+ TCG_REG_A7, -+}; -+ -+static const int tcg_target_call_oarg_regs[] = { -+ TCG_REG_A0, -+ TCG_REG_A1, -+}; -+ -+#ifndef CONFIG_SOFTMMU -+#define USE_GUEST_BASE (guest_base != 0) -+#define TCG_GUEST_BASE_REG TCG_REG_S1 -+#endif -+ -+#define TCG_CT_CONST_ZERO 0x100 -+#define TCG_CT_CONST_S12 0x200 -+#define TCG_CT_CONST_N12 0x400 -+#define TCG_CT_CONST_U12 0x800 -+#define TCG_CT_CONST_C12 0x1000 -+#define TCG_CT_CONST_WSZ 0x2000 -+ -+#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32) -+/* -+ * For softmmu, we need to avoid conflicts with the first 5 -+ * argument registers to call the helper. Some of these are -+ * also used for the tlb lookup. -+ */ -+#ifdef CONFIG_SOFTMMU -+#define SOFTMMU_RESERVE_REGS MAKE_64BIT_MASK(TCG_REG_A0, 5) -+#else -+#define SOFTMMU_RESERVE_REGS 0 -+#endif -+ -+ -+static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len) -+{ -+ return sextract64(val, pos, len); -+} -+ -+/* test if a constant matches the constraint */ -+static bool tcg_target_const_match(int64_t val, TCGType type, int ct) -+{ -+ if (ct & TCG_CT_CONST) { -+ return true; -+ } -+ if ((ct & TCG_CT_CONST_ZERO) && val == 0) { -+ return true; -+ } -+ if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) { -+ return true; -+ } -+ if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) { -+ return true; -+ } -+ if ((ct & TCG_CT_CONST_U12) && val >= 0 && val <= 0xfff) { -+ return true; -+ } -+ if ((ct & TCG_CT_CONST_C12) && ~val >= 0 && ~val <= 0xfff) { -+ return true; -+ } -+ if ((ct & TCG_CT_CONST_WSZ) && val == (type == TCG_TYPE_I32 ? 32 : 64)) { -+ return true; -+ } -+ return false; -+} -+ -+/* -+ * Relocations -+ */ -+ -+/* -+ * Relocation records defined in LoongArch ELF psABI v1.00 is way too -+ * complicated; a whopping stack machine is needed to stuff the fields, at -+ * the very least one SOP_PUSH and one SOP_POP (of the correct format) are -+ * needed. -+ * -+ * Hence, define our own simpler relocation types. Numbers are chosen as to -+ * not collide with potential future additions to the true ELF relocation -+ * type enum. -+ */ -+ -+/* Field Sk16, shifted right by 2; suitable for conditional jumps */ -+#define R_LOONGARCH_BR_SK16 256 -+/* Field Sd10k16, shifted right by 2; suitable for B and BL */ -+#define R_LOONGARCH_BR_SD10K16 257 -+ -+static bool reloc_br_sk16(tcg_insn_unit *src_rw, const tcg_insn_unit *target) -+{ -+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); -+ intptr_t offset = (intptr_t)target - (intptr_t)src_rx; -+ -+ tcg_debug_assert((offset & 3) == 0); -+ offset >>= 2; -+ if (offset == sextreg(offset, 0, 16)) { -+ *src_rw = deposit64(*src_rw, 10, 16, offset); -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool reloc_br_sd10k16(tcg_insn_unit *src_rw, -+ const tcg_insn_unit *target) -+{ -+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); -+ intptr_t offset = (intptr_t)target - (intptr_t)src_rx; -+ -+ tcg_debug_assert((offset & 3) == 0); -+ offset >>= 2; -+ if (offset == sextreg(offset, 0, 26)) { -+ *src_rw = deposit64(*src_rw, 0, 10, offset >> 16); /* slot d10 */ -+ *src_rw = deposit64(*src_rw, 10, 16, offset); /* slot k16 */ -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool patch_reloc(tcg_insn_unit *code_ptr, int type, -+ intptr_t value, intptr_t addend) -+{ -+ tcg_debug_assert(addend == 0); -+ switch (type) { -+ case R_LOONGARCH_BR_SK16: -+ return reloc_br_sk16(code_ptr, (tcg_insn_unit *)value); -+ case R_LOONGARCH_BR_SD10K16: -+ return reloc_br_sd10k16(code_ptr, (tcg_insn_unit *)value); -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+#include "tcg-insn-defs.c.inc" -+ -+/* -+ * TCG intrinsics -+ */ -+ -+static void tcg_out_mb(TCGContext *s, TCGArg a0) -+{ -+ /* Baseline LoongArch only has the full barrier, unfortunately. */ -+ tcg_out_opc_dbar(s, 0); -+} -+ -+static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) -+{ -+ if (ret == arg) { -+ return true; -+ } -+ switch (type) { -+ case TCG_TYPE_I32: -+ case TCG_TYPE_I64: -+ /* -+ * Conventional register-register move used in LoongArch is -+ * `or dst, src, zero`. -+ */ -+ tcg_out_opc_or(s, ret, arg, TCG_REG_ZERO); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+ return true; -+} -+ -+static bool imm_part_needs_loading(bool high_bits_are_ones, -+ tcg_target_long part) -+{ -+ if (high_bits_are_ones) { -+ return part != -1; -+ } else { -+ return part != 0; -+ } -+} -+ -+/* Loads a 32-bit immediate into rd, sign-extended. */ -+static void tcg_out_movi_i32(TCGContext *s, TCGReg rd, int32_t val) -+{ -+ tcg_target_long lo = sextreg(val, 0, 12); -+ tcg_target_long hi12 = sextreg(val, 12, 20); -+ -+ /* Single-instruction cases. */ -+ if (lo == val) { -+ /* val fits in simm12: addi.w rd, zero, val */ -+ tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val); -+ return; -+ } -+ if (0x800 <= val && val <= 0xfff) { -+ /* val fits in uimm12: ori rd, zero, val */ -+ tcg_out_opc_ori(s, rd, TCG_REG_ZERO, val); -+ return; -+ } -+ -+ /* High bits must be set; load with lu12i.w + optional ori. */ -+ tcg_out_opc_lu12i_w(s, rd, hi12); -+ if (lo != 0) { -+ tcg_out_opc_ori(s, rd, rd, lo & 0xfff); -+ } -+} -+ -+static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, -+ tcg_target_long val) -+{ -+ /* -+ * LoongArch conventionally loads 64-bit immediates in at most 4 steps, -+ * with dedicated instructions for filling the respective bitfields -+ * below: -+ * -+ * 6 5 4 3 -+ * 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 -+ * +-----------------------+---------------------------------------+... -+ * | hi52 | hi32 | -+ * +-----------------------+---------------------------------------+... -+ * 3 2 1 -+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -+ * ...+-------------------------------------+-------------------------+ -+ * | hi12 | lo | -+ * ...+-------------------------------------+-------------------------+ -+ * -+ * Check if val belong to one of the several fast cases, before falling -+ * back to the slow path. -+ */ -+ -+ intptr_t pc_offset; -+ tcg_target_long val_lo, val_hi, pc_hi, offset_hi; -+ tcg_target_long hi32, hi52; -+ bool rd_high_bits_are_ones; -+ -+ /* Value fits in signed i32. */ -+ if (type == TCG_TYPE_I32 || val == (int32_t)val) { -+ tcg_out_movi_i32(s, rd, val); -+ return; -+ } -+ -+ /* PC-relative cases. */ -+ pc_offset = tcg_pcrel_diff(s, (void *)val); -+ if (pc_offset == sextreg(pc_offset, 0, 22) && (pc_offset & 3) == 0) { -+ /* Single pcaddu2i. */ -+ tcg_out_opc_pcaddu2i(s, rd, pc_offset >> 2); -+ return; -+ } -+ -+ if (pc_offset == (int32_t)pc_offset) { -+ /* Offset within 32 bits; load with pcalau12i + ori. */ -+ val_lo = sextreg(val, 0, 12); -+ val_hi = val >> 12; -+ pc_hi = (val - pc_offset) >> 12; -+ offset_hi = val_hi - pc_hi; -+ -+ tcg_debug_assert(offset_hi == sextreg(offset_hi, 0, 20)); -+ tcg_out_opc_pcalau12i(s, rd, offset_hi); -+ if (val_lo != 0) { -+ tcg_out_opc_ori(s, rd, rd, val_lo & 0xfff); -+ } -+ return; -+ } -+ -+ hi32 = sextreg(val, 32, 20); -+ hi52 = sextreg(val, 52, 12); -+ -+ /* Single cu52i.d case. */ -+ if (ctz64(val) >= 52) { -+ tcg_out_opc_cu52i_d(s, rd, TCG_REG_ZERO, hi52); -+ return; -+ } -+ -+ /* Slow path. Initialize the low 32 bits, then concat high bits. */ -+ tcg_out_movi_i32(s, rd, val); -+ rd_high_bits_are_ones = (int32_t)val < 0; -+ -+ if (imm_part_needs_loading(rd_high_bits_are_ones, hi32)) { -+ tcg_out_opc_cu32i_d(s, rd, hi32); -+ rd_high_bits_are_ones = hi32 < 0; -+ } -+ -+ if (imm_part_needs_loading(rd_high_bits_are_ones, hi52)) { -+ tcg_out_opc_cu52i_d(s, rd, rd, hi52); -+ } -+} -+ -+static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg) -+{ -+ tcg_out_opc_andi(s, ret, arg, 0xff); -+} -+ -+static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg) -+{ -+ tcg_out_opc_bstrpick_w(s, ret, arg, 0, 15); -+} -+ -+static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg) -+{ -+ tcg_out_opc_bstrpick_d(s, ret, arg, 0, 31); -+} -+ -+static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg) -+{ -+ tcg_out_opc_sext_b(s, ret, arg); -+} -+ -+static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg) -+{ -+ tcg_out_opc_sext_h(s, ret, arg); -+} -+ -+static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg) -+{ -+ tcg_out_opc_addi_w(s, ret, arg, 0); -+} -+ -+static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc, -+ TCGReg a0, TCGReg a1, TCGReg a2, -+ bool c2, bool is_32bit) -+{ -+ if (c2) { -+ /* -+ * Fast path: semantics already satisfied due to constraint and -+ * insn behavior, single instruction is enough. -+ */ -+ tcg_debug_assert(a2 == (is_32bit ? 32 : 64)); -+ /* all clz/ctz insns belong to DJ-format */ -+ tcg_out32(s, encode_dj_insn(opc, a0, a1)); -+ return; -+ } -+ -+ tcg_out32(s, encode_dj_insn(opc, TCG_REG_TMP0, a1)); -+ /* a0 = a1 ? REG_TMP0 : a2 */ -+ tcg_out_opc_maskeqz(s, TCG_REG_TMP0, TCG_REG_TMP0, a1); -+ tcg_out_opc_masknez(s, a0, a2, a1); -+ tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0); -+} -+ -+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, -+ TCGReg arg1, TCGReg arg2, bool c2) -+{ -+ TCGReg tmp; -+ -+ if (c2) { -+ tcg_debug_assert(arg2 == 0); -+ } -+ -+ switch (cond) { -+ case TCG_COND_EQ: -+ if (c2) { -+ tmp = arg1; -+ } else { -+ tcg_out_opc_sub_d(s, ret, arg1, arg2); -+ tmp = ret; -+ } -+ tcg_out_opc_sltui(s, ret, tmp, 1); -+ break; -+ case TCG_COND_NE: -+ if (c2) { -+ tmp = arg1; -+ } else { -+ tcg_out_opc_sub_d(s, ret, arg1, arg2); -+ tmp = ret; -+ } -+ tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp); -+ break; -+ case TCG_COND_LT: -+ tcg_out_opc_slt(s, ret, arg1, arg2); -+ break; -+ case TCG_COND_GE: -+ tcg_out_opc_slt(s, ret, arg1, arg2); -+ tcg_out_opc_xori(s, ret, ret, 1); -+ break; -+ case TCG_COND_LE: -+ tcg_out_setcond(s, TCG_COND_GE, ret, arg2, arg1, false); -+ break; -+ case TCG_COND_GT: -+ tcg_out_setcond(s, TCG_COND_LT, ret, arg2, arg1, false); -+ break; -+ case TCG_COND_LTU: -+ tcg_out_opc_sltu(s, ret, arg1, arg2); -+ break; -+ case TCG_COND_GEU: -+ tcg_out_opc_sltu(s, ret, arg1, arg2); -+ tcg_out_opc_xori(s, ret, ret, 1); -+ break; -+ case TCG_COND_LEU: -+ tcg_out_setcond(s, TCG_COND_GEU, ret, arg2, arg1, false); -+ break; -+ case TCG_COND_GTU: -+ tcg_out_setcond(s, TCG_COND_LTU, ret, arg2, arg1, false); -+ break; -+ default: -+ g_assert_not_reached(); -+ break; -+ } -+} -+ -+/* -+ * Branch helpers -+ */ -+ -+static const struct { -+ LoongArchInsn op; -+ bool swap; -+} tcg_brcond_to_loongarch[] = { -+ [TCG_COND_EQ] = { OPC_BEQ, false }, -+ [TCG_COND_NE] = { OPC_BNE, false }, -+ [TCG_COND_LT] = { OPC_BGT, true }, -+ [TCG_COND_GE] = { OPC_BLE, true }, -+ [TCG_COND_LE] = { OPC_BLE, false }, -+ [TCG_COND_GT] = { OPC_BGT, false }, -+ [TCG_COND_LTU] = { OPC_BGTU, true }, -+ [TCG_COND_GEU] = { OPC_BLEU, true }, -+ [TCG_COND_LEU] = { OPC_BLEU, false }, -+ [TCG_COND_GTU] = { OPC_BGTU, false } -+}; -+ -+static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1, -+ TCGReg arg2, TCGLabel *l) -+{ -+ LoongArchInsn op = tcg_brcond_to_loongarch[cond].op; -+ -+ tcg_debug_assert(op != 0); -+ -+ if (tcg_brcond_to_loongarch[cond].swap) { -+ TCGReg t = arg1; -+ arg1 = arg2; -+ arg2 = t; -+ } -+ -+ /* all conditional branch insns belong to DJSk16-format */ -+ tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SK16, l, 0); -+ tcg_out32(s, encode_djsk16_insn(op, arg1, arg2, 0)); -+} -+ -+static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail) -+{ -+ TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA; -+ ptrdiff_t offset = tcg_pcrel_diff(s, arg); -+ -+ tcg_debug_assert((offset & 3) == 0); -+ if (offset == sextreg(offset, 0, 28)) { -+ /* short jump: +/- 256MiB */ -+ if (tail) { -+ tcg_out_opc_b(s, offset >> 2); -+ } else { -+ tcg_out_opc_bl(s, offset >> 2); -+ } -+ } else if (offset == sextreg(offset, 0, 38)) { -+ /* long jump: +/- 256GiB */ -+ tcg_target_long lo = sextreg(offset, 0, 18); -+ tcg_target_long hi = offset - lo; -+ tcg_out_opc_pcaddu18i(s, TCG_REG_TMP0, hi >> 18); -+ tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2); -+ } else { -+ /* far jump: 64-bit */ -+ tcg_target_long lo = sextreg((tcg_target_long)arg, 0, 18); -+ tcg_target_long hi = (tcg_target_long)arg - lo; -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, hi); -+ tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2); -+ } -+} -+ -+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg) -+{ -+ tcg_out_call_int(s, arg, false); -+} -+ -+/* -+ * Load/store helpers -+ */ -+ -+static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, TCGReg data, -+ TCGReg addr, intptr_t offset) -+{ -+ intptr_t imm12 = sextreg(offset, 0, 12); -+ -+ if (offset != imm12) { -+ intptr_t diff = offset - (uintptr_t)s->code_ptr; -+ -+ if (addr == TCG_REG_ZERO && diff == (int32_t)diff) { -+ imm12 = sextreg(diff, 0, 12); -+ tcg_out_opc_pcaddu12i(s, TCG_REG_TMP2, (diff - imm12) >> 12); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP2, offset - imm12); -+ if (addr != TCG_REG_ZERO) { -+ tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, addr); -+ } -+ } -+ addr = TCG_REG_TMP2; -+ } -+ -+ switch (opc) { -+ case OPC_LD_B: -+ case OPC_LD_BU: -+ case OPC_LD_H: -+ case OPC_LD_HU: -+ case OPC_LD_W: -+ case OPC_LD_WU: -+ case OPC_LD_D: -+ case OPC_ST_B: -+ case OPC_ST_H: -+ case OPC_ST_W: -+ case OPC_ST_D: -+ tcg_out32(s, encode_djsk12_insn(opc, data, addr, imm12)); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, -+ TCGReg arg1, intptr_t arg2) -+{ -+ bool is_32bit = type == TCG_TYPE_I32; -+ tcg_out_ldst(s, is_32bit ? OPC_LD_W : OPC_LD_D, arg, arg1, arg2); -+} -+ -+static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, -+ TCGReg arg1, intptr_t arg2) -+{ -+ bool is_32bit = type == TCG_TYPE_I32; -+ tcg_out_ldst(s, is_32bit ? OPC_ST_W : OPC_ST_D, arg, arg1, arg2); -+} -+ -+static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, -+ TCGReg base, intptr_t ofs) -+{ -+ if (val == 0) { -+ tcg_out_st(s, type, TCG_REG_ZERO, base, ofs); -+ return true; -+ } -+ return false; -+} -+ -+/* -+ * Load/store helpers for SoftMMU, and qemu_ld/st implementations -+ */ -+ -+#if defined(CONFIG_SOFTMMU) -+/* -+ * helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr, -+ * MemOpIdx oi, uintptr_t ra) -+ */ -+static void * const qemu_ld_helpers[4] = { -+ [MO_8] = helper_ret_ldub_mmu, -+ [MO_16] = helper_le_lduw_mmu, -+ [MO_32] = helper_le_ldul_mmu, -+ [MO_64] = helper_le_ldq_mmu, -+}; -+ -+/* -+ * helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr, -+ * uintxx_t val, MemOpIdx oi, -+ * uintptr_t ra) -+ */ -+static void * const qemu_st_helpers[4] = { -+ [MO_8] = helper_ret_stb_mmu, -+ [MO_16] = helper_le_stw_mmu, -+ [MO_32] = helper_le_stl_mmu, -+ [MO_64] = helper_le_stq_mmu, -+}; -+ -+/* We expect to use a 12-bit negative offset from ENV. */ -+QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0); -+QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11)); -+ -+static bool tcg_out_goto(TCGContext *s, const tcg_insn_unit *target) -+{ -+ tcg_out_opc_b(s, 0); -+ return reloc_br_sd10k16(s->code_ptr - 1, target); -+} -+ -+/* -+ * Emits common code for TLB addend lookup, that eventually loads the -+ * addend in TCG_REG_TMP2. -+ */ -+static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl, MemOpIdx oi, -+ tcg_insn_unit **label_ptr, bool is_load) -+{ -+ MemOp opc = get_memop(oi); -+ unsigned s_bits = opc & MO_SIZE; -+ unsigned a_bits = get_alignment_bits(opc); -+ tcg_target_long compare_mask; -+ int mem_index = get_mmuidx(oi); -+ int fast_ofs = TLB_MASK_TABLE_OFS(mem_index); -+ int mask_ofs = fast_ofs + offsetof(CPUTLBDescFast, mask); -+ int table_ofs = fast_ofs + offsetof(CPUTLBDescFast, table); -+ -+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs); -+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs); -+ -+ tcg_out_opc_srli_d(s, TCG_REG_TMP2, addrl, -+ TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); -+ tcg_out_opc_and(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP0); -+ tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP1); -+ -+ /* Load the tlb comparator and the addend. */ -+ tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP0, TCG_REG_TMP2, -+ is_load ? offsetof(CPUTLBEntry, addr_read) -+ : offsetof(CPUTLBEntry, addr_write)); -+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_REG_TMP2, -+ offsetof(CPUTLBEntry, addend)); -+ -+ /* We don't support unaligned accesses. */ -+ if (a_bits < s_bits) { -+ a_bits = s_bits; -+ } -+ /* Clear the non-page, non-alignment bits from the address. */ -+ compare_mask = (tcg_target_long)TARGET_PAGE_MASK | ((1 << a_bits) - 1); -+ tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_TMP1, compare_mask); -+ tcg_out_opc_and(s, TCG_REG_TMP1, TCG_REG_TMP1, addrl); -+ -+ /* Compare masked address with the TLB entry. */ -+ label_ptr[0] = s->code_ptr; -+ tcg_out_opc_bne(s, TCG_REG_TMP0, TCG_REG_TMP1, 0); -+ -+ /* TLB Hit - addend in TCG_REG_TMP2, ready for use. */ -+} -+ -+static void add_qemu_ldst_label(TCGContext *s, int is_ld, MemOpIdx oi, -+ TCGType type, -+ TCGReg datalo, TCGReg addrlo, -+ void *raddr, tcg_insn_unit **label_ptr) -+{ -+ TCGLabelQemuLdst *label = new_ldst_label(s); -+ -+ label->is_ld = is_ld; -+ label->oi = oi; -+ label->type = type; -+ label->datalo_reg = datalo; -+ label->datahi_reg = 0; /* unused */ -+ label->addrlo_reg = addrlo; -+ label->addrhi_reg = 0; /* unused */ -+ label->raddr = tcg_splitwx_to_rx(raddr); -+ label->label_ptr[0] = label_ptr[0]; -+} -+ -+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) -+{ -+ MemOpIdx oi = l->oi; -+ MemOp opc = get_memop(oi); -+ MemOp size = opc & MO_SIZE; -+ TCGType type = l->type; -+ -+ /* resolve label address */ -+ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { -+ return false; -+ } -+ -+ /* call load helper */ -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A1, l->addrlo_reg); -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A2, oi); -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A3, (tcg_target_long)l->raddr); -+ -+ tcg_out_call(s, qemu_ld_helpers[size]); -+ -+ switch (opc & MO_SSIZE) { -+ case MO_SB: -+ tcg_out_ext8s(s, l->datalo_reg, TCG_REG_A0); -+ break; -+ case MO_SW: -+ tcg_out_ext16s(s, l->datalo_reg, TCG_REG_A0); -+ break; -+ case MO_SL: -+ tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0); -+ break; -+ case MO_UL: -+ if (type == TCG_TYPE_I32) { -+ /* MO_UL loads of i32 should be sign-extended too */ -+ tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0); -+ break; -+ } -+ /* fallthrough */ -+ default: -+ tcg_out_mov(s, type, l->datalo_reg, TCG_REG_A0); -+ break; -+ } -+ -+ return tcg_out_goto(s, l->raddr); -+} -+ -+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) -+{ -+ MemOpIdx oi = l->oi; -+ MemOp opc = get_memop(oi); -+ MemOp size = opc & MO_SIZE; -+ -+ /* resolve label address */ -+ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { -+ return false; -+ } -+ -+ /* call store helper */ -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A1, l->addrlo_reg); -+ switch (size) { -+ case MO_8: -+ tcg_out_ext8u(s, TCG_REG_A2, l->datalo_reg); -+ break; -+ case MO_16: -+ tcg_out_ext16u(s, TCG_REG_A2, l->datalo_reg); -+ break; -+ case MO_32: -+ tcg_out_ext32u(s, TCG_REG_A2, l->datalo_reg); -+ break; -+ case MO_64: -+ tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_A2, l->datalo_reg); -+ break; -+ default: -+ g_assert_not_reached(); -+ break; -+ } -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A3, oi); -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A4, (tcg_target_long)l->raddr); -+ -+ tcg_out_call(s, qemu_st_helpers[size]); -+ -+ return tcg_out_goto(s, l->raddr); -+} -+#else -+ -+/* -+ * Alignment helpers for user-mode emulation -+ */ -+ -+static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addr_reg, -+ unsigned a_bits) -+{ -+ TCGLabelQemuLdst *l = new_ldst_label(s); -+ -+ l->is_ld = is_ld; -+ l->addrlo_reg = addr_reg; -+ -+ /* -+ * Without micro-architecture details, we don't know which of bstrpick or -+ * andi is faster, so use bstrpick as it's not constrained by imm field -+ * width. (Not to say alignments >= 2^12 are going to happen any time -+ * soon, though) -+ */ -+ tcg_out_opc_bstrpick_d(s, TCG_REG_TMP1, addr_reg, 0, a_bits - 1); -+ -+ l->label_ptr[0] = s->code_ptr; -+ tcg_out_opc_bne(s, TCG_REG_TMP1, TCG_REG_ZERO, 0); -+ -+ l->raddr = tcg_splitwx_to_rx(s->code_ptr); -+} -+ -+static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l) -+{ -+ /* resolve label address */ -+ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { -+ return false; -+ } -+ -+ tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_A1, l->addrlo_reg); -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); -+ -+ /* tail call, with the return address back inline. */ -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (uintptr_t)l->raddr); -+ tcg_out_call_int(s, (const void *)(l->is_ld ? helper_unaligned_ld -+ : helper_unaligned_st), true); -+ return true; -+} -+ -+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) -+{ -+ return tcg_out_fail_alignment(s, l); -+} -+ -+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) -+{ -+ return tcg_out_fail_alignment(s, l); -+} -+ -+#endif /* CONFIG_SOFTMMU */ -+ -+/* -+ * `ext32u` the address register into the temp register given, -+ * if target is 32-bit, no-op otherwise. -+ * -+ * Returns the address register ready for use with TLB addend. -+ */ -+static TCGReg tcg_out_zext_addr_if_32_bit(TCGContext *s, -+ TCGReg addr, TCGReg tmp) -+{ -+ if (TARGET_LONG_BITS == 32) { -+ tcg_out_ext32u(s, tmp, addr); -+ return tmp; -+ } -+ return addr; -+} -+ -+static void tcg_out_qemu_ld_indexed(TCGContext *s, TCGReg rd, TCGReg rj, -+ TCGReg rk, MemOp opc, TCGType type) -+{ -+ /* Byte swapping is left to middle-end expansion. */ -+ tcg_debug_assert((opc & MO_BSWAP) == 0); -+ -+ switch (opc & MO_SSIZE) { -+ case MO_UB: -+ tcg_out_opc_ldx_bu(s, rd, rj, rk); -+ break; -+ case MO_SB: -+ tcg_out_opc_ldx_b(s, rd, rj, rk); -+ break; -+ case MO_UW: -+ tcg_out_opc_ldx_hu(s, rd, rj, rk); -+ break; -+ case MO_SW: -+ tcg_out_opc_ldx_h(s, rd, rj, rk); -+ break; -+ case MO_UL: -+ if (type == TCG_TYPE_I64) { -+ tcg_out_opc_ldx_wu(s, rd, rj, rk); -+ break; -+ } -+ /* fallthrough */ -+ case MO_SL: -+ tcg_out_opc_ldx_w(s, rd, rj, rk); -+ break; -+ case MO_Q: -+ tcg_out_opc_ldx_d(s, rd, rj, rk); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGType type) -+{ -+ TCGReg addr_regl; -+ TCGReg data_regl; -+ MemOpIdx oi; -+ MemOp opc; -+#if defined(CONFIG_SOFTMMU) -+ tcg_insn_unit *label_ptr[1]; -+#else -+ unsigned a_bits; -+#endif -+ TCGReg base; -+ -+ data_regl = *args++; -+ addr_regl = *args++; -+ oi = *args++; -+ opc = get_memop(oi); -+ -+#if defined(CONFIG_SOFTMMU) -+ tcg_out_tlb_load(s, addr_regl, oi, label_ptr, 1); -+ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); -+ tcg_out_qemu_ld_indexed(s, data_regl, base, TCG_REG_TMP2, opc, type); -+ add_qemu_ldst_label(s, 1, oi, type, -+ data_regl, addr_regl, -+ s->code_ptr, label_ptr); -+#else -+ a_bits = get_alignment_bits(opc); -+ if (a_bits) { -+ tcg_out_test_alignment(s, true, addr_regl, a_bits); -+ } -+ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); -+ TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO; -+ tcg_out_qemu_ld_indexed(s, data_regl, base, guest_base_reg, opc, type); -+#endif -+} -+ -+static void tcg_out_qemu_st_indexed(TCGContext *s, TCGReg data, -+ TCGReg rj, TCGReg rk, MemOp opc) -+{ -+ /* Byte swapping is left to middle-end expansion. */ -+ tcg_debug_assert((opc & MO_BSWAP) == 0); -+ -+ switch (opc & MO_SIZE) { -+ case MO_8: -+ tcg_out_opc_stx_b(s, data, rj, rk); -+ break; -+ case MO_16: -+ tcg_out_opc_stx_h(s, data, rj, rk); -+ break; -+ case MO_32: -+ tcg_out_opc_stx_w(s, data, rj, rk); -+ break; -+ case MO_64: -+ tcg_out_opc_stx_d(s, data, rj, rk); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args) -+{ -+ TCGReg addr_regl; -+ TCGReg data_regl; -+ MemOpIdx oi; -+ MemOp opc; -+#if defined(CONFIG_SOFTMMU) -+ tcg_insn_unit *label_ptr[1]; -+#else -+ unsigned a_bits; -+#endif -+ TCGReg base; -+ -+ data_regl = *args++; -+ addr_regl = *args++; -+ oi = *args++; -+ opc = get_memop(oi); -+ -+#if defined(CONFIG_SOFTMMU) -+ tcg_out_tlb_load(s, addr_regl, oi, label_ptr, 0); -+ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); -+ tcg_out_qemu_st_indexed(s, data_regl, base, TCG_REG_TMP2, opc); -+ add_qemu_ldst_label(s, 0, oi, -+ 0, /* type param is unused for stores */ -+ data_regl, addr_regl, -+ s->code_ptr, label_ptr); -+#else -+ a_bits = get_alignment_bits(opc); -+ if (a_bits) { -+ tcg_out_test_alignment(s, false, addr_regl, a_bits); -+ } -+ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); -+ TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO; -+ tcg_out_qemu_st_indexed(s, data_regl, base, guest_base_reg, opc); -+#endif -+} -+ -+/* -+ * Entry-points -+ */ -+ -+static const tcg_insn_unit *tb_ret_addr; -+ -+static void tcg_out_op(TCGContext *s, TCGOpcode opc, -+ const TCGArg args[TCG_MAX_OP_ARGS], -+ const int const_args[TCG_MAX_OP_ARGS]) -+{ -+ TCGArg a0 = args[0]; -+ TCGArg a1 = args[1]; -+ TCGArg a2 = args[2]; -+ int c2 = const_args[2]; -+ -+ switch (opc) { -+ case INDEX_op_exit_tb: -+ /* Reuse the zeroing that exists for goto_ptr. */ -+ if (a0 == 0) { -+ tcg_out_call_int(s, tcg_code_gen_epilogue, true); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, a0); -+ tcg_out_call_int(s, tb_ret_addr, true); -+ } -+ break; -+ -+ case INDEX_op_goto_tb: -+ assert(s->tb_jmp_insn_offset == 0); -+ /* indirect jump method */ -+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO, -+ (uintptr_t)(s->tb_jmp_target_addr + a0)); -+ tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_TMP0, 0); -+ set_jmp_reset_offset(s, a0); -+ break; -+ -+ case INDEX_op_mb: -+ tcg_out_mb(s, a0); -+ break; -+ -+ case INDEX_op_goto_ptr: -+ tcg_out_opc_jirl(s, TCG_REG_ZERO, a0, 0); -+ break; -+ -+ case INDEX_op_br: -+ tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SD10K16, arg_label(a0), -+ 0); -+ tcg_out_opc_b(s, 0); -+ break; -+ -+ case INDEX_op_brcond_i32: -+ case INDEX_op_brcond_i64: -+ tcg_out_brcond(s, a2, a0, a1, arg_label(args[3])); -+ break; -+ -+ case INDEX_op_ext8s_i32: -+ case INDEX_op_ext8s_i64: -+ tcg_out_ext8s(s, a0, a1); -+ break; -+ -+ case INDEX_op_ext8u_i32: -+ case INDEX_op_ext8u_i64: -+ tcg_out_ext8u(s, a0, a1); -+ break; -+ -+ case INDEX_op_ext16s_i32: -+ case INDEX_op_ext16s_i64: -+ tcg_out_ext16s(s, a0, a1); -+ break; -+ -+ case INDEX_op_ext16u_i32: -+ case INDEX_op_ext16u_i64: -+ tcg_out_ext16u(s, a0, a1); -+ break; -+ -+ case INDEX_op_ext32u_i64: -+ case INDEX_op_extu_i32_i64: -+ tcg_out_ext32u(s, a0, a1); -+ break; -+ -+ case INDEX_op_ext32s_i64: -+ case INDEX_op_extrl_i64_i32: -+ case INDEX_op_ext_i32_i64: -+ tcg_out_ext32s(s, a0, a1); -+ break; -+ -+ case INDEX_op_extrh_i64_i32: -+ tcg_out_opc_srai_d(s, a0, a1, 32); -+ break; -+ -+ case INDEX_op_not_i32: -+ case INDEX_op_not_i64: -+ tcg_out_opc_nor(s, a0, a1, TCG_REG_ZERO); -+ break; -+ -+ case INDEX_op_nor_i32: -+ case INDEX_op_nor_i64: -+ if (c2) { -+ tcg_out_opc_ori(s, a0, a1, a2); -+ tcg_out_opc_nor(s, a0, a0, TCG_REG_ZERO); -+ } else { -+ tcg_out_opc_nor(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_andc_i32: -+ case INDEX_op_andc_i64: -+ if (c2) { -+ /* guaranteed to fit due to constraint */ -+ tcg_out_opc_andi(s, a0, a1, ~a2); -+ } else { -+ tcg_out_opc_andn(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_orc_i32: -+ case INDEX_op_orc_i64: -+ if (c2) { -+ /* guaranteed to fit due to constraint */ -+ tcg_out_opc_ori(s, a0, a1, ~a2); -+ } else { -+ tcg_out_opc_orn(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_and_i32: -+ case INDEX_op_and_i64: -+ if (c2) { -+ tcg_out_opc_andi(s, a0, a1, a2); -+ } else { -+ tcg_out_opc_and(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_or_i32: -+ case INDEX_op_or_i64: -+ if (c2) { -+ tcg_out_opc_ori(s, a0, a1, a2); -+ } else { -+ tcg_out_opc_or(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_xor_i32: -+ case INDEX_op_xor_i64: -+ if (c2) { -+ tcg_out_opc_xori(s, a0, a1, a2); -+ } else { -+ tcg_out_opc_xor(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_extract_i32: -+ tcg_out_opc_bstrpick_w(s, a0, a1, a2, a2 + args[3] - 1); -+ break; -+ case INDEX_op_extract_i64: -+ tcg_out_opc_bstrpick_d(s, a0, a1, a2, a2 + args[3] - 1); -+ break; -+ -+ case INDEX_op_deposit_i32: -+ tcg_out_opc_bstrins_w(s, a0, a2, args[3], args[3] + args[4] - 1); -+ break; -+ case INDEX_op_deposit_i64: -+ tcg_out_opc_bstrins_d(s, a0, a2, args[3], args[3] + args[4] - 1); -+ break; -+ -+ case INDEX_op_bswap16_i32: -+ case INDEX_op_bswap16_i64: -+ tcg_out_opc_revb_2h(s, a0, a1); -+ if (a2 & TCG_BSWAP_OS) { -+ tcg_out_ext16s(s, a0, a0); -+ } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { -+ tcg_out_ext16u(s, a0, a0); -+ } -+ break; -+ -+ case INDEX_op_bswap32_i32: -+ /* All 32-bit values are computed sign-extended in the register. */ -+ a2 = TCG_BSWAP_OS; -+ /* fallthrough */ -+ case INDEX_op_bswap32_i64: -+ tcg_out_opc_revb_2w(s, a0, a1); -+ if (a2 & TCG_BSWAP_OS) { -+ tcg_out_ext32s(s, a0, a0); -+ } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { -+ tcg_out_ext32u(s, a0, a0); -+ } -+ break; -+ -+ case INDEX_op_bswap64_i64: -+ tcg_out_opc_revb_d(s, a0, a1); -+ break; -+ -+ case INDEX_op_clz_i32: -+ tcg_out_clzctz(s, OPC_CLZ_W, a0, a1, a2, c2, true); -+ break; -+ case INDEX_op_clz_i64: -+ tcg_out_clzctz(s, OPC_CLZ_D, a0, a1, a2, c2, false); -+ break; -+ -+ case INDEX_op_ctz_i32: -+ tcg_out_clzctz(s, OPC_CTZ_W, a0, a1, a2, c2, true); -+ break; -+ case INDEX_op_ctz_i64: -+ tcg_out_clzctz(s, OPC_CTZ_D, a0, a1, a2, c2, false); -+ break; -+ -+ case INDEX_op_shl_i32: -+ if (c2) { -+ tcg_out_opc_slli_w(s, a0, a1, a2 & 0x1f); -+ } else { -+ tcg_out_opc_sll_w(s, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_shl_i64: -+ if (c2) { -+ tcg_out_opc_slli_d(s, a0, a1, a2 & 0x3f); -+ } else { -+ tcg_out_opc_sll_d(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_shr_i32: -+ if (c2) { -+ tcg_out_opc_srli_w(s, a0, a1, a2 & 0x1f); -+ } else { -+ tcg_out_opc_srl_w(s, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_shr_i64: -+ if (c2) { -+ tcg_out_opc_srli_d(s, a0, a1, a2 & 0x3f); -+ } else { -+ tcg_out_opc_srl_d(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_sar_i32: -+ if (c2) { -+ tcg_out_opc_srai_w(s, a0, a1, a2 & 0x1f); -+ } else { -+ tcg_out_opc_sra_w(s, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_sar_i64: -+ if (c2) { -+ tcg_out_opc_srai_d(s, a0, a1, a2 & 0x3f); -+ } else { -+ tcg_out_opc_sra_d(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_rotl_i32: -+ /* transform into equivalent rotr/rotri */ -+ if (c2) { -+ tcg_out_opc_rotri_w(s, a0, a1, (32 - a2) & 0x1f); -+ } else { -+ tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2); -+ tcg_out_opc_rotr_w(s, a0, a1, TCG_REG_TMP0); -+ } -+ break; -+ case INDEX_op_rotl_i64: -+ /* transform into equivalent rotr/rotri */ -+ if (c2) { -+ tcg_out_opc_rotri_d(s, a0, a1, (64 - a2) & 0x3f); -+ } else { -+ tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2); -+ tcg_out_opc_rotr_d(s, a0, a1, TCG_REG_TMP0); -+ } -+ break; -+ -+ case INDEX_op_rotr_i32: -+ if (c2) { -+ tcg_out_opc_rotri_w(s, a0, a1, a2 & 0x1f); -+ } else { -+ tcg_out_opc_rotr_w(s, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_rotr_i64: -+ if (c2) { -+ tcg_out_opc_rotri_d(s, a0, a1, a2 & 0x3f); -+ } else { -+ tcg_out_opc_rotr_d(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_add_i32: -+ if (c2) { -+ tcg_out_opc_addi_w(s, a0, a1, a2); -+ } else { -+ tcg_out_opc_add_w(s, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_add_i64: -+ if (c2) { -+ tcg_out_opc_addi_d(s, a0, a1, a2); -+ } else { -+ tcg_out_opc_add_d(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_sub_i32: -+ if (c2) { -+ tcg_out_opc_addi_w(s, a0, a1, -a2); -+ } else { -+ tcg_out_opc_sub_w(s, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_sub_i64: -+ if (c2) { -+ tcg_out_opc_addi_d(s, a0, a1, -a2); -+ } else { -+ tcg_out_opc_sub_d(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_mul_i32: -+ tcg_out_opc_mul_w(s, a0, a1, a2); -+ break; -+ case INDEX_op_mul_i64: -+ tcg_out_opc_mul_d(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_mulsh_i32: -+ tcg_out_opc_mulh_w(s, a0, a1, a2); -+ break; -+ case INDEX_op_mulsh_i64: -+ tcg_out_opc_mulh_d(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_muluh_i32: -+ tcg_out_opc_mulh_wu(s, a0, a1, a2); -+ break; -+ case INDEX_op_muluh_i64: -+ tcg_out_opc_mulh_du(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_div_i32: -+ tcg_out_opc_div_w(s, a0, a1, a2); -+ break; -+ case INDEX_op_div_i64: -+ tcg_out_opc_div_d(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_divu_i32: -+ tcg_out_opc_div_wu(s, a0, a1, a2); -+ break; -+ case INDEX_op_divu_i64: -+ tcg_out_opc_div_du(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_rem_i32: -+ tcg_out_opc_mod_w(s, a0, a1, a2); -+ break; -+ case INDEX_op_rem_i64: -+ tcg_out_opc_mod_d(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_remu_i32: -+ tcg_out_opc_mod_wu(s, a0, a1, a2); -+ break; -+ case INDEX_op_remu_i64: -+ tcg_out_opc_mod_du(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_setcond_i32: -+ case INDEX_op_setcond_i64: -+ tcg_out_setcond(s, args[3], a0, a1, a2, c2); -+ break; -+ -+ case INDEX_op_ld8s_i32: -+ case INDEX_op_ld8s_i64: -+ tcg_out_ldst(s, OPC_LD_B, a0, a1, a2); -+ break; -+ case INDEX_op_ld8u_i32: -+ case INDEX_op_ld8u_i64: -+ tcg_out_ldst(s, OPC_LD_BU, a0, a1, a2); -+ break; -+ case INDEX_op_ld16s_i32: -+ case INDEX_op_ld16s_i64: -+ tcg_out_ldst(s, OPC_LD_H, a0, a1, a2); -+ break; -+ case INDEX_op_ld16u_i32: -+ case INDEX_op_ld16u_i64: -+ tcg_out_ldst(s, OPC_LD_HU, a0, a1, a2); -+ break; -+ case INDEX_op_ld_i32: -+ case INDEX_op_ld32s_i64: -+ tcg_out_ldst(s, OPC_LD_W, a0, a1, a2); -+ break; -+ case INDEX_op_ld32u_i64: -+ tcg_out_ldst(s, OPC_LD_WU, a0, a1, a2); -+ break; -+ case INDEX_op_ld_i64: -+ tcg_out_ldst(s, OPC_LD_D, a0, a1, a2); -+ break; -+ -+ case INDEX_op_st8_i32: -+ case INDEX_op_st8_i64: -+ tcg_out_ldst(s, OPC_ST_B, a0, a1, a2); -+ break; -+ case INDEX_op_st16_i32: -+ case INDEX_op_st16_i64: -+ tcg_out_ldst(s, OPC_ST_H, a0, a1, a2); -+ break; -+ case INDEX_op_st_i32: -+ case INDEX_op_st32_i64: -+ tcg_out_ldst(s, OPC_ST_W, a0, a1, a2); -+ break; -+ case INDEX_op_st_i64: -+ tcg_out_ldst(s, OPC_ST_D, a0, a1, a2); -+ break; -+ -+ case INDEX_op_qemu_ld_i32: -+ tcg_out_qemu_ld(s, args, TCG_TYPE_I32); -+ break; -+ case INDEX_op_qemu_ld_i64: -+ tcg_out_qemu_ld(s, args, TCG_TYPE_I64); -+ break; -+ case INDEX_op_qemu_st_i32: -+ tcg_out_qemu_st(s, args); -+ break; -+ case INDEX_op_qemu_st_i64: -+ tcg_out_qemu_st(s, args); -+ break; -+ -+ case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ -+ case INDEX_op_mov_i64: -+ case INDEX_op_call: /* Always emitted via tcg_out_call. */ -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) -+{ -+ switch (op) { -+ case INDEX_op_goto_ptr: -+ return C_O0_I1(r); -+ -+ case INDEX_op_st8_i32: -+ case INDEX_op_st8_i64: -+ case INDEX_op_st16_i32: -+ case INDEX_op_st16_i64: -+ case INDEX_op_st32_i64: -+ case INDEX_op_st_i32: -+ case INDEX_op_st_i64: -+ return C_O0_I2(rZ, r); -+ -+ case INDEX_op_brcond_i32: -+ case INDEX_op_brcond_i64: -+ return C_O0_I2(rZ, rZ); -+ -+ case INDEX_op_qemu_st_i32: -+ case INDEX_op_qemu_st_i64: -+ return C_O0_I2(LZ, L); -+ -+ case INDEX_op_ext8s_i32: -+ case INDEX_op_ext8s_i64: -+ case INDEX_op_ext8u_i32: -+ case INDEX_op_ext8u_i64: -+ case INDEX_op_ext16s_i32: -+ case INDEX_op_ext16s_i64: -+ case INDEX_op_ext16u_i32: -+ case INDEX_op_ext16u_i64: -+ case INDEX_op_ext32s_i64: -+ case INDEX_op_ext32u_i64: -+ case INDEX_op_extu_i32_i64: -+ case INDEX_op_extrl_i64_i32: -+ case INDEX_op_extrh_i64_i32: -+ case INDEX_op_ext_i32_i64: -+ case INDEX_op_not_i32: -+ case INDEX_op_not_i64: -+ case INDEX_op_extract_i32: -+ case INDEX_op_extract_i64: -+ case INDEX_op_bswap16_i32: -+ case INDEX_op_bswap16_i64: -+ case INDEX_op_bswap32_i32: -+ case INDEX_op_bswap32_i64: -+ case INDEX_op_bswap64_i64: -+ case INDEX_op_ld8s_i32: -+ case INDEX_op_ld8s_i64: -+ case INDEX_op_ld8u_i32: -+ case INDEX_op_ld8u_i64: -+ case INDEX_op_ld16s_i32: -+ case INDEX_op_ld16s_i64: -+ case INDEX_op_ld16u_i32: -+ case INDEX_op_ld16u_i64: -+ case INDEX_op_ld32s_i64: -+ case INDEX_op_ld32u_i64: -+ case INDEX_op_ld_i32: -+ case INDEX_op_ld_i64: -+ return C_O1_I1(r, r); -+ -+ case INDEX_op_qemu_ld_i32: -+ case INDEX_op_qemu_ld_i64: -+ return C_O1_I1(r, L); -+ -+ case INDEX_op_andc_i32: -+ case INDEX_op_andc_i64: -+ case INDEX_op_orc_i32: -+ case INDEX_op_orc_i64: -+ /* -+ * LoongArch insns for these ops don't have reg-imm forms, but we -+ * can express using andi/ori if ~constant satisfies -+ * TCG_CT_CONST_U12. -+ */ -+ return C_O1_I2(r, r, rC); -+ -+ case INDEX_op_shl_i32: -+ case INDEX_op_shl_i64: -+ case INDEX_op_shr_i32: -+ case INDEX_op_shr_i64: -+ case INDEX_op_sar_i32: -+ case INDEX_op_sar_i64: -+ case INDEX_op_rotl_i32: -+ case INDEX_op_rotl_i64: -+ case INDEX_op_rotr_i32: -+ case INDEX_op_rotr_i64: -+ return C_O1_I2(r, r, ri); -+ -+ case INDEX_op_add_i32: -+ case INDEX_op_add_i64: -+ return C_O1_I2(r, r, rI); -+ -+ case INDEX_op_and_i32: -+ case INDEX_op_and_i64: -+ case INDEX_op_nor_i32: -+ case INDEX_op_nor_i64: -+ case INDEX_op_or_i32: -+ case INDEX_op_or_i64: -+ case INDEX_op_xor_i32: -+ case INDEX_op_xor_i64: -+ /* LoongArch reg-imm bitops have their imms ZERO-extended */ -+ return C_O1_I2(r, r, rU); -+ -+ case INDEX_op_clz_i32: -+ case INDEX_op_clz_i64: -+ case INDEX_op_ctz_i32: -+ case INDEX_op_ctz_i64: -+ return C_O1_I2(r, r, rW); -+ -+ case INDEX_op_setcond_i32: -+ case INDEX_op_setcond_i64: -+ return C_O1_I2(r, r, rZ); -+ -+ case INDEX_op_deposit_i32: -+ case INDEX_op_deposit_i64: -+ /* Must deposit into the same register as input */ -+ return C_O1_I2(r, 0, rZ); -+ -+ case INDEX_op_sub_i32: -+ case INDEX_op_sub_i64: -+ return C_O1_I2(r, rZ, rN); -+ -+ case INDEX_op_mul_i32: -+ case INDEX_op_mul_i64: -+ case INDEX_op_mulsh_i32: -+ case INDEX_op_mulsh_i64: -+ case INDEX_op_muluh_i32: -+ case INDEX_op_muluh_i64: -+ case INDEX_op_div_i32: -+ case INDEX_op_div_i64: -+ case INDEX_op_divu_i32: -+ case INDEX_op_divu_i64: -+ case INDEX_op_rem_i32: -+ case INDEX_op_rem_i64: -+ case INDEX_op_remu_i32: -+ case INDEX_op_remu_i64: -+ return C_O1_I2(r, rZ, rZ); -+ -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static const int tcg_target_callee_save_regs[] = { -+ TCG_REG_S0, /* used for the global env (TCG_AREG0) */ -+ TCG_REG_S1, -+ TCG_REG_S2, -+ TCG_REG_S3, -+ TCG_REG_S4, -+ TCG_REG_S5, -+ TCG_REG_S6, -+ TCG_REG_S7, -+ TCG_REG_S8, -+ TCG_REG_S9, -+ TCG_REG_RA, /* should be last for ABI compliance */ -+}; -+ -+/* Stack frame parameters. */ -+#define REG_SIZE (TCG_TARGET_REG_BITS / 8) -+#define SAVE_SIZE ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE) -+#define TEMP_SIZE (CPU_TEMP_BUF_NLONGS * (int)sizeof(long)) -+#define FRAME_SIZE ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE \ -+ + TCG_TARGET_STACK_ALIGN - 1) \ -+ & -TCG_TARGET_STACK_ALIGN) -+#define SAVE_OFS (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE) -+ -+/* We're expecting to be able to use an immediate for frame allocation. */ -+QEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7ff); -+ -+/* Generate global QEMU prologue and epilogue code */ -+static void tcg_target_qemu_prologue(TCGContext *s) -+{ -+ int i; -+ -+ tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE); -+ -+ /* TB prologue */ -+ tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE); -+ for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { -+ tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i], -+ TCG_REG_SP, SAVE_OFS + i * REG_SIZE); -+ } -+ -+#if !defined(CONFIG_SOFTMMU) -+ if (USE_GUEST_BASE) { -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base); -+ tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG); -+ } -+#endif -+ -+ /* Call generated code */ -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); -+ tcg_out_opc_jirl(s, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0); -+ -+ /* Return path for goto_ptr. Set return value to 0 */ -+ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr); -+ tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO); -+ -+ /* TB epilogue */ -+ tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr); -+ for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { -+ tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i], -+ TCG_REG_SP, SAVE_OFS + i * REG_SIZE); -+ } -+ -+ tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE); -+ tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_RA, 0); -+} -+ -+static void tcg_target_init(TCGContext *s) -+{ -+ tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS; -+ tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS; -+ -+ tcg_target_call_clobber_regs = ALL_GENERAL_REGS; -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S3); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S4); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S5); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S6); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S7); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S8); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S9); -+ -+ s->reserved_regs = 0; -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP0); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_RESERVED); -+} -+ -+typedef struct { -+ DebugFrameHeader h; -+ uint8_t fde_def_cfa[4]; -+ uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2]; -+} DebugFrame; -+ -+#define ELF_HOST_MACHINE EM_LOONGARCH -+ -+static const DebugFrame debug_frame = { -+ .h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */ -+ .h.cie.id = -1, -+ .h.cie.version = 1, -+ .h.cie.code_align = 1, -+ .h.cie.data_align = -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */ -+ .h.cie.return_column = TCG_REG_RA, -+ -+ /* Total FDE size does not include the "len" member. */ -+ .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset), -+ -+ .fde_def_cfa = { -+ 12, TCG_REG_SP, /* DW_CFA_def_cfa sp, ... */ -+ (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */ -+ (FRAME_SIZE >> 7) -+ }, -+ .fde_reg_ofs = { -+ 0x80 + 23, 11, /* DW_CFA_offset, s0, -88 */ -+ 0x80 + 24, 10, /* DW_CFA_offset, s1, -80 */ -+ 0x80 + 25, 9, /* DW_CFA_offset, s2, -72 */ -+ 0x80 + 26, 8, /* DW_CFA_offset, s3, -64 */ -+ 0x80 + 27, 7, /* DW_CFA_offset, s4, -56 */ -+ 0x80 + 28, 6, /* DW_CFA_offset, s5, -48 */ -+ 0x80 + 29, 5, /* DW_CFA_offset, s6, -40 */ -+ 0x80 + 30, 4, /* DW_CFA_offset, s7, -32 */ -+ 0x80 + 31, 3, /* DW_CFA_offset, s8, -24 */ -+ 0x80 + 22, 2, /* DW_CFA_offset, s9, -16 */ -+ 0x80 + 1 , 1, /* DW_CFA_offset, ra, -8 */ -+ } -+}; -+ -+void tcg_register_jit(const void *buf, size_t buf_size) -+{ -+ tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); -+} -diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h -new file mode 100644 -index 000000000..d58a6162f ---- /dev/null -+++ b/tcg/loongarch64/tcg-target.h -@@ -0,0 +1,178 @@ -+/* -+ * Tiny Code Generator for QEMU -+ * -+ * Copyright (c) 2021 WANG Xuerui -+ * -+ * Based on tcg/riscv/tcg-target.h -+ * -+ * Copyright (c) 2018 SiFive, Inc -+ * -+ * 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. -+ */ -+ -+#ifndef LOONGARCH_TCG_TARGET_H -+#define LOONGARCH_TCG_TARGET_H -+ -+/* -+ * Loongson removed the (incomplete) 32-bit support from kernel and toolchain -+ * for the initial upstreaming of this architecture, so don't bother and just -+ * support the LP64* ABI for now. -+ */ -+#if defined(__loongarch64) -+# define TCG_TARGET_REG_BITS 64 -+#else -+# error unsupported LoongArch register size -+#endif -+ -+#define TCG_TARGET_INSN_UNIT_SIZE 4 -+#define TCG_TARGET_NB_REGS 32 -+#define MAX_CODE_GEN_BUFFER_SIZE SIZE_MAX -+ -+typedef enum { -+ TCG_REG_ZERO, -+ TCG_REG_RA, -+ TCG_REG_TP, -+ TCG_REG_SP, -+ TCG_REG_A0, -+ TCG_REG_A1, -+ TCG_REG_A2, -+ TCG_REG_A3, -+ TCG_REG_A4, -+ TCG_REG_A5, -+ TCG_REG_A6, -+ TCG_REG_A7, -+ TCG_REG_T0, -+ TCG_REG_T1, -+ TCG_REG_T2, -+ TCG_REG_T3, -+ TCG_REG_T4, -+ TCG_REG_T5, -+ TCG_REG_T6, -+ TCG_REG_T7, -+ TCG_REG_T8, -+ TCG_REG_RESERVED, -+ TCG_REG_S9, -+ TCG_REG_S0, -+ TCG_REG_S1, -+ TCG_REG_S2, -+ TCG_REG_S3, -+ TCG_REG_S4, -+ TCG_REG_S5, -+ TCG_REG_S6, -+ TCG_REG_S7, -+ TCG_REG_S8, -+ -+ /* aliases */ -+ TCG_AREG0 = TCG_REG_S0, -+ TCG_REG_TMP0 = TCG_REG_T8, -+ TCG_REG_TMP1 = TCG_REG_T7, -+ TCG_REG_TMP2 = TCG_REG_T6, -+} TCGReg; -+ -+/* used for function call generation */ -+#define TCG_REG_CALL_STACK TCG_REG_SP -+#define TCG_TARGET_STACK_ALIGN 16 -+#define TCG_TARGET_CALL_ALIGN_ARGS 1 -+#define TCG_TARGET_CALL_STACK_OFFSET 0 -+ -+/* optional instructions */ -+#define TCG_TARGET_HAS_movcond_i32 0 -+#define TCG_TARGET_HAS_div_i32 1 -+#define TCG_TARGET_HAS_rem_i32 1 -+#define TCG_TARGET_HAS_div2_i32 0 -+#define TCG_TARGET_HAS_rot_i32 1 -+#define TCG_TARGET_HAS_deposit_i32 1 -+#define TCG_TARGET_HAS_extract_i32 1 -+#define TCG_TARGET_HAS_sextract_i32 0 -+#define TCG_TARGET_HAS_extract2_i32 0 -+#define TCG_TARGET_HAS_add2_i32 0 -+#define TCG_TARGET_HAS_sub2_i32 0 -+#define TCG_TARGET_HAS_mulu2_i32 0 -+#define TCG_TARGET_HAS_muls2_i32 0 -+#define TCG_TARGET_HAS_muluh_i32 1 -+#define TCG_TARGET_HAS_mulsh_i32 1 -+#define TCG_TARGET_HAS_ext8s_i32 1 -+#define TCG_TARGET_HAS_ext16s_i32 1 -+#define TCG_TARGET_HAS_ext8u_i32 1 -+#define TCG_TARGET_HAS_ext16u_i32 1 -+#define TCG_TARGET_HAS_bswap16_i32 1 -+#define TCG_TARGET_HAS_bswap32_i32 1 -+#define TCG_TARGET_HAS_not_i32 1 -+#define TCG_TARGET_HAS_neg_i32 0 -+#define TCG_TARGET_HAS_andc_i32 1 -+#define TCG_TARGET_HAS_orc_i32 1 -+#define TCG_TARGET_HAS_eqv_i32 0 -+#define TCG_TARGET_HAS_nand_i32 0 -+#define TCG_TARGET_HAS_nor_i32 1 -+#define TCG_TARGET_HAS_clz_i32 1 -+#define TCG_TARGET_HAS_ctz_i32 1 -+#define TCG_TARGET_HAS_ctpop_i32 0 -+#define TCG_TARGET_HAS_direct_jump 0 -+#define TCG_TARGET_HAS_brcond2 0 -+#define TCG_TARGET_HAS_setcond2 0 -+#define TCG_TARGET_HAS_qemu_st8_i32 0 -+ -+/* 64-bit operations */ -+#define TCG_TARGET_HAS_movcond_i64 0 -+#define TCG_TARGET_HAS_div_i64 1 -+#define TCG_TARGET_HAS_rem_i64 1 -+#define TCG_TARGET_HAS_div2_i64 0 -+#define TCG_TARGET_HAS_rot_i64 1 -+#define TCG_TARGET_HAS_deposit_i64 1 -+#define TCG_TARGET_HAS_extract_i64 1 -+#define TCG_TARGET_HAS_sextract_i64 0 -+#define TCG_TARGET_HAS_extract2_i64 0 -+#define TCG_TARGET_HAS_extrl_i64_i32 1 -+#define TCG_TARGET_HAS_extrh_i64_i32 1 -+#define TCG_TARGET_HAS_ext8s_i64 1 -+#define TCG_TARGET_HAS_ext16s_i64 1 -+#define TCG_TARGET_HAS_ext32s_i64 1 -+#define TCG_TARGET_HAS_ext8u_i64 1 -+#define TCG_TARGET_HAS_ext16u_i64 1 -+#define TCG_TARGET_HAS_ext32u_i64 1 -+#define TCG_TARGET_HAS_bswap16_i64 1 -+#define TCG_TARGET_HAS_bswap32_i64 1 -+#define TCG_TARGET_HAS_bswap64_i64 1 -+#define TCG_TARGET_HAS_not_i64 1 -+#define TCG_TARGET_HAS_neg_i64 0 -+#define TCG_TARGET_HAS_andc_i64 1 -+#define TCG_TARGET_HAS_orc_i64 1 -+#define TCG_TARGET_HAS_eqv_i64 0 -+#define TCG_TARGET_HAS_nand_i64 0 -+#define TCG_TARGET_HAS_nor_i64 1 -+#define TCG_TARGET_HAS_clz_i64 1 -+#define TCG_TARGET_HAS_ctz_i64 1 -+#define TCG_TARGET_HAS_ctpop_i64 0 -+#define TCG_TARGET_HAS_add2_i64 0 -+#define TCG_TARGET_HAS_sub2_i64 0 -+#define TCG_TARGET_HAS_mulu2_i64 0 -+#define TCG_TARGET_HAS_muls2_i64 0 -+#define TCG_TARGET_HAS_muluh_i64 1 -+#define TCG_TARGET_HAS_mulsh_i64 1 -+ -+/* not defined -- call should be eliminated at compile time */ -+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t); -+ -+#define TCG_TARGET_DEFAULT_MO (0) -+ -+#define TCG_TARGET_NEED_LDST_LABELS -+ -+#define TCG_TARGET_HAS_MEMORY_BSWAP 0 -+ -+#endif /* LOONGARCH_TCG_TARGET_H */ --- -2.43.5 - diff --git a/1038-doc-update-AMD-SEV-to-include-Live-migration-flow.patch b/1038-doc-update-AMD-SEV-to-include-Live-migration-flow.patch deleted file mode 100644 index 6672e3f..0000000 --- a/1038-doc-update-AMD-SEV-to-include-Live-migration-flow.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 5152d49cc4aead7dc06e9f788e9c078701c5a160 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Thu, 7 May 2020 22:26:17 +0000 -Subject: [PATCH 01/29] doc: update AMD SEV to include Live migration flow - -cherry-picked from https://github.com/AMDESE/qemu/commit/0e2b3d80e3. - -Reviewed-by: Dr. David Alan Gilbert -Signed-off-by: Brijesh Singh -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - docs/amd-memory-encryption.txt | 40 +++++++++++++++++++++++++++++++++- - 1 file changed, 39 insertions(+), 1 deletion(-) - -diff --git a/docs/amd-memory-encryption.txt b/docs/amd-memory-encryption.txt -index ffca382b5..17e2714d9 100644 ---- a/docs/amd-memory-encryption.txt -+++ b/docs/amd-memory-encryption.txt -@@ -126,7 +126,45 @@ TODO - - Live Migration - ---------------- --TODO -+AMD SEV encrypts the memory of VMs and because a different key is used -+in each VM, the hypervisor will be unable to simply copy the -+ciphertext from one VM to another to migrate the VM. Instead the AMD SEV Key -+Management API provides sets of function which the hypervisor can use -+to package a guest page for migration, while maintaining the confidentiality -+provided by AMD SEV. -+ -+SEV guest VMs have the concept of private and shared memory. The private -+memory is encrypted with the guest-specific key, while shared memory may -+be encrypted with the hypervisor key. The migration APIs provided by the -+SEV API spec should be used for migrating the private pages. The -+KVM_GET_PAGE_ENC_BITMAP ioctl can be used to get the guest page encryption -+bitmap. The bitmap can be used to check if the given guest page is -+private or shared. -+ -+Before initiating the migration, we need to know the targets machine's public -+Diffie-Hellman key (PDH) and certificate chain. It can be retrieved -+with the 'query-sev-capabilities' QMP command or using the sev-tool. The -+migrate-set-parameter can be used to pass the target machine's PDH and -+certificate chain. -+ -+During the migration flow, the SEND_START is called on the source hypervisor -+to create an outgoing encryption context. The SEV guest policy dictates whether -+the certificate passed through the migrate-sev-set-info command will be -+validated. SEND_UPDATE_DATA is called to encrypt the guest private pages. -+After migration is completed, SEND_FINISH is called to destroy the encryption -+context and make the VM non-runnable to protect it against cloning. -+ -+On the target machine, RECEIVE_START is called first to create an -+incoming encryption context. The RECEIVE_UPDATE_DATA is called to copy -+the received encrypted page into guest memory. After migration has -+completed, RECEIVE_FINISH is called to make the VM runnable. -+ -+For more information about the migration see SEV API Appendix A -+Usage flow (Live migration section). -+ -+NOTE: -+To protect against the memory clone SEV APIs are designed to make the VM -+unrunnable in case of the migration failure. - - References - ----------------- --- -2.31.1 - diff --git a/1039-migration.json-add-AMD-SEV-specific-migration-parame.patch b/1039-migration.json-add-AMD-SEV-specific-migration-parame.patch deleted file mode 100644 index bd46ba7..0000000 --- a/1039-migration.json-add-AMD-SEV-specific-migration-parame.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 7dc7f0659bfe9c8be64f65873df9595b3791dce5 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 11:27:00 +0000 -Subject: [PATCH 02/29] migration.json: add AMD SEV specific migration - parameters - -cherry-picked from https://github.com/AMDESE/qemu/commit/d6a23bde6b6e. - -AMD SEV migration flow requires that target machine's public Diffie-Hellman -key (PDH) and certificate chain must be passed before initiating the guest -migration. User can use QMP 'migrate-set-parameters' to pass the certificate -chain. The certificate chain will be used while creating the outgoing -encryption context. - -Signed-off-by: Brijesh Singh -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - migration/migration.c | 66 +++++++++++++++++++++++++++++++++++++++++++ - monitor/hmp-cmds.c | 18 ++++++++++++ - qapi/migration.json | 40 ++++++++++++++++++++++++-- - 3 files changed, 121 insertions(+), 3 deletions(-) - -diff --git a/migration/migration.c b/migration/migration.c -index 0885549de..6810bcefc 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -932,6 +932,12 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) - params->announce_rounds = s->parameters.announce_rounds; - params->has_announce_step = true; - params->announce_step = s->parameters.announce_step; -+ params->has_sev_pdh = true; -+ params->sev_pdh = g_strdup(s->parameters.sev_pdh); -+ params->has_sev_plat_cert = true; -+ params->sev_plat_cert = g_strdup(s->parameters.sev_plat_cert); -+ params->has_sev_amd_cert = true; -+ params->sev_amd_cert = g_strdup(s->parameters.sev_amd_cert); - - if (s->parameters.has_block_bitmap_mapping) { - params->has_block_bitmap_mapping = true; -@@ -1633,6 +1639,19 @@ static void migrate_params_test_apply(MigrateSetParameters *params, - dest->has_block_bitmap_mapping = true; - dest->block_bitmap_mapping = params->block_bitmap_mapping; - } -+ -+ if (params->has_sev_pdh) { -+ assert(params->sev_pdh->type == QTYPE_QSTRING); -+ dest->sev_pdh = g_strdup(params->sev_pdh->u.s); -+ } -+ if (params->has_sev_plat_cert) { -+ assert(params->sev_plat_cert->type == QTYPE_QSTRING); -+ dest->sev_plat_cert = g_strdup(params->sev_plat_cert->u.s); -+ } -+ if (params->has_sev_amd_cert) { -+ assert(params->sev_amd_cert->type == QTYPE_QSTRING); -+ dest->sev_amd_cert = g_strdup(params->sev_amd_cert->u.s); -+ } - } - - static void migrate_params_apply(MigrateSetParameters *params, Error **errp) -@@ -1755,6 +1774,22 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp) - QAPI_CLONE(BitmapMigrationNodeAliasList, - params->block_bitmap_mapping); - } -+ -+ if (params->has_sev_pdh) { -+ g_free(s->parameters.sev_pdh); -+ assert(params->sev_pdh->type == QTYPE_QSTRING); -+ s->parameters.sev_pdh = g_strdup(params->sev_pdh->u.s); -+ } -+ if (params->has_sev_plat_cert) { -+ g_free(s->parameters.sev_plat_cert); -+ assert(params->sev_plat_cert->type == QTYPE_QSTRING); -+ s->parameters.sev_plat_cert = g_strdup(params->sev_plat_cert->u.s); -+ } -+ if (params->has_sev_amd_cert) { -+ g_free(s->parameters.sev_amd_cert); -+ assert(params->sev_amd_cert->type == QTYPE_QSTRING); -+ s->parameters.sev_amd_cert = g_strdup(params->sev_amd_cert->u.s); -+ } - } - - void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) -@@ -1775,6 +1810,27 @@ void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) - params->tls_hostname->type = QTYPE_QSTRING; - params->tls_hostname->u.s = strdup(""); - } -+ /* TODO Rewrite "" to null instead */ -+ if (params->has_sev_pdh -+ && params->sev_pdh->type == QTYPE_QNULL) { -+ qobject_unref(params->sev_pdh->u.n); -+ params->sev_pdh->type = QTYPE_QSTRING; -+ params->sev_pdh->u.s = strdup(""); -+ } -+ /* TODO Rewrite "" to null instead */ -+ if (params->has_sev_plat_cert -+ && params->sev_plat_cert->type == QTYPE_QNULL) { -+ qobject_unref(params->sev_plat_cert->u.n); -+ params->sev_plat_cert->type = QTYPE_QSTRING; -+ params->sev_plat_cert->u.s = strdup(""); -+ } -+ /* TODO Rewrite "" to null instead */ -+ if (params->has_sev_amd_cert -+ && params->sev_amd_cert->type == QTYPE_QNULL) { -+ qobject_unref(params->sev_amd_cert->u.n); -+ params->sev_amd_cert->type = QTYPE_QSTRING; -+ params->sev_amd_cert->u.s = strdup(""); -+ } - - migrate_params_test_apply(params, &tmp); - -@@ -4332,6 +4388,9 @@ static void migration_instance_finalize(Object *obj) - qemu_mutex_destroy(&ms->qemu_file_lock); - g_free(params->tls_hostname); - g_free(params->tls_creds); -+ g_free(params->sev_pdh); -+ g_free(params->sev_plat_cert); -+ g_free(params->sev_amd_cert); - qemu_sem_destroy(&ms->wait_unplug_sem); - qemu_sem_destroy(&ms->rate_limit_sem); - qemu_sem_destroy(&ms->pause_sem); -@@ -4383,6 +4442,13 @@ static void migration_instance_init(Object *obj) - params->has_tls_hostname = true; - params->has_tls_authz = true; - -+ params->sev_pdh = g_strdup(""); -+ params->sev_plat_cert = g_strdup(""); -+ params->sev_amd_cert = g_strdup(""); -+ params->has_sev_pdh = true; -+ params->has_sev_plat_cert = true; -+ params->has_sev_amd_cert = true; -+ - qemu_sem_init(&ms->postcopy_pause_sem, 0); - qemu_sem_init(&ms->postcopy_pause_rp_sem, 0); - qemu_sem_init(&ms->rp_state.rp_sem, 0); -diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c -index f7216ab5d..409bd15a6 100644 ---- a/monitor/hmp-cmds.c -+++ b/monitor/hmp-cmds.c -@@ -1349,6 +1349,24 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) - error_setg(&err, "The block-bitmap-mapping parameter can only be set " - "through QMP"); - break; -+ case MIGRATION_PARAMETER_SEV_PDH: -+ p->has_sev_pdh = true; -+ p->sev_pdh = g_new0(StrOrNull, 1); -+ p->sev_pdh->type = QTYPE_QSTRING; -+ visit_type_str(v, param, &p->sev_pdh->u.s, &err); -+ break; -+ case MIGRATION_PARAMETER_SEV_PLAT_CERT: -+ p->has_sev_plat_cert = true; -+ p->sev_plat_cert = g_new0(StrOrNull, 1); -+ p->sev_plat_cert->type = QTYPE_QSTRING; -+ visit_type_str(v, param, &p->sev_plat_cert->u.s, &err); -+ break; -+ case MIGRATION_PARAMETER_SEV_AMD_CERT: -+ p->has_sev_amd_cert = true; -+ p->sev_amd_cert = g_new0(StrOrNull, 1); -+ p->sev_amd_cert->type = QTYPE_QSTRING; -+ visit_type_str(v, param, &p->sev_amd_cert->u.s, &err); -+ break; - default: - assert(0); - } -diff --git a/qapi/migration.json b/qapi/migration.json -index 94bc5c69d..bad53a2f8 100644 ---- a/qapi/migration.json -+++ b/qapi/migration.json -@@ -774,6 +774,15 @@ - # block device name if there is one, and to their node name - # otherwise. (Since 5.2) - # -+# @sev-pdh: The target host platform diffie-hellman key encoded in base64 -+# (Since 4.2) -+# -+# @sev-plat-cert: The target host platform certificate chain encoded in base64 -+# (Since 4.2) -+# -+# @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in -+# base64 (Since 4.2) -+# - # Features: - # @unstable: Member @x-checkpoint-delay is experimental. - # -@@ -794,7 +803,8 @@ - 'xbzrle-cache-size', 'max-postcopy-bandwidth', - 'max-cpu-throttle', 'multifd-compression', - 'multifd-zlib-level' ,'multifd-zstd-level', -- 'block-bitmap-mapping' ] } -+ 'block-bitmap-mapping', -+ 'sev-pdh', 'sev-plat-cert', 'sev-amd-cert' ] } - - ## - # @MigrateSetParameters: -@@ -939,6 +949,15 @@ - # block device name if there is one, and to their node name - # otherwise. (Since 5.2) - # -+# @sev-pdh: The target host platform diffie-hellman key encoded in base64 -+# (Since 4.2) -+# -+# @sev-plat-cert: The target host platform certificate chain encoded in base64 -+# (Since 4.2) -+# -+# @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in -+# base64 (Since 4.2) -+# - # Features: - # @unstable: Member @x-checkpoint-delay is experimental. - # -@@ -974,7 +993,10 @@ - '*multifd-compression': 'MultiFDCompression', - '*multifd-zlib-level': 'uint8', - '*multifd-zstd-level': 'uint8', -- '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } } -+ '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ], -+ '*sev-pdh':'StrOrNull', -+ '*sev-plat-cert': 'StrOrNull', -+ '*sev-amd-cert' : 'StrOrNull' } } - - ## - # @migrate-set-parameters: -@@ -1139,6 +1161,15 @@ - # block device name if there is one, and to their node name - # otherwise. (Since 5.2) - # -+# @sev-pdh: The target host platform diffie-hellman key encoded in base64 -+# (Since 4.2) -+# -+# @sev-plat-cert: The target host platform certificate chain encoded in base64 -+# (Since 4.2) -+# -+# @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in -+# base64 (Since 4.2) -+# - # Features: - # @unstable: Member @x-checkpoint-delay is experimental. - # -@@ -1172,7 +1203,10 @@ - '*multifd-compression': 'MultiFDCompression', - '*multifd-zlib-level': 'uint8', - '*multifd-zstd-level': 'uint8', -- '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } } -+ '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ], -+ '*sev-pdh':'str', -+ '*sev-plat-cert': 'str', -+ '*sev-amd-cert' : 'str'} } - - ## - # @query-migrate-parameters: --- -2.31.1 - diff --git a/1040-confidential-guest-support-introduce-ConfidentialGue.patch b/1040-confidential-guest-support-introduce-ConfidentialGue.patch deleted file mode 100644 index c76a7dc..0000000 --- a/1040-confidential-guest-support-introduce-ConfidentialGue.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 7b50e920f4faacb529a43230565ae9e022e61649 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 11:41:37 +0000 -Subject: [PATCH 03/29] confidential guest support: introduce - ConfidentialGuestMemoryEncryptionOps for encrypted VMs - -cherry-picked from https://github.com/AMDESE/qemu/commit/74fce7be9bd. - -When memory encryption is enabled in VM, the guest RAM will be encrypted -with the guest-specific key, to protect the confidentiality of data while -in transit we need to platform specific hooks to save or migrate the -guest RAM. - -Introduce the new ConfidentialGuestMemoryEncryptionOps in this patch -which will be later used by the encrypted guest for migration. - -Signed-off-by: Brijesh Singh -Co-developed-by: Ashish Kalra -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 27 +++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index ba2dd4b5d..343f686fc 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -53,8 +53,35 @@ struct ConfidentialGuestSupport { - bool ready; - }; - -+/** -+ * The functions registers with ConfidentialGuestMemoryEncryptionOps will be -+ * used during the encrypted guest migration. -+ */ -+struct ConfidentialGuestMemoryEncryptionOps { -+ /* Initialize the platform specific state before starting the migration */ -+ int (*save_setup)(const char *pdh, const char *plat_cert, -+ const char *amd_cert); -+ -+ /* Write the encrypted page and metadata associated with it */ -+ int (*save_outgoing_page)(QEMUFile *f, uint8_t *ptr, uint32_t size, -+ uint64_t *bytes_sent); -+ -+ /* Load the incoming encrypted page into guest memory */ -+ int (*load_incoming_page)(QEMUFile *f, uint8_t *ptr); -+ -+ /* Check if gfn is in shared/unencrypted region */ -+ bool (*is_gfn_in_unshared_region)(unsigned long gfn); -+ -+ /* Write the shared regions list */ -+ int (*save_outgoing_shared_regions_list)(QEMUFile *f); -+ -+ /* Load the shared regions list */ -+ int (*load_incoming_shared_regions_list)(QEMUFile *f); -+}; -+ - typedef struct ConfidentialGuestSupportClass { - ObjectClass parent; -+ struct ConfidentialGuestMemoryEncryptionOps *memory_encryption_ops; - } ConfidentialGuestSupportClass; - - #endif /* !CONFIG_USER_ONLY */ --- -2.31.1 - diff --git a/1041-target-i386-sev-provide-callback-to-setup-outgoing-c.patch b/1041-target-i386-sev-provide-callback-to-setup-outgoing-c.patch deleted file mode 100644 index f7c60e2..0000000 --- a/1041-target-i386-sev-provide-callback-to-setup-outgoing-c.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 4e400056b6e3d895814d091da819ba742602581b Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 12:10:23 +0000 -Subject: [PATCH 04/29] target/i386: sev: provide callback to setup outgoing - context - -cherry-picked from https://github.com/AMDESE/qemu/commit/7521883afc0. - -The user provides the target machine's Platform Diffie-Hellman key (PDH) -and certificate chain before starting the SEV guest migration. Cache the -certificate chain as we need them while creating the outgoing context. - -Signed-off-by: Brijesh Singh -Co-developed-by: Ashish Kalra -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - target/i386/sev.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ - target/i386/sev.h | 2 ++ - 2 files changed, 61 insertions(+) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 36669bbdf..5dd6c0a3f 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -76,6 +76,12 @@ struct SevGuestState { - int sev_fd; - SevState state; - gchar *measurement; -+ guchar *remote_pdh; -+ size_t remote_pdh_len; -+ guchar *remote_plat_cert; -+ size_t remote_plat_cert_len; -+ guchar *amd_cert; -+ size_t amd_cert_len; - - uint32_t reset_cs; - uint32_t reset_ip; -@@ -160,6 +166,12 @@ static const char *const sev_fw_errlist[] = { - - #define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist) - -+#define SEV_FW_BLOB_MAX_SIZE 0x4000 /* 16KB */ -+ -+static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { -+ .save_setup = sev_save_setup, -+}; -+ - static int - sev_ioctl(int fd, int cmd, void *data, int *error) - { -@@ -872,6 +884,48 @@ sev_vm_state_change(void *opaque, bool running, RunState state) - } - } - -+static inline bool check_blob_length(size_t value) -+{ -+ if (value > SEV_FW_BLOB_MAX_SIZE) { -+ error_report("invalid length max=%d got=%ld", -+ SEV_FW_BLOB_MAX_SIZE, value); -+ return false; -+ } -+ -+ return true; -+} -+ -+int sev_save_setup(const char *pdh, const char *plat_cert, -+ const char *amd_cert) -+{ -+ SevGuestState *s = sev_guest; -+ -+ s->remote_pdh = g_base64_decode(pdh, &s->remote_pdh_len); -+ if (!check_blob_length(s->remote_pdh_len)) { -+ goto error; -+ } -+ -+ s->remote_plat_cert = g_base64_decode(plat_cert, -+ &s->remote_plat_cert_len); -+ if (!check_blob_length(s->remote_plat_cert_len)) { -+ goto error; -+ } -+ -+ s->amd_cert = g_base64_decode(amd_cert, &s->amd_cert_len); -+ if (!check_blob_length(s->amd_cert_len)) { -+ goto error; -+ } -+ -+ return 0; -+ -+error: -+ g_free(s->remote_pdh); -+ g_free(s->remote_plat_cert); -+ g_free(s->amd_cert); -+ -+ return 1; -+} -+ - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { - SevGuestState *sev -@@ -886,6 +940,9 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - return 0; - } - -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(cgs)); -+ - ret = ram_block_discard_disable(true); - if (ret) { - error_report("%s: cannot disable RAM discard", __func__); -@@ -980,6 +1037,8 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - qemu_add_machine_init_done_notifier(&sev_machine_done_notify); - qemu_add_vm_change_state_handler(sev_vm_state_change, sev); - -+ cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; -+ - cgs->ready = true; - - return 0; -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 1c97bff99..14801ec44 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -51,6 +51,8 @@ extern uint32_t sev_get_reduced_phys_bits(void); - extern bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp); - - int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp); -+int sev_save_setup(const char *pdh, const char *plat_cert, -+ const char *amd_cert); - int sev_inject_launch_secret(const char *hdr, const char *secret, - uint64_t gpa, Error **errp); - --- -2.31.1 - diff --git a/1042-target-i386-sev-do-not-create-launch-context-for-an-.patch b/1042-target-i386-sev-do-not-create-launch-context-for-an-.patch deleted file mode 100644 index da664a3..0000000 --- a/1042-target-i386-sev-do-not-create-launch-context-for-an-.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 36b08d0392f2baec061e6fb90416db42dfad20f7 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 12:16:09 +0000 -Subject: [PATCH 05/29] target/i386: sev: do not create launch context for an - incoming guest - -cherry-picked from https://github.com/AMDESE/qemu/commit/b85694233495. - -The LAUNCH_START is used for creating an encryption context to encrypt -newly created guest, for an incoming guest the RECEIVE_START should be -used. - -Reviewed-by: Dr. David Alan Gilbert -Signed-off-by: Brijesh Singh -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - target/i386/sev.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 5dd6c0a3f..fc8a2bb61 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1024,10 +1024,16 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - } - } - -- ret = sev_launch_start(sev); -- if (ret) { -- error_setg(errp, "%s: failed to create encryption context", __func__); -- goto err; -+ /* -+ * The LAUNCH context is used for new guest, if its an incoming guest -+ * then RECEIVE context will be created after the connection is established. -+ */ -+ if (!runstate_check(RUN_STATE_INMIGRATE)) { -+ ret = sev_launch_start(sev); -+ if (ret) { -+ error_setg(errp, "%s: failed to create encryption context", __func__); -+ goto err; -+ } - } - - /* CSV guest needs no notifier to reg/unreg memory */ --- -2.31.1 - diff --git a/1043-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch b/1043-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch deleted file mode 100644 index f0a412a..0000000 --- a/1043-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch +++ /dev/null @@ -1,324 +0,0 @@ -From 196380db46216f207e57b00e4bbc95178683d0cf Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 12:55:25 +0000 -Subject: [PATCH 06/29] target/i386: sev: add support to encrypt the outgoing - page - -cherry-picked from https://github.com/AMDESE/qemu/commit/5187c6f86bd. - -The sev_save_outgoing_page() provide the implementation to encrypt the -guest private pages during the transit. The routines uses the SEND_START -command to create the outgoing encryption context on the first call then -uses the SEND_UPDATE_DATA command to encrypt the data before writing it -to the socket. While encrypting the data SEND_UPDATE_DATA produces some -metadata (e.g MAC, IV). The metadata is also sent to the target machine. -After migration is completed, we issue the SEND_FINISH command to transition -the SEV guest state from sending to unrunnable state. - -Signed-off-by: Brijesh Singh -Co-developed-by: Ashish Kalra -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - target/i386/sev.c | 221 +++++++++++++++++++++++++++++++++++++++ - target/i386/sev.h | 2 + - target/i386/trace-events | 3 + - 3 files changed, 226 insertions(+) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index fc8a2bb61..622150106 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -31,6 +31,8 @@ - #include "sysemu/runstate.h" - #include "trace.h" - #include "migration/blocker.h" -+#include "migration/qemu-file.h" -+#include "migration/misc.h" - #include "qom/object.h" - #include "monitor/monitor.h" - #include "monitor/hmp-target.h" -@@ -82,6 +84,8 @@ struct SevGuestState { - size_t remote_plat_cert_len; - guchar *amd_cert; - size_t amd_cert_len; -+ gchar *send_packet_hdr; -+ size_t send_packet_hdr_len; - - uint32_t reset_cs; - uint32_t reset_ip; -@@ -170,6 +174,7 @@ static const char *const sev_fw_errlist[] = { - - static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_setup = sev_save_setup, -+ .save_outgoing_page = sev_save_outgoing_page, - }; - - static int -@@ -926,6 +931,40 @@ error: - return 1; - } - -+static void -+sev_send_finish(void) -+{ -+ int ret, error; -+ -+ trace_kvm_sev_send_finish(); -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_FINISH, 0, &error); -+ if (ret) { -+ error_report("%s: SEND_FINISH ret=%d fw_error=%d '%s'", -+ __func__, ret, error, fw_error_to_str(error)); -+ } -+ -+ g_free(sev_guest->send_packet_hdr); -+ sev_set_guest_state(sev_guest, SEV_STATE_RUNNING); -+} -+ -+static void -+sev_migration_state_notifier(Notifier *notifier, void *data) -+{ -+ MigrationState *s = data; -+ -+ if (migration_has_finished(s) || -+ migration_in_postcopy_after_devices(s) || -+ migration_has_failed(s)) { -+ if (sev_check_state(sev_guest, SEV_STATE_SEND_UPDATE)) { -+ sev_send_finish(); -+ } -+ } -+} -+ -+static Notifier sev_migration_state_notify = { -+ .notify = sev_migration_state_notifier, -+}; -+ - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { - SevGuestState *sev -@@ -1042,6 +1081,7 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - } - qemu_add_machine_init_done_notifier(&sev_machine_done_notify); - qemu_add_vm_change_state_handler(sev_vm_state_change, sev); -+ add_migration_state_change_notifier(&sev_migration_state_notify); - - cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; - -@@ -1283,6 +1323,187 @@ int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size) - return 0; - } - -+static int -+sev_get_send_session_length(void) -+{ -+ int ret, fw_err = 0; -+ struct kvm_sev_send_start start = {}; -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_START, &start, &fw_err); -+ if (fw_err != SEV_RET_INVALID_LEN) { -+ ret = -1; -+ error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_err, fw_error_to_str(fw_err)); -+ goto err; -+ } -+ -+ ret = start.session_len; -+err: -+ return ret; -+} -+ -+static int -+sev_send_start(SevGuestState *s, QEMUFile *f, uint64_t *bytes_sent) -+{ -+ gsize pdh_len = 0, plat_cert_len; -+ int session_len, ret, fw_error; -+ struct kvm_sev_send_start start = { }; -+ guchar *pdh = NULL, *plat_cert = NULL, *session = NULL; -+ Error *local_err = NULL; -+ -+ if (!s->remote_pdh || !s->remote_plat_cert || !s->amd_cert_len) { -+ error_report("%s: missing remote PDH or PLAT_CERT", __func__); -+ return 1; -+ } -+ -+ start.pdh_cert_uaddr = (uintptr_t) s->remote_pdh; -+ start.pdh_cert_len = s->remote_pdh_len; -+ -+ start.plat_certs_uaddr = (uintptr_t)s->remote_plat_cert; -+ start.plat_certs_len = s->remote_plat_cert_len; -+ -+ start.amd_certs_uaddr = (uintptr_t)s->amd_cert; -+ start.amd_certs_len = s->amd_cert_len; -+ -+ /* get the session length */ -+ session_len = sev_get_send_session_length(); -+ if (session_len < 0) { -+ ret = 1; -+ goto err; -+ } -+ -+ session = g_new0(guchar, session_len); -+ start.session_uaddr = (unsigned long)session; -+ start.session_len = session_len; -+ -+ /* Get our PDH certificate */ -+ ret = sev_get_pdh_info(s->sev_fd, &pdh, &pdh_len, -+ &plat_cert, &plat_cert_len, &local_err); -+ if (ret) { -+ error_report("Failed to get our PDH cert"); -+ goto err; -+ } -+ -+ trace_kvm_sev_send_start(start.pdh_cert_uaddr, start.pdh_cert_len, -+ start.plat_certs_uaddr, start.plat_certs_len, -+ start.amd_certs_uaddr, start.amd_certs_len); -+ -+ ret = sev_ioctl(s->sev_fd, KVM_SEV_SEND_START, &start, &fw_error); -+ if (ret < 0) { -+ error_report("%s: SEND_START ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ qemu_put_be32(f, start.policy); -+ qemu_put_be32(f, pdh_len); -+ qemu_put_buffer(f, (uint8_t *)pdh, pdh_len); -+ qemu_put_be32(f, start.session_len); -+ qemu_put_buffer(f, (uint8_t *)start.session_uaddr, start.session_len); -+ *bytes_sent = 12 + pdh_len + start.session_len; -+ -+ sev_set_guest_state(s, SEV_STATE_SEND_UPDATE); -+ -+err: -+ g_free(pdh); -+ g_free(plat_cert); -+ return ret; -+} -+ -+static int -+sev_send_get_packet_len(int *fw_err) -+{ -+ int ret; -+ struct kvm_sev_send_update_data update = { 0, }; -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_UPDATE_DATA, -+ &update, fw_err); -+ if (*fw_err != SEV_RET_INVALID_LEN) { -+ ret = -1; -+ error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", -+ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); -+ goto err; -+ } -+ -+ ret = update.hdr_len; -+ -+err: -+ return ret; -+} -+ -+static int -+sev_send_update_data(SevGuestState *s, QEMUFile *f, uint8_t *ptr, uint32_t size, -+ uint64_t *bytes_sent) -+{ -+ int ret, fw_error; -+ guchar *trans; -+ struct kvm_sev_send_update_data update = { }; -+ -+ /* -+ * If this is first call then query the packet header bytes and allocate -+ * the packet buffer. -+ */ -+ if (!s->send_packet_hdr) { -+ s->send_packet_hdr_len = sev_send_get_packet_len(&fw_error); -+ if (s->send_packet_hdr_len < 1) { -+ error_report("%s: SEND_UPDATE fw_error=%d '%s'", -+ __func__, fw_error, fw_error_to_str(fw_error)); -+ return 1; -+ } -+ -+ s->send_packet_hdr = g_new(gchar, s->send_packet_hdr_len); -+ } -+ -+ /* allocate transport buffer */ -+ trans = g_new(guchar, size); -+ -+ update.hdr_uaddr = (uintptr_t)s->send_packet_hdr; -+ update.hdr_len = s->send_packet_hdr_len; -+ update.guest_uaddr = (uintptr_t)ptr; -+ update.guest_len = size; -+ update.trans_uaddr = (uintptr_t)trans; -+ update.trans_len = size; -+ -+ trace_kvm_sev_send_update_data(ptr, trans, size); -+ -+ ret = sev_ioctl(s->sev_fd, KVM_SEV_SEND_UPDATE_DATA, &update, &fw_error); -+ if (ret) { -+ error_report("%s: SEND_UPDATE_DATA ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ qemu_put_be32(f, update.hdr_len); -+ qemu_put_buffer(f, (uint8_t *)update.hdr_uaddr, update.hdr_len); -+ *bytes_sent = 4 + update.hdr_len; -+ -+ qemu_put_be32(f, update.trans_len); -+ qemu_put_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ *bytes_sent += (4 + update.trans_len); -+ -+err: -+ g_free(trans); -+ return ret; -+} -+ -+int sev_save_outgoing_page(QEMUFile *f, uint8_t *ptr, -+ uint32_t sz, uint64_t *bytes_sent) -+{ -+ SevGuestState *s = sev_guest; -+ -+ /* -+ * If this is a first buffer then create outgoing encryption context -+ * and write our PDH, policy and session data. -+ */ -+ if (!sev_check_state(s, SEV_STATE_SEND_UPDATE) && -+ sev_send_start(s, f, bytes_sent)) { -+ error_report("Failed to create outgoing context"); -+ return 1; -+ } -+ -+ return sev_send_update_data(s, f, ptr, sz, bytes_sent); -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 14801ec44..19d3136dd 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -53,6 +53,8 @@ extern bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **er - int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp); - int sev_save_setup(const char *pdh, const char *plat_cert, - const char *amd_cert); -+int sev_save_outgoing_page(QEMUFile *f, uint8_t *ptr, -+ uint32_t size, uint64_t *bytes_sent); - int sev_inject_launch_secret(const char *hdr, const char *secret, - uint64_t gpa, Error **errp); - -diff --git a/target/i386/trace-events b/target/i386/trace-events -index b7da9bd74..c165e3737 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -11,6 +11,9 @@ kvm_sev_launch_measurement(const char *value) "data %s" - kvm_sev_launch_finish(void) "" - kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d" - kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data %s" -+kvm_sev_send_start(uint64_t pdh, int l1, uint64_t plat, int l2, uint64_t amd, int l3) "pdh 0x%" PRIx64 " len %d plat 0x%" PRIx64 " len %d amd 0x%" PRIx64 " len %d" -+kvm_sev_send_update_data(void *src, void *dst, int len) "guest %p trans %p len %d" -+kvm_sev_send_finish(void) "" - - # csv.c - kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 --- -2.31.1 - diff --git a/1044-target-i386-sev-add-support-to-load-incoming-encrypt.patch b/1044-target-i386-sev-add-support-to-load-incoming-encrypt.patch deleted file mode 100644 index cf10880..0000000 --- a/1044-target-i386-sev-add-support-to-load-incoming-encrypt.patch +++ /dev/null @@ -1,224 +0,0 @@ -From 10e03772a0a14f65602c496d65a4392b5b70da51 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 13:00:50 +0000 -Subject: [PATCH 07/29] target/i386: sev: add support to load incoming - encrypted page - -cherry-picked from https://github.com/AMDESE/qemu/commit/e86e5dccb045. - -The sev_load_incoming_page() provide the implementation to read the -incoming guest private pages from the socket and load it into the guest -memory. The routines uses the RECEIVE_START command to create the -incoming encryption context on the first call then uses the -RECEIEVE_UPDATE_DATA command to load the encrypted pages into the guest -memory. After migration is completed, we issue the RECEIVE_FINISH command -to transition the SEV guest to the runnable state so that it can be -executed. - -Signed-off-by: Brijesh Singh -Co-developed-by: Ashish Kalra -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - target/i386/sev.c | 137 ++++++++++++++++++++++++++++++++++++++- - target/i386/sev.h | 1 + - target/i386/trace-events | 3 + - 3 files changed, 140 insertions(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 622150106..bdd77fd0e 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -175,6 +175,7 @@ static const char *const sev_fw_errlist[] = { - static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_setup = sev_save_setup, - .save_outgoing_page = sev_save_outgoing_page, -+ .load_incoming_page = sev_load_incoming_page, - }; - - static int -@@ -877,13 +878,33 @@ sev_launch_finish(SevGuestState *sev) - migrate_add_blocker(sev_mig_blocker, &error_fatal); - } - -+static int -+sev_receive_finish(SevGuestState *s) -+{ -+ int error, ret = 1; -+ -+ trace_kvm_sev_receive_finish(); -+ ret = sev_ioctl(s->sev_fd, KVM_SEV_RECEIVE_FINISH, 0, &error); -+ if (ret) { -+ error_report("%s: RECEIVE_FINISH ret=%d fw_error=%d '%s'", -+ __func__, ret, error, fw_error_to_str(error)); -+ goto err; -+ } -+ -+ sev_set_guest_state(s, SEV_STATE_RUNNING); -+err: -+ return ret; -+} -+ - static void - sev_vm_state_change(void *opaque, bool running, RunState state) - { - SevGuestState *sev = opaque; - - if (running) { -- if (!sev_check_state(sev, SEV_STATE_RUNNING)) { -+ if (sev_check_state(sev, SEV_STATE_RECEIVE_UPDATE)) { -+ sev_receive_finish(sev); -+ } else if (!sev_check_state(sev, SEV_STATE_RUNNING)) { - sev_launch_finish(sev); - } - } -@@ -1504,6 +1525,120 @@ int sev_save_outgoing_page(QEMUFile *f, uint8_t *ptr, - return sev_send_update_data(s, f, ptr, sz, bytes_sent); - } - -+static int -+sev_receive_start(SevGuestState *sev, QEMUFile *f) -+{ -+ int ret = 1; -+ int fw_error; -+ struct kvm_sev_receive_start start = { }; -+ gchar *session = NULL, *pdh_cert = NULL; -+ -+ /* get SEV guest handle */ -+ start.handle = object_property_get_int(OBJECT(sev), "handle", -+ &error_abort); -+ -+ /* get the source policy */ -+ start.policy = qemu_get_be32(f); -+ -+ /* get source PDH key */ -+ start.pdh_len = qemu_get_be32(f); -+ if (!check_blob_length(start.pdh_len)) { -+ return 1; -+ } -+ -+ pdh_cert = g_new(gchar, start.pdh_len); -+ qemu_get_buffer(f, (uint8_t *)pdh_cert, start.pdh_len); -+ start.pdh_uaddr = (uintptr_t)pdh_cert; -+ -+ /* get source session data */ -+ start.session_len = qemu_get_be32(f); -+ if (!check_blob_length(start.session_len)) { -+ return 1; -+ } -+ session = g_new(gchar, start.session_len); -+ qemu_get_buffer(f, (uint8_t *)session, start.session_len); -+ start.session_uaddr = (uintptr_t)session; -+ -+ trace_kvm_sev_receive_start(start.policy, session, pdh_cert); -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_RECEIVE_START, -+ &start, &fw_error); -+ if (ret < 0) { -+ error_report("Error RECEIVE_START ret=%d fw_error=%d '%s'", -+ ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ object_property_set_int(OBJECT(sev), "handle", start.handle, &error_abort); -+ sev_set_guest_state(sev, SEV_STATE_RECEIVE_UPDATE); -+err: -+ g_free(session); -+ g_free(pdh_cert); -+ -+ return ret; -+} -+ -+static int sev_receive_update_data(QEMUFile *f, uint8_t *ptr) -+{ -+ int ret = 1, fw_error = 0; -+ gchar *hdr = NULL, *trans = NULL; -+ struct kvm_sev_receive_update_data update = {}; -+ -+ /* get packet header */ -+ update.hdr_len = qemu_get_be32(f); -+ if (!check_blob_length(update.hdr_len)) { -+ return 1; -+ } -+ -+ hdr = g_new(gchar, update.hdr_len); -+ qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len); -+ update.hdr_uaddr = (uintptr_t)hdr; -+ -+ /* get transport buffer */ -+ update.trans_len = qemu_get_be32(f); -+ if (!check_blob_length(update.trans_len)) { -+ goto err; -+ } -+ -+ trans = g_new(gchar, update.trans_len); -+ update.trans_uaddr = (uintptr_t)trans; -+ qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ -+ update.guest_uaddr = (uintptr_t) ptr; -+ update.guest_len = update.trans_len; -+ -+ trace_kvm_sev_receive_update_data(trans, ptr, update.guest_len, -+ hdr, update.hdr_len); -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_RECEIVE_UPDATE_DATA, -+ &update, &fw_error); -+ if (ret) { -+ error_report("Error RECEIVE_UPDATE_DATA ret=%d fw_error=%d '%s'", -+ ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+err: -+ g_free(trans); -+ g_free(hdr); -+ return ret; -+} -+ -+int sev_load_incoming_page(QEMUFile *f, uint8_t *ptr) -+{ -+ SevGuestState *s = sev_guest; -+ -+ /* -+ * If this is first buffer and SEV is not in recieiving state then -+ * use RECEIVE_START command to create a encryption context. -+ */ -+ if (!sev_check_state(s, SEV_STATE_RECEIVE_UPDATE) && -+ sev_receive_start(s, f)) { -+ return 1; -+ } -+ -+ return sev_receive_update_data(f, ptr); -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 19d3136dd..1040b0cb2 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -55,6 +55,7 @@ int sev_save_setup(const char *pdh, const char *plat_cert, - const char *amd_cert); - int sev_save_outgoing_page(QEMUFile *f, uint8_t *ptr, - uint32_t size, uint64_t *bytes_sent); -+int sev_load_incoming_page(QEMUFile *f, uint8_t *ptr); - int sev_inject_launch_secret(const char *hdr, const char *secret, - uint64_t gpa, Error **errp); - -diff --git a/target/i386/trace-events b/target/i386/trace-events -index c165e3737..e32b0319b 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -14,6 +14,9 @@ kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data - kvm_sev_send_start(uint64_t pdh, int l1, uint64_t plat, int l2, uint64_t amd, int l3) "pdh 0x%" PRIx64 " len %d plat 0x%" PRIx64 " len %d amd 0x%" PRIx64 " len %d" - kvm_sev_send_update_data(void *src, void *dst, int len) "guest %p trans %p len %d" - kvm_sev_send_finish(void) "" -+kvm_sev_receive_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p" -+kvm_sev_receive_update_data(void *src, void *dst, int len, void *hdr, int hdr_len) "guest %p trans %p len %d hdr %p hdr_len %d" -+kvm_sev_receive_finish(void) "" - - # csv.c - kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 --- -2.31.1 - diff --git a/1045-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch b/1045-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch deleted file mode 100644 index 27daa6b..0000000 --- a/1045-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch +++ /dev/null @@ -1,293 +0,0 @@ -From da756577d513a92fdfd4c1bdda3961dc704ccf12 Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Tue, 27 Jul 2021 15:05:49 +0000 -Subject: [PATCH 08/29] kvm: Add support for SEV shared regions list and - KVM_EXIT_HYPERCALL. - -cherry-picked from https://github.com/AMDESE/qemu/commit/fcbbd9b19ac. - -KVM_HC_MAP_GPA_RANGE hypercall is used by the SEV guest to notify a -change in the page encryption status to the hypervisor. The hypercall -should be invoked only when the encryption attribute is changed from -encrypted -> decrypted and vice versa. By default all guest pages are -considered encrypted. - -The hypercall exits to userspace with KVM_EXIT_HYPERCALL exit code, -currently this is used only by SEV guests for guest page encryptiion -status tracking. Add support to handle this exit and invoke SEV -shared regions list handlers. - -Add support for SEV guest shared regions and implementation of the -SEV shared regions list. - -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - linux-headers/linux/kvm.h | 3 ++ - target/i386/kvm/kvm.c | 48 +++++++++++++++++ - target/i386/sev.c | 105 ++++++++++++++++++++++++++++++++++++++ - target/i386/sev.h | 3 ++ - 4 files changed, 159 insertions(+) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 3bc062a18..b640e72c8 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -344,6 +344,7 @@ struct kvm_run { - } mmio; - /* KVM_EXIT_HYPERCALL */ - struct { -+#define KVM_HC_MAP_GPA_RANGE 12 - __u64 nr; - __u64 args[6]; - __u64 ret; -@@ -1154,6 +1155,8 @@ struct kvm_ppc_resize_hpt { - #define KVM_CAP_S390_ZPCI_OP 221 - #define KVM_CAP_S390_CPU_TOPOLOGY 222 - -+#define KVM_EXIT_HYPERCALL_VALID_MASK (1 << KVM_HC_MAP_GPA_RANGE) -+ - #ifdef KVM_CAP_IRQ_ROUTING - - struct kvm_irq_routing_irqchip { -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index a06221d3e..5262806c4 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -127,6 +127,7 @@ static int has_xsave2; - static int has_xcrs; - static int has_pit_state2; - static int has_exception_payload; -+static int has_map_gpa_range; - - static bool has_msr_mcg_ext_ctl; - -@@ -2052,6 +2053,17 @@ int kvm_arch_init_vcpu(CPUState *cs) - c->eax = MAX(c->eax, KVM_CPUID_SIGNATURE | 0x10); - } - -+ if (sev_enabled()) { -+ c = cpuid_find_entry(&cpuid_data.cpuid, -+ KVM_CPUID_FEATURES | kvm_base, 0); -+ if (c) { -+ c->eax |= (1 << KVM_FEATURE_MIGRATION_CONTROL); -+ if (has_map_gpa_range) { -+ c->eax |= (1 << KVM_FEATURE_HC_MAP_GPA_RANGE); -+ } -+ } -+ } -+ - cpuid_data.cpuid.nent = cpuid_i; - - cpuid_data.cpuid.padding = 0; -@@ -2397,6 +2409,17 @@ int kvm_arch_init(MachineState *ms, KVMState *s) - } - } - -+ has_map_gpa_range = kvm_check_extension(s, KVM_CAP_EXIT_HYPERCALL); -+ if (has_map_gpa_range) { -+ ret = kvm_vm_enable_cap(s, KVM_CAP_EXIT_HYPERCALL, 0, -+ KVM_EXIT_HYPERCALL_VALID_MASK); -+ if (ret < 0) { -+ error_report("kvm: Failed to enable MAP_GPA_RANGE cap: %s", -+ strerror(-ret)); -+ return ret; -+ } -+ } -+ - ret = kvm_get_supported_msrs(s); - if (ret < 0) { - return ret; -@@ -4612,6 +4635,28 @@ static int kvm_handle_tpr_access(X86CPU *cpu) - return 1; - } - -+static int kvm_handle_exit_hypercall(X86CPU *cpu, struct kvm_run *run) -+{ -+ /* -+ * Currently this exit is only used by SEV guests for -+ * guest page encryption status tracking. -+ */ -+ if (run->hypercall.nr == KVM_HC_MAP_GPA_RANGE) { -+ unsigned long enc = run->hypercall.args[2]; -+ unsigned long gpa = run->hypercall.args[0]; -+ unsigned long npages = run->hypercall.args[1]; -+ unsigned long gfn_start = gpa >> TARGET_PAGE_BITS; -+ unsigned long gfn_end = gfn_start + npages; -+ -+ if (enc) { -+ sev_remove_shared_regions_list(gfn_start, gfn_end); -+ } else { -+ sev_add_shared_regions_list(gfn_start, gfn_end); -+ } -+ } -+ return 0; -+} -+ - int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) - { - static const uint8_t int3 = 0xcc; -@@ -4902,6 +4947,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - /* already handled in kvm_arch_post_run */ - ret = 0; - break; -+ case KVM_EXIT_HYPERCALL: -+ ret = kvm_handle_exit_hypercall(cpu, run); -+ break; - default: - fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); - ret = -1; -diff --git a/target/i386/sev.c b/target/i386/sev.c -index bdd77fd0e..de57b0a27 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -45,6 +45,10 @@ - #define TYPE_SEV_GUEST "sev-guest" - OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST) - -+struct shared_region { -+ unsigned long gfn_start, gfn_end; -+ QTAILQ_ENTRY(shared_region) list; -+}; - - extern struct sev_ops sev_ops; - -@@ -90,6 +94,8 @@ struct SevGuestState { - uint32_t reset_cs; - uint32_t reset_ip; - bool reset_data_valid; -+ -+ QTAILQ_HEAD(, shared_region) shared_regions_list; - }; - - #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */ -@@ -1105,6 +1111,7 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - add_migration_state_change_notifier(&sev_migration_state_notify); - - cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; -+ QTAILQ_INIT(&sev->shared_regions_list); - - cgs->ready = true; - -@@ -1639,6 +1646,104 @@ int sev_load_incoming_page(QEMUFile *f, uint8_t *ptr) - return sev_receive_update_data(f, ptr); - } - -+int sev_remove_shared_regions_list(unsigned long start, unsigned long end) -+{ -+ SevGuestState *s = sev_guest; -+ struct shared_region *pos; -+ -+ QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { -+ unsigned long l, r; -+ unsigned long curr_gfn_end = pos->gfn_end; -+ -+ /* -+ * Find if any intersection exists ? -+ * left bound for intersecting segment -+ */ -+ l = MAX(start, pos->gfn_start); -+ /* right bound for intersecting segment */ -+ r = MIN(end, pos->gfn_end); -+ if (l <= r) { -+ if (pos->gfn_start == l && pos->gfn_end == r) { -+ QTAILQ_REMOVE(&s->shared_regions_list, pos, list); -+ } else if (l == pos->gfn_start) { -+ pos->gfn_start = r; -+ } else if (r == pos->gfn_end) { -+ pos->gfn_end = l; -+ } else { -+ /* Do a de-merge -- split linked list nodes */ -+ struct shared_region *shrd_region; -+ -+ pos->gfn_end = l; -+ shrd_region = g_malloc0(sizeof(*shrd_region)); -+ if (!shrd_region) { -+ return 0; -+ } -+ shrd_region->gfn_start = r; -+ shrd_region->gfn_end = curr_gfn_end; -+ QTAILQ_INSERT_AFTER(&s->shared_regions_list, pos, -+ shrd_region, list); -+ } -+ } -+ if (end <= curr_gfn_end) { -+ break; -+ } -+ } -+ return 0; -+} -+ -+int sev_add_shared_regions_list(unsigned long start, unsigned long end) -+{ -+ struct shared_region *shrd_region; -+ struct shared_region *pos; -+ SevGuestState *s = sev_guest; -+ -+ if (QTAILQ_EMPTY(&s->shared_regions_list)) { -+ shrd_region = g_malloc0(sizeof(*shrd_region)); -+ if (!shrd_region) { -+ return -1; -+ } -+ shrd_region->gfn_start = start; -+ shrd_region->gfn_end = end; -+ QTAILQ_INSERT_TAIL(&s->shared_regions_list, shrd_region, list); -+ return 0; -+ } -+ -+ /* -+ * shared regions list is a sorted list in ascending order -+ * of guest PA's and also merges consecutive range of guest PA's -+ */ -+ QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { -+ /* handle duplicate overlapping regions */ -+ if (start >= pos->gfn_start && end <= pos->gfn_end) { -+ return 0; -+ } -+ if (pos->gfn_end < start) { -+ continue; -+ } -+ /* merge consecutive guest PA(s) -- forward merge */ -+ if (pos->gfn_start <= start && pos->gfn_end >= start) { -+ pos->gfn_end = end; -+ return 0; -+ } -+ break; -+ } -+ /* -+ * Add a new node -+ */ -+ shrd_region = g_malloc0(sizeof(*shrd_region)); -+ if (!shrd_region) { -+ return -1; -+ } -+ shrd_region->gfn_start = start; -+ shrd_region->gfn_end = end; -+ if (pos) { -+ QTAILQ_INSERT_BEFORE(pos, shrd_region, list); -+ } else { -+ QTAILQ_INSERT_TAIL(&s->shared_regions_list, shrd_region, list); -+ } -+ return 1; -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 1040b0cb2..8423b5522 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -61,6 +61,9 @@ int sev_inject_launch_secret(const char *hdr, const char *secret, - - int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size); - void sev_es_set_reset_vector(CPUState *cpu); -+int sev_remove_shared_regions_list(unsigned long gfn_start, -+ unsigned long gfn_end); -+int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end); - - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - --- -2.31.1 - diff --git a/1046-migration-add-support-to-migrate-shared-regions-list.patch b/1046-migration-add-support-to-migrate-shared-regions-list.patch deleted file mode 100644 index 72e8cbe..0000000 --- a/1046-migration-add-support-to-migrate-shared-regions-list.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 9f9b6fbfc4cf9f73a001686954d34c40b29e3538 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 16:31:36 +0000 -Subject: [PATCH 09/29] migration: add support to migrate shared regions list - -cherry-picked from https://github.com/AMDESE/qemu/commit/9236f522e48b6. - -When memory encryption is enabled, the hypervisor maintains a shared -regions list which is referred by hypervisor during migration to check -if page is private or shared. This list is built during the VM bootup and -must be migrated to the target host so that hypervisor on target host can -use it for future migration. - -Signed-off-by: Brijesh Singh -Co-developed-by: Ashish Kalra -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - target/i386/sev.c | 43 +++++++++++++++++++++++++++++++++++++++++++ - target/i386/sev.h | 2 ++ - 2 files changed, 45 insertions(+) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index de57b0a27..30cd436ab 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -178,10 +178,15 @@ static const char *const sev_fw_errlist[] = { - - #define SEV_FW_BLOB_MAX_SIZE 0x4000 /* 16KB */ - -+#define SHARED_REGION_LIST_CONT 0x1 -+#define SHARED_REGION_LIST_END 0x2 -+ - static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_setup = sev_save_setup, - .save_outgoing_page = sev_save_outgoing_page, - .load_incoming_page = sev_load_incoming_page, -+ .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, -+ .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, - }; - - static int -@@ -1744,6 +1749,44 @@ int sev_add_shared_regions_list(unsigned long start, unsigned long end) - return 1; - } - -+int sev_save_outgoing_shared_regions_list(QEMUFile *f) -+{ -+ SevGuestState *s = sev_guest; -+ struct shared_region *pos; -+ -+ QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { -+ qemu_put_be32(f, SHARED_REGION_LIST_CONT); -+ qemu_put_be32(f, pos->gfn_start); -+ qemu_put_be32(f, pos->gfn_end); -+ } -+ -+ qemu_put_be32(f, SHARED_REGION_LIST_END); -+ return 0; -+} -+ -+int sev_load_incoming_shared_regions_list(QEMUFile *f) -+{ -+ SevGuestState *s = sev_guest; -+ struct shared_region *shrd_region; -+ int status; -+ -+ status = qemu_get_be32(f); -+ while (status == SHARED_REGION_LIST_CONT) { -+ -+ shrd_region = g_malloc0(sizeof(*shrd_region)); -+ if (!shrd_region) { -+ return 0; -+ } -+ shrd_region->gfn_start = qemu_get_be32(f); -+ shrd_region->gfn_end = qemu_get_be32(f); -+ -+ QTAILQ_INSERT_TAIL(&s->shared_regions_list, shrd_region, list); -+ -+ status = qemu_get_be32(f); -+ } -+ return 0; -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 8423b5522..34814b9f2 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -64,6 +64,8 @@ void sev_es_set_reset_vector(CPUState *cpu); - int sev_remove_shared_regions_list(unsigned long gfn_start, - unsigned long gfn_end); - int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end); -+int sev_save_outgoing_shared_regions_list(QEMUFile *f); -+int sev_load_incoming_shared_regions_list(QEMUFile *f); - - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - --- -2.31.1 - diff --git a/1047-migration-ram-add-support-to-send-encrypted-pages.patch b/1047-migration-ram-add-support-to-send-encrypted-pages.patch deleted file mode 100644 index 42223d6..0000000 --- a/1047-migration-ram-add-support-to-send-encrypted-pages.patch +++ /dev/null @@ -1,338 +0,0 @@ -From a973e7ee1489c9ee089f8c502f9b10f5ca4a4772 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 16:53:19 +0000 -Subject: [PATCH 10/29] migration/ram: add support to send encrypted pages - -cherry-picked from https://github.com/AMDESE/qemu/commit/2d6bda0d4cf. - -When memory encryption is enabled, the guest memory will be encrypted with -the guest specific key. The patch introduces RAM_SAVE_FLAG_ENCRYPTED_PAGE -flag to distinguish the encrypted data from plaintext. Encrypted pages -may need special handling. The sev_save_outgoing_page() is used -by the sender to write the encrypted pages onto the socket, similarly the -sev_load_incoming_page() is used by the target to read the -encrypted pages from the socket and load into the guest memory. - -Signed-off-by: Brijesh Singh -Co-developed-by: Ashish Kalra -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - migration/migration.h | 2 + - migration/ram.c | 163 +++++++++++++++++++++++++++++++++++++++++- - target/i386/sev.c | 14 ++++ - target/i386/sev.h | 4 ++ - 4 files changed, 182 insertions(+), 1 deletion(-) - -diff --git a/migration/migration.h b/migration/migration.h -index 0ae213332..596668d80 100644 ---- a/migration/migration.h -+++ b/migration/migration.h -@@ -403,4 +403,6 @@ void migration_cancel(const Error *error); - - void populate_vfio_info(MigrationInfo *info); - -+bool memcrypt_enabled(void); -+ - #endif -diff --git a/migration/ram.c b/migration/ram.c -index 93cdb456a..57f2c01bf 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -55,6 +55,10 @@ - #include "qemu/iov.h" - #include "multifd.h" - #include "sysemu/runstate.h" -+#include "exec/confidential-guest-support.h" -+ -+/* Defines RAM_SAVE_ENCRYPTED_PAGE and RAM_SAVE_SHARED_REGION_LIST */ -+#include "target/i386/sev.h" - - #include "hw/boards.h" /* for machine_dump_guest_core() */ - -@@ -80,6 +84,16 @@ - #define RAM_SAVE_FLAG_XBZRLE 0x40 - /* 0x80 is reserved in migration.h start with 0x100 next */ - #define RAM_SAVE_FLAG_COMPRESS_PAGE 0x100 -+#define RAM_SAVE_FLAG_ENCRYPTED_DATA 0x200 -+ -+bool memcrypt_enabled(void) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ if(ms->cgs) -+ return ms->cgs->ready; -+ else -+ return false; -+} - - static inline bool is_zero_range(uint8_t *p, uint64_t size) - { -@@ -468,6 +482,8 @@ static QemuCond decomp_done_cond; - - static bool do_compress_ram_page(QEMUFile *f, z_stream *stream, RAMBlock *block, - ram_addr_t offset, uint8_t *source_buf); -+static int ram_save_encrypted_page(RAMState *rs, PageSearchStatus *pss, -+ bool last_stage); - - static void *do_data_compress(void *opaque) - { -@@ -1301,6 +1317,80 @@ static int save_normal_page(RAMState *rs, RAMBlock *block, ram_addr_t offset, - return 1; - } - -+/** -+ * ram_save_encrypted_page - send the given encrypted page to the stream -+ */ -+static int ram_save_encrypted_page(RAMState *rs, PageSearchStatus *pss, -+ bool last_stage) -+{ -+ int ret; -+ uint8_t *p; -+ RAMBlock *block = pss->block; -+ ram_addr_t offset = pss->page << TARGET_PAGE_BITS; -+ uint64_t bytes_xmit; -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ -+ p = block->host + offset; -+ -+ ram_counters.transferred += -+ save_page_header(rs, rs->f, block, -+ offset | RAM_SAVE_FLAG_ENCRYPTED_DATA); -+ -+ qemu_put_be32(rs->f, RAM_SAVE_ENCRYPTED_PAGE); -+ ret = ops->save_outgoing_page(rs->f, p, TARGET_PAGE_SIZE, &bytes_xmit); -+ if (ret) { -+ return -1; -+ } -+ -+ ram_counters.transferred += bytes_xmit; -+ ram_counters.normal++; -+ -+ return 1; -+} -+ -+/** -+ * ram_save_shared_region_list: send the shared region list -+ */ -+static int ram_save_shared_region_list(RAMState *rs, QEMUFile *f) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ -+ save_page_header(rs, rs->f, rs->last_seen_block, -+ RAM_SAVE_FLAG_ENCRYPTED_DATA); -+ qemu_put_be32(rs->f, RAM_SAVE_SHARED_REGIONS_LIST); -+ return ops->save_outgoing_shared_regions_list(rs->f); -+} -+ -+static int load_encrypted_data(QEMUFile *f, uint8_t *ptr) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ -+ int flag; -+ -+ flag = qemu_get_be32(f); -+ -+ if (flag == RAM_SAVE_ENCRYPTED_PAGE) { -+ return ops->load_incoming_page(f, ptr); -+ } else if (flag == RAM_SAVE_SHARED_REGIONS_LIST) { -+ return ops->load_incoming_shared_regions_list(f); -+ } else { -+ error_report("unknown encrypted flag %x", flag); -+ return 1; -+ } -+} -+ - /** - * ram_save_page: send the given page to the stream - * -@@ -2144,6 +2234,35 @@ static bool save_compress_page(RAMState *rs, RAMBlock *block, ram_addr_t offset) - return false; - } - -+/** -+ * encrypted_test_list: check if the page is encrypted -+ * -+ * Returns a bool indicating whether the page is encrypted. -+ */ -+static bool encrypted_test_list(RAMState *rs, RAMBlock *block, -+ unsigned long page) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ unsigned long gfn; -+ -+ /* ROM devices contains the unencrypted data */ -+ if (memory_region_is_rom(block->mr)) { -+ return false; -+ } -+ -+ /* -+ * Translate page in ram_addr_t address space to GPA address -+ * space using memory region. -+ */ -+ gfn = page + (block->mr->addr >> TARGET_PAGE_BITS); -+ -+ return ops->is_gfn_in_unshared_region(gfn); -+} -+ - /** - * ram_save_target_page: save one target page - * -@@ -2164,6 +2283,17 @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss, - return res; - } - -+ /* -+ * If memory encryption is enabled then use memory encryption APIs -+ * to write the outgoing buffer to the wire. The encryption APIs -+ * will take care of accessing the guest memory and re-encrypt it -+ * for the transport purposes. -+ */ -+ if (memcrypt_enabled() && -+ encrypted_test_list(rs, pss->block, pss->page)) { -+ return ram_save_encrypted_page(rs, pss, last_stage); -+ } -+ - if (save_compress_page(rs, block, offset)) { - return 1; - } -@@ -2990,6 +3120,18 @@ void qemu_guest_free_page_hint(void *addr, size_t len) - } - } - -+static int ram_encrypted_save_setup(void) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ MigrationParameters *p = &migrate_get_current()->parameters; -+ -+ return ops->save_setup(p->sev_pdh, p->sev_plat_cert, p->sev_amd_cert); -+} -+ - /* - * Each of ram_save_setup, ram_save_iterate and ram_save_complete has - * long-running RCU critical section. When rcu-reclaims in the code -@@ -3025,6 +3167,13 @@ static int ram_save_setup(QEMUFile *f, void *opaque) - (*rsp)->f = f; - - WITH_RCU_READ_LOCK_GUARD() { -+ -+ if (memcrypt_enabled()) { -+ if (ram_encrypted_save_setup()) { -+ return -1; -+ } -+ } -+ - qemu_put_be64(f, ram_bytes_total_common(true) | RAM_SAVE_FLAG_MEM_SIZE); - - RAMBLOCK_FOREACH_MIGRATABLE(block) { -@@ -3217,6 +3366,11 @@ static int ram_save_complete(QEMUFile *f, void *opaque) - - flush_compressed_data(rs); - ram_control_after_iterate(f, RAM_CONTROL_FINISH); -+ -+ /* send the shared regions list */ -+ if (memcrypt_enabled()) { -+ ret = ram_save_shared_region_list(rs, f); -+ } - } - - if (ret < 0) { -@@ -4038,7 +4192,8 @@ static int ram_load_precopy(QEMUFile *f) - } - - if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE | -- RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) { -+ RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE | -+ RAM_SAVE_FLAG_ENCRYPTED_DATA)) { - RAMBlock *block = ram_block_from_stream(f, flags); - - host = host_from_ram_block_offset(block, addr); -@@ -4167,6 +4322,12 @@ static int ram_load_precopy(QEMUFile *f) - break; - } - break; -+ case RAM_SAVE_FLAG_ENCRYPTED_DATA: -+ if (load_encrypted_data(f, host)) { -+ error_report("Failed to load encrypted data"); -+ ret = -EINVAL; -+ } -+ break; - case RAM_SAVE_FLAG_EOS: - /* normal exit */ - multifd_recv_sync_main(); -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 30cd436ab..cc63a1aef 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -185,6 +185,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_setup = sev_save_setup, - .save_outgoing_page = sev_save_outgoing_page, - .load_incoming_page = sev_load_incoming_page, -+ .is_gfn_in_unshared_region = sev_is_gfn_in_unshared_region, - .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, - .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, - }; -@@ -1787,6 +1788,19 @@ int sev_load_incoming_shared_regions_list(QEMUFile *f) - return 0; - } - -+bool sev_is_gfn_in_unshared_region(unsigned long gfn) -+{ -+ SevGuestState *s = sev_guest; -+ struct shared_region *pos; -+ -+ QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { -+ if (gfn >= pos->gfn_start && gfn < pos->gfn_end) { -+ return false; -+ } -+ } -+ return true; -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 34814b9f2..b8ad84014 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -38,6 +38,9 @@ typedef struct SevKernelLoaderContext { - size_t cmdline_size; - } SevKernelLoaderContext; - -+#define RAM_SAVE_ENCRYPTED_PAGE 0x1 -+#define RAM_SAVE_SHARED_REGIONS_LIST 0x2 -+ - #ifdef CONFIG_SEV - bool sev_enabled(void); - bool sev_es_enabled(void); -@@ -66,6 +69,7 @@ int sev_remove_shared_regions_list(unsigned long gfn_start, - int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end); - int sev_save_outgoing_shared_regions_list(QEMUFile *f); - int sev_load_incoming_shared_regions_list(QEMUFile *f); -+bool sev_is_gfn_in_unshared_region(unsigned long gfn); - - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - --- -2.31.1 - diff --git a/1048-migration-ram-Force-encrypted-status-for-flash0-flas.patch b/1048-migration-ram-Force-encrypted-status-for-flash0-flas.patch deleted file mode 100644 index 8202afc..0000000 --- a/1048-migration-ram-Force-encrypted-status-for-flash0-flas.patch +++ /dev/null @@ -1,44 +0,0 @@ -From aae5a6ae741a985ff74b0ae7540d3c6ce3ef2fd0 Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Tue, 27 Jul 2021 18:05:25 +0000 -Subject: [PATCH 11/29] migration/ram: Force encrypted status for flash0 & - flash1 devices. - -cherry-picked from https://github.com/AMDESE/qemu/commit/803d6a4c8d. - -Currently OVMF clears the C-bit and marks NonExistent memory space -as decrypted in the page encryption bitmap. By marking the -NonExistent memory space as decrypted it gurantees any future MMIO adds -will work correctly, but this marks flash0 device space as decrypted. -At reset the SEV core will be in forced encrypted state, so this -decrypted marking of flash0 device space will cause VCPU reset to fail -as flash0 device pages will be migrated incorrectly. - -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - migration/ram.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/migration/ram.c b/migration/ram.c -index 57f2c01bf..da7a80994 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -2254,6 +2254,14 @@ static bool encrypted_test_list(RAMState *rs, RAMBlock *block, - return false; - } - -+ if (!strcmp(memory_region_name(block->mr), "system.flash0")) { -+ return true; -+ } -+ -+ if (!strcmp(memory_region_name(block->mr), "system.flash1")) { -+ return false; -+ } -+ - /* - * Translate page in ram_addr_t address space to GPA address - * space using memory region. --- -2.31.1 - diff --git a/1049-migration-for-SEV-live-migration-bump-downtime-limit.patch b/1049-migration-for-SEV-live-migration-bump-downtime-limit.patch deleted file mode 100644 index 70e9213..0000000 --- a/1049-migration-for-SEV-live-migration-bump-downtime-limit.patch +++ /dev/null @@ -1,64 +0,0 @@ -From a102d449e9601125c226cf40bc57b705bd1e3c28 Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Tue, 3 Aug 2021 16:06:27 +0000 -Subject: [PATCH 12/29] migration: for SEV live migration bump downtime limit - to 1s. - -cherry-picked from https://github.com/AMDESE/qemu/commit/b1468803a2200. - -Now, qemu has a default expected downtime of 300 ms and -SEV Live migration has a page-per-second bandwidth of 350-450 pages -( SEV Live migration being generally slow due to guest RAM pages -being migrated after encryption using the security processor ). -With this expected downtime of 300ms and 350-450 pps bandwith, -the threshold size = <1/3 of the PPS bandwidth = ~100 pages. - -Now, this threshold size is the maximum pages/bytes that can be -sent in the final completion phase of Live migration -(where the source VM is stopped) with the expected downtime. -Therefore, with the threshold size computed above, -the migration completion phase which halts the source VM -and then transfers the leftover dirty pages, -is only reached in SEV live migration case when # of dirty pages are ~100. - -The dirty-pages-rate with larger guest RAM configuration like 4G, 8G, etc. -is much higher, typically in the range of 300-400+ pages, hence, -we always remain in the "dirty-sync" phase of migration and never -reach the migration completion phase with above guest RAM configs. - -To summarize, with larger guest RAM configs, -the dirty-pages-rate > threshold_size (with the default qemu expected downtime of 300ms). - -So, the fix is to increase qemu's expected downtime. - -This is a tweakable parameter which can be set using "migrate_set_downtime". - -With a downtime of 1 second, we get a threshold size of ~350-450 pages, -which will handle the "dirty-pages-rate" of 300+ pages and complete -the migration process, so we bump the default downtime to 1s in case -of SEV live migration being active. - -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - migration/migration.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/migration/migration.c b/migration/migration.c -index 6810bcefc..27c875c6c 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -3663,6 +3663,10 @@ static void migration_update_counters(MigrationState *s, - transferred = current_bytes - s->iteration_initial_bytes; - time_spent = current_time - s->iteration_start_time; - bandwidth = (double)transferred / time_spent; -+ if (memcrypt_enabled() && -+ s->parameters.downtime_limit < 1000) { -+ s->parameters.downtime_limit = 1000; -+ } - s->threshold_size = bandwidth * s->parameters.downtime_limit; - - s->mbps = (((double) transferred * 8.0) / --- -2.31.1 - diff --git a/1050-i386-kvm-Add-support-for-MSR-filtering.patch b/1050-i386-kvm-Add-support-for-MSR-filtering.patch deleted file mode 100644 index c967cf5..0000000 --- a/1050-i386-kvm-Add-support-for-MSR-filtering.patch +++ /dev/null @@ -1,201 +0,0 @@ -From b45eabe2febd210065e964b6425f73f1d53af43e Mon Sep 17 00:00:00 2001 -From: Alexander Graf -Date: Wed, 5 Oct 2022 00:56:42 +0200 -Subject: [PATCH 13/29] i386: kvm: Add support for MSR filtering - -commit 860054d8ce4067ef2bc3deb2a98cf93350fc03e4 upstream. - -KVM has grown support to deflect arbitrary MSRs to user space since -Linux 5.10. For now we don't expect to make a lot of use of this -feature, so let's expose it the easiest way possible: With up to 16 -individually maskable MSRs. - -This patch adds a kvm_filter_msr() function that other code can call -to install a hook on KVM MSR reads or writes. - -Signed-off-by: Alexander Graf -Message-Id: <20221004225643.65036-3-agraf@csgraf.de> -Signed-off-by: Paolo Bonzini ---- - target/i386/kvm/kvm.c | 123 +++++++++++++++++++++++++++++++++++++ - target/i386/kvm/kvm_i386.h | 11 ++++ - 2 files changed, 134 insertions(+) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 5262806c4..607469fb3 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -135,6 +135,8 @@ static struct kvm_cpuid2 *cpuid_cache; - static struct kvm_cpuid2 *hv_cpuid_cache; - static struct kvm_msr_list *kvm_feature_msrs; - -+static KVMMSRHandlers msr_handlers[KVM_MSR_FILTER_MAX_RANGES]; -+ - #define BUS_LOCK_SLICE_TIME 1000000000ULL /* ns */ - static RateLimit bus_lock_ratelimit_ctrl; - -@@ -2524,6 +2526,15 @@ int kvm_arch_init(MachineState *ms, KVMState *s) - x86ms->bus_lock_ratelimit, BUS_LOCK_SLICE_TIME); - } - } -+ if (kvm_vm_check_extension(s, KVM_CAP_X86_USER_SPACE_MSR)) { -+ ret = kvm_vm_enable_cap(s, KVM_CAP_X86_USER_SPACE_MSR, 0, -+ KVM_MSR_EXIT_REASON_FILTER); -+ if (ret) { -+ error_report("Could not enable user space MSRs: %s", -+ strerror(-ret)); -+ exit(1); -+ } -+ } - - return 0; - } -@@ -4848,6 +4859,108 @@ void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg) - } - } - -+static bool kvm_install_msr_filters(KVMState *s) -+{ -+ uint64_t zero = 0; -+ struct kvm_msr_filter filter = { -+ .flags = KVM_MSR_FILTER_DEFAULT_ALLOW, -+ }; -+ int r, i, j = 0; -+ -+ for (i = 0; i < KVM_MSR_FILTER_MAX_RANGES; i++) { -+ KVMMSRHandlers *handler = &msr_handlers[i]; -+ if (handler->msr) { -+ struct kvm_msr_filter_range *range = &filter.ranges[j++]; -+ -+ *range = (struct kvm_msr_filter_range) { -+ .flags = 0, -+ .nmsrs = 1, -+ .base = handler->msr, -+ .bitmap = (__u8 *)&zero, -+ }; -+ -+ if (handler->rdmsr) { -+ range->flags |= KVM_MSR_FILTER_READ; -+ } -+ -+ if (handler->wrmsr) { -+ range->flags |= KVM_MSR_FILTER_WRITE; -+ } -+ } -+ } -+ -+ r = kvm_vm_ioctl(s, KVM_X86_SET_MSR_FILTER, &filter); -+ if (r) { -+ return false; -+ } -+ -+ return true; -+} -+ -+bool kvm_filter_msr(KVMState *s, uint32_t msr, QEMURDMSRHandler *rdmsr, -+ QEMUWRMSRHandler *wrmsr) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(msr_handlers); i++) { -+ if (!msr_handlers[i].msr) { -+ msr_handlers[i] = (KVMMSRHandlers) { -+ .msr = msr, -+ .rdmsr = rdmsr, -+ .wrmsr = wrmsr, -+ }; -+ -+ if (!kvm_install_msr_filters(s)) { -+ msr_handlers[i] = (KVMMSRHandlers) { }; -+ return false; -+ } -+ -+ return true; -+ } -+ } -+ -+ return false; -+} -+ -+static int kvm_handle_rdmsr(X86CPU *cpu, struct kvm_run *run) -+{ -+ int i; -+ bool r; -+ -+ for (i = 0; i < ARRAY_SIZE(msr_handlers); i++) { -+ KVMMSRHandlers *handler = &msr_handlers[i]; -+ if (run->msr.index == handler->msr) { -+ if (handler->rdmsr) { -+ r = handler->rdmsr(cpu, handler->msr, -+ (uint64_t *)&run->msr.data); -+ run->msr.error = r ? 0 : 1; -+ return 0; -+ } -+ } -+ } -+ -+ assert(false); -+} -+ -+static int kvm_handle_wrmsr(X86CPU *cpu, struct kvm_run *run) -+{ -+ int i; -+ bool r; -+ -+ for (i = 0; i < ARRAY_SIZE(msr_handlers); i++) { -+ KVMMSRHandlers *handler = &msr_handlers[i]; -+ if (run->msr.index == handler->msr) { -+ if (handler->wrmsr) { -+ r = handler->wrmsr(cpu, handler->msr, run->msr.data); -+ run->msr.error = r ? 0 : 1; -+ return 0; -+ } -+ } -+ } -+ -+ assert(false); -+} -+ - static bool has_sgx_provisioning; - - static bool __kvm_enable_sgx_provisioning(KVMState *s) -@@ -4947,6 +5060,16 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - /* already handled in kvm_arch_post_run */ - ret = 0; - break; -+ case KVM_EXIT_X86_RDMSR: -+ /* We only enable MSR filtering, any other exit is bogus */ -+ assert(run->msr.reason == KVM_MSR_EXIT_REASON_FILTER); -+ ret = kvm_handle_rdmsr(cpu, run); -+ break; -+ case KVM_EXIT_X86_WRMSR: -+ /* We only enable MSR filtering, any other exit is bogus */ -+ assert(run->msr.reason == KVM_MSR_EXIT_REASON_FILTER); -+ ret = kvm_handle_wrmsr(cpu, run); -+ break; - case KVM_EXIT_HYPERCALL: - ret = kvm_handle_exit_hypercall(cpu, run); - break; -diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h -index 4124912c2..2ed586c11 100644 ---- a/target/i386/kvm/kvm_i386.h -+++ b/target/i386/kvm/kvm_i386.h -@@ -54,4 +54,15 @@ uint64_t kvm_swizzle_msi_ext_dest_id(uint64_t address); - bool kvm_enable_sgx_provisioning(KVMState *s); - void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask); - -+typedef bool QEMURDMSRHandler(X86CPU *cpu, uint32_t msr, uint64_t *val); -+typedef bool QEMUWRMSRHandler(X86CPU *cpu, uint32_t msr, uint64_t val); -+typedef struct kvm_msr_handlers { -+ uint32_t msr; -+ QEMURDMSRHandler *rdmsr; -+ QEMUWRMSRHandler *wrmsr; -+} KVMMSRHandlers; -+ -+bool kvm_filter_msr(KVMState *s, uint32_t msr, QEMURDMSRHandler *rdmsr, -+ QEMUWRMSRHandler *wrmsr); -+ - #endif --- -2.31.1 - diff --git a/1051-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch b/1051-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch deleted file mode 100644 index 998be40..0000000 --- a/1051-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch +++ /dev/null @@ -1,118 +0,0 @@ -From f2f9d5860a3a32431b397f4a643de16423b5e4b3 Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Tue, 27 Jul 2021 17:59:33 +0000 -Subject: [PATCH 14/29] kvm: Add support for userspace MSR filtering and - handling of MSR_KVM_MIGRATION_CONTROL. - -cherry-picked from https://github.com/AMDESE/qemu/commit/67935c3fd5f. - -Add support for userspace MSR filtering using KVM_X86_SET_MSR_FILTER -ioctl and handling of MSRs in userspace. Currently this is only used -for SEV guests which use MSR_KVM_MIGRATION_CONTROL to indicate if the -guest is enabled and ready for migration. - -KVM arch code calls into SEV guest specific code to delete the -SEV migrate blocker which has been setup at SEV_LAUNCH_FINISH. - -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - target/i386/kvm/kvm.c | 37 +++++++++++++++++++++++++++++++++++++ - target/i386/sev.c | 6 ++++++ - target/i386/sev.h | 1 + - 3 files changed, 44 insertions(+) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 607469fb3..a833219d0 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -2330,6 +2330,32 @@ static int kvm_get_supported_msrs(KVMState *s) - return ret; - } - -+/* -+ * Currently this exit is only used by SEV guests for -+ * MSR_KVM_MIGRATION_CONTROL to indicate if the guest -+ * is ready for migration. -+ */ -+static uint64_t msr_kvm_migration_control; -+ -+static bool kvm_rdmsr_kvm_migration_control(X86CPU *cpu, uint32_t msr, -+ uint64_t *val) -+{ -+ *val = msr_kvm_migration_control; -+ -+ return true; -+} -+ -+static bool kvm_wrmsr_kvm_migration_control(X86CPU *cpu, uint32_t msr, -+ uint64_t val) -+{ -+ msr_kvm_migration_control = val; -+ -+ if (val == KVM_MIGRATION_READY) -+ sev_del_migrate_blocker(); -+ -+ return true; -+} -+ - static Notifier smram_machine_done; - static KVMMemoryListener smram_listener; - static AddressSpace smram_address_space; -@@ -2527,6 +2553,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s) - } - } - if (kvm_vm_check_extension(s, KVM_CAP_X86_USER_SPACE_MSR)) { -+ bool r; -+ - ret = kvm_vm_enable_cap(s, KVM_CAP_X86_USER_SPACE_MSR, 0, - KVM_MSR_EXIT_REASON_FILTER); - if (ret) { -@@ -2534,6 +2562,15 @@ int kvm_arch_init(MachineState *ms, KVMState *s) - strerror(-ret)); - exit(1); - } -+ -+ r = kvm_filter_msr(s, MSR_KVM_MIGRATION_CONTROL, -+ kvm_rdmsr_kvm_migration_control, -+ kvm_wrmsr_kvm_migration_control); -+ if (!r) { -+ error_report("Could not install MSR_KVM_MIGRATION_CONTROL handler: %s", -+ strerror(-ret)); -+ exit(1); -+ } - } - - return 0; -diff --git a/target/i386/sev.c b/target/i386/sev.c -index cc63a1aef..b66665021 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -890,6 +890,12 @@ sev_launch_finish(SevGuestState *sev) - migrate_add_blocker(sev_mig_blocker, &error_fatal); - } - -+void -+sev_del_migrate_blocker(void) -+{ -+ migrate_del_blocker(sev_mig_blocker); -+} -+ - static int - sev_receive_finish(SevGuestState *s) - { -diff --git a/target/i386/sev.h b/target/i386/sev.h -index b8ad84014..7e53f8461 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -70,6 +70,7 @@ int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end); - int sev_save_outgoing_shared_regions_list(QEMUFile *f); - int sev_load_incoming_shared_regions_list(QEMUFile *f); - bool sev_is_gfn_in_unshared_region(unsigned long gfn); -+void sev_del_migrate_blocker(void); - - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - --- -2.31.1 - diff --git a/1052-anolis-migration-ram-Force-encrypted-status-for-VGA-.patch b/1052-anolis-migration-ram-Force-encrypted-status-for-VGA-.patch deleted file mode 100644 index b9cfa6e..0000000 --- a/1052-anolis-migration-ram-Force-encrypted-status-for-VGA-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 1e332429c9aa4c996191ec703e3ec10a6bd459b3 Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Tue, 8 Dec 2020 22:57:46 -0500 -Subject: [PATCH 15/29] anolis: migration/ram: Force encrypted status for VGA - vram - -The VGA vram memory region act as frame buffer of VM. This memory -is decrypted in the QEMU process. For CSV VM live migration, we -should avoid memory encryption status check on VGA vram. - -Signed-off-by: hanliyang ---- - migration/ram.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/migration/ram.c b/migration/ram.c -index da7a80994..fb05ff44e 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -2262,6 +2262,10 @@ static bool encrypted_test_list(RAMState *rs, RAMBlock *block, - return false; - } - -+ if (!strcmp(memory_region_name(block->mr), "vga.vram")) { -+ return false; -+ } -+ - /* - * Translate page in ram_addr_t address space to GPA address - * space using memory region. --- -2.31.1 - diff --git a/1053-anolis-target-i386-sev-Clear-shared_regions_list-whe.patch b/1053-anolis-target-i386-sev-Clear-shared_regions_list-whe.patch deleted file mode 100644 index 9e00e54..0000000 --- a/1053-anolis-target-i386-sev-Clear-shared_regions_list-whe.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 6ff9e3e73b0a756c9a42f2df43178ef52cf5aa26 Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Sun, 16 Jan 2022 19:57:58 -0500 -Subject: [PATCH 16/29] anolis: target/i386: sev: Clear shared_regions_list - when reboot CSV Guest - -Also fix memory leak in sev_remove_shared_regions_list(). - -Signed-off-by: hanliyang ---- - target/i386/kvm/kvm.c | 6 ++++++ - target/i386/sev.c | 5 +++-- - 2 files changed, 9 insertions(+), 2 deletions(-) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index a833219d0..f0b61ec3c 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -2143,6 +2143,12 @@ void kvm_arch_reset_vcpu(X86CPU *cpu) - - hyperv_x86_synic_reset(cpu); - } -+ -+ if (cpu_is_bsp(cpu) && -+ sev_enabled() && has_map_gpa_range) { -+ sev_remove_shared_regions_list(0, -1); -+ } -+ - /* enabled by default */ - env->poll_control_msr = 1; - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index b66665021..e3eab4119 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1661,9 +1661,9 @@ int sev_load_incoming_page(QEMUFile *f, uint8_t *ptr) - int sev_remove_shared_regions_list(unsigned long start, unsigned long end) - { - SevGuestState *s = sev_guest; -- struct shared_region *pos; -+ struct shared_region *pos, *next_pos; - -- QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { -+ QTAILQ_FOREACH_SAFE(pos, &s->shared_regions_list, list, next_pos) { - unsigned long l, r; - unsigned long curr_gfn_end = pos->gfn_end; - -@@ -1677,6 +1677,7 @@ int sev_remove_shared_regions_list(unsigned long start, unsigned long end) - if (l <= r) { - if (pos->gfn_start == l && pos->gfn_end == r) { - QTAILQ_REMOVE(&s->shared_regions_list, pos, list); -+ g_free(pos); - } else if (l == pos->gfn_start) { - pos->gfn_start = r; - } else if (r == pos->gfn_end) { --- -2.31.1 - diff --git a/1054-anolis-migration-ram-Fix-calculation-of-gfn-correpon.patch b/1054-anolis-migration-ram-Fix-calculation-of-gfn-correpon.patch deleted file mode 100644 index d385706..0000000 --- a/1054-anolis-migration-ram-Fix-calculation-of-gfn-correpon.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 7a8e357130982817732272c89a53adbb13408832 Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Sun, 16 Jan 2022 20:05:02 -0500 -Subject: [PATCH 17/29] anolis: migration/ram: Fix calculation of gfn correpond - to a page in ramblock - -A RAMBlock contains a host memory region which may consist of many -discontiguous MemoryRegion in AddressSpace of a Guest, so we cannot -get gpa by MemoryRegion.addr. Since KVM memslot records the relationship -between gpa and hva, so we can pass the hva of page in RAMBlock to -kvm_phisical_memory_addr_from_host() to get the expected gpa. - -Signed-off-by: hanliyang ---- - migration/ram.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/migration/ram.c b/migration/ram.c -index fb05ff44e..33e2c9d5f 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -59,6 +59,7 @@ - - /* Defines RAM_SAVE_ENCRYPTED_PAGE and RAM_SAVE_SHARED_REGION_LIST */ - #include "target/i386/sev.h" -+#include "sysemu/kvm.h" - - #include "hw/boards.h" /* for machine_dump_guest_core() */ - -@@ -2248,6 +2249,8 @@ static bool encrypted_test_list(RAMState *rs, RAMBlock *block, - struct ConfidentialGuestMemoryEncryptionOps *ops = - cgs_class->memory_encryption_ops; - unsigned long gfn; -+ hwaddr paddr = 0; -+ int ret; - - /* ROM devices contains the unencrypted data */ - if (memory_region_is_rom(block->mr)) { -@@ -2270,7 +2273,14 @@ static bool encrypted_test_list(RAMState *rs, RAMBlock *block, - * Translate page in ram_addr_t address space to GPA address - * space using memory region. - */ -- gfn = page + (block->mr->addr >> TARGET_PAGE_BITS); -+ if (kvm_enabled()) { -+ ret = kvm_physical_memory_addr_from_host(kvm_state, -+ block->host + (page << TARGET_PAGE_BITS), &paddr); -+ if (ret == 0) { -+ return false; -+ } -+ } -+ gfn = paddr >> TARGET_PAGE_BITS; - - return ops->is_gfn_in_unshared_region(gfn); - } --- -2.31.1 - diff --git a/1055-anolis-target-i386-csv-Move-is_hygon_cpu-to-header-f.patch b/1055-anolis-target-i386-csv-Move-is_hygon_cpu-to-header-f.patch deleted file mode 100644 index 41c6269..0000000 --- a/1055-anolis-target-i386-csv-Move-is_hygon_cpu-to-header-f.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 00e7b439f3c514d8ae20c20d5f18d24d71351c7d Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Wed, 1 Nov 2023 06:00:11 +0000 -Subject: [PATCH 18/29] anolis: target/i386: csv: Move is_hygon_cpu() to header - file csv.h - -The helper function is_hygon_cpu() will be called by functions out of -target/i386/csv.c. Move it to header file csv.h so that it can be a -common helper function. - -Signed-off-by: hanliyang ---- - target/i386/csv.c | 20 -------------------- - target/i386/csv.h | 22 ++++++++++++++++++++++ - 2 files changed, 22 insertions(+), 20 deletions(-) - -diff --git a/target/i386/csv.c b/target/i386/csv.c -index d166d3775..161cad39a 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -27,28 +27,8 @@ - - CsvGuestState csv_guest = { 0 }; - --#define CPUID_VENDOR_HYGON_EBX 0x6f677948 /* "Hygo" */ --#define CPUID_VENDOR_HYGON_ECX 0x656e6975 /* "uine" */ --#define CPUID_VENDOR_HYGON_EDX 0x6e65476e /* "nGen" */ -- - #define GUEST_POLICY_CSV_BIT (1 << 6) - --static bool is_hygon_cpu(void) --{ -- uint32_t ebx = 0; -- uint32_t ecx = 0; -- uint32_t edx = 0; -- -- host_cpuid(0, 0, NULL, &ebx, &ecx, &edx); -- -- if (ebx == CPUID_VENDOR_HYGON_EBX && -- ecx == CPUID_VENDOR_HYGON_ECX && -- edx == CPUID_VENDOR_HYGON_EDX) -- return true; -- else -- return false; --} -- - int - csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) - { -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 7dc5c7536..4f5b2773c 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -16,6 +16,28 @@ - - #include "qapi/qapi-commands-misc-target.h" - -+#include "cpu.h" -+ -+#define CPUID_VENDOR_HYGON_EBX 0x6f677948 /* "Hygo" */ -+#define CPUID_VENDOR_HYGON_ECX 0x656e6975 /* "uine" */ -+#define CPUID_VENDOR_HYGON_EDX 0x6e65476e /* "nGen" */ -+ -+static __attribute__((unused)) bool is_hygon_cpu(void) -+{ -+ uint32_t ebx = 0; -+ uint32_t ecx = 0; -+ uint32_t edx = 0; -+ -+ host_cpuid(0, 0, NULL, &ebx, &ecx, &edx); -+ -+ if (ebx == CPUID_VENDOR_HYGON_EBX && -+ ecx == CPUID_VENDOR_HYGON_ECX && -+ edx == CPUID_VENDOR_HYGON_EDX) -+ return true; -+ else -+ return false; -+} -+ - #ifdef CONFIG_CSV - bool csv_enabled(void); - #else --- -2.31.1 - diff --git a/1056-anolis-target-i386-csv-Read-cert-chain-from-file-whe.patch b/1056-anolis-target-i386-csv-Read-cert-chain-from-file-whe.patch deleted file mode 100644 index 23a528c..0000000 --- a/1056-anolis-target-i386-csv-Read-cert-chain-from-file-whe.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 980dff011e266d60f8ce669a1dc14cc23b192c8b Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Mon, 13 Nov 2023 21:55:33 +0000 -Subject: [PATCH 19/29] anolis: target/i386: csv: Read cert chain from file - when prepared for CSV live migration - -The cert chain is too long when encoded with base64, use the filename -of cert chain instead of the encoded string when prepared for CSV live -migration. - -Signed-off-by: hanliyang ---- - qapi/migration.json | 24 +++++++++++++++--------- - target/i386/sev.c | 29 +++++++++++++++++++++++++---- - 2 files changed, 40 insertions(+), 13 deletions(-) - -diff --git a/qapi/migration.json b/qapi/migration.json -index bad53a2f8..8632abb20 100644 ---- a/qapi/migration.json -+++ b/qapi/migration.json -@@ -774,14 +774,16 @@ - # block device name if there is one, and to their node name - # otherwise. (Since 5.2) - # --# @sev-pdh: The target host platform diffie-hellman key encoded in base64 -+# @sev-pdh: The target host platform diffie-hellman key encoded in base64, or -+# pdh filename for hygon - # (Since 4.2) - # --# @sev-plat-cert: The target host platform certificate chain encoded in base64 -+# @sev-plat-cert: The target host platform certificate chain encoded in base64, -+# or plat cert filename for hygon - # (Since 4.2) - # - # @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in --# base64 (Since 4.2) -+# base64, or vendor cert filename for hygon (Since 4.2) - # - # Features: - # @unstable: Member @x-checkpoint-delay is experimental. -@@ -949,14 +951,16 @@ - # block device name if there is one, and to their node name - # otherwise. (Since 5.2) - # --# @sev-pdh: The target host platform diffie-hellman key encoded in base64 -+# @sev-pdh: The target host platform diffie-hellman key encoded in base64, or -+# pdh filename for hygon - # (Since 4.2) - # --# @sev-plat-cert: The target host platform certificate chain encoded in base64 -+# @sev-plat-cert: The target host platform certificate chain encoded in base64, -+# or plat cert filename for hygon - # (Since 4.2) - # - # @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in --# base64 (Since 4.2) -+# base64, or vendor cert filename for hygon (Since 4.2) - # - # Features: - # @unstable: Member @x-checkpoint-delay is experimental. -@@ -1161,14 +1165,16 @@ - # block device name if there is one, and to their node name - # otherwise. (Since 5.2) - # --# @sev-pdh: The target host platform diffie-hellman key encoded in base64 -+# @sev-pdh: The target host platform diffie-hellman key encoded in base64, or -+# pdh filename for hygon - # (Since 4.2) - # --# @sev-plat-cert: The target host platform certificate chain encoded in base64 -+# @sev-plat-cert: The target host platform certificate chain encoded in base64, -+# or plat cert filename for hygon - # (Since 4.2) - # - # @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in --# base64 (Since 4.2) -+# base64, or vendor cert filename for hygon (Since 4.2) - # - # Features: - # @unstable: Member @x-checkpoint-delay is experimental. -diff --git a/target/i386/sev.c b/target/i386/sev.c -index e3eab4119..ebe97799c 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -944,18 +944,39 @@ int sev_save_setup(const char *pdh, const char *plat_cert, - { - SevGuestState *s = sev_guest; - -- s->remote_pdh = g_base64_decode(pdh, &s->remote_pdh_len); -+ if (is_hygon_cpu()) { -+ if (sev_read_file_base64(pdh, &s->remote_pdh, -+ &s->remote_pdh_len) < 0) { -+ goto error; -+ } -+ } else { -+ s->remote_pdh = g_base64_decode(pdh, &s->remote_pdh_len); -+ } - if (!check_blob_length(s->remote_pdh_len)) { - goto error; - } - -- s->remote_plat_cert = g_base64_decode(plat_cert, -- &s->remote_plat_cert_len); -+ if (is_hygon_cpu()) { -+ if (sev_read_file_base64(plat_cert, &s->remote_plat_cert, -+ &s->remote_plat_cert_len) < 0) { -+ goto error; -+ } -+ } else { -+ s->remote_plat_cert = g_base64_decode(plat_cert, -+ &s->remote_plat_cert_len); -+ } - if (!check_blob_length(s->remote_plat_cert_len)) { - goto error; - } - -- s->amd_cert = g_base64_decode(amd_cert, &s->amd_cert_len); -+ if (is_hygon_cpu()) { -+ if (sev_read_file_base64(amd_cert, &s->amd_cert, -+ &s->amd_cert_len) < 0) { -+ goto error; -+ } -+ } else { -+ s->amd_cert = g_base64_decode(amd_cert, &s->amd_cert_len); -+ } - if (!check_blob_length(s->amd_cert_len)) { - goto error; - } --- -2.31.1 - diff --git a/1057-anolis-target-i386-csv-add-support-to-queue-the-outg.patch b/1057-anolis-target-i386-csv-add-support-to-queue-the-outg.patch deleted file mode 100644 index f6a3b3b..0000000 --- a/1057-anolis-target-i386-csv-add-support-to-queue-the-outg.patch +++ /dev/null @@ -1,270 +0,0 @@ -From 19941d177378b596a52a7905925525d68d152dea Mon Sep 17 00:00:00 2001 -From: fangbaoshun -Date: Mon, 2 Aug 2021 11:00:07 +0800 -Subject: [PATCH 20/29] anolis: target/i386: csv: add support to queue the - outgoing page into a list - -The csv_queue_outgoing_page() provide the implementation to queue the -guest private pages during transmission. The routines queues the outgoing -pages into a listi, and then issues the KVM_CSV_COMMAND_BATCH command to -encrypt the pages togather before writing them to the socket. - -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 3 + - linux-headers/linux/kvm.h | 6 + - target/i386/sev.c | 172 ++++++++++++++++++++++ - target/i386/sev.h | 2 + - 4 files changed, 183 insertions(+) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index 343f686fc..1f32519d4 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -77,6 +77,9 @@ struct ConfidentialGuestMemoryEncryptionOps { - - /* Load the shared regions list */ - int (*load_incoming_shared_regions_list)(QEMUFile *f); -+ -+ /* Queue the encrypted page and metadata associated with it into a list */ -+ int (*queue_outgoing_page)(uint8_t *ptr, uint32_t size, uint64_t addr); - }; - - typedef struct ConfidentialGuestSupportClass { -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index b640e72c8..8dd8c5e6a 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1938,6 +1938,12 @@ struct kvm_csv_init_data { - __u64 nodemask; - }; - -+struct kvm_csv_batch_list_node { -+ __u64 cmd_data_addr; -+ __u64 addr; -+ __u64 next_cmd_addr; -+}; -+ - #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) - #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) - #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) -diff --git a/target/i386/sev.c b/target/i386/sev.c -index ebe97799c..e7ff3f4dd 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -50,6 +50,15 @@ struct shared_region { - QTAILQ_ENTRY(shared_region) list; - }; - -+typedef struct CsvBatchCmdList CsvBatchCmdList; -+typedef void (*CsvDestroyCmdNodeFn) (void *data); -+ -+struct CsvBatchCmdList { -+ struct kvm_csv_batch_list_node *head; -+ struct kvm_csv_batch_list_node *tail; -+ CsvDestroyCmdNodeFn destroy_fn; -+}; -+ - extern struct sev_ops sev_ops; - - /** -@@ -96,6 +105,9 @@ struct SevGuestState { - bool reset_data_valid; - - QTAILQ_HEAD(, shared_region) shared_regions_list; -+ -+ /* link list used for HYGON CSV */ -+ CsvBatchCmdList *csv_batch_cmd_list; - }; - - #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */ -@@ -188,6 +200,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .is_gfn_in_unshared_region = sev_is_gfn_in_unshared_region, - .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, - .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, -+ .queue_outgoing_page = csv_queue_outgoing_page, - }; - - static int -@@ -1829,6 +1842,165 @@ bool sev_is_gfn_in_unshared_region(unsigned long gfn) - return true; - } - -+#include "csv.h" -+ -+static CsvBatchCmdList * -+csv_batch_cmd_list_create(struct kvm_csv_batch_list_node *head, -+ CsvDestroyCmdNodeFn func) -+{ -+ CsvBatchCmdList *csv_batch_cmd_list = -+ g_malloc0(sizeof(*csv_batch_cmd_list)); -+ -+ if (!csv_batch_cmd_list) { -+ return NULL; -+ } -+ -+ csv_batch_cmd_list->head = head; -+ csv_batch_cmd_list->tail = head; -+ csv_batch_cmd_list->destroy_fn = func; -+ -+ return csv_batch_cmd_list; -+} -+ -+static int -+csv_batch_cmd_list_add_after(CsvBatchCmdList *list, -+ struct kvm_csv_batch_list_node *new_node) -+{ -+ list->tail->next_cmd_addr = (__u64)new_node; -+ list->tail = new_node; -+ -+ return 0; -+} -+ -+static struct kvm_csv_batch_list_node * -+csv_batch_cmd_list_node_create(uint64_t cmd_data_addr, uint64_t addr) -+{ -+ struct kvm_csv_batch_list_node *new_node = -+ g_malloc0(sizeof(struct kvm_csv_batch_list_node)); -+ -+ if (!new_node) { -+ return NULL; -+ } -+ -+ new_node->cmd_data_addr = cmd_data_addr; -+ new_node->addr = addr; -+ new_node->next_cmd_addr = 0; -+ -+ return new_node; -+} -+ -+static int csv_batch_cmd_list_destroy(CsvBatchCmdList *list) -+{ -+ struct kvm_csv_batch_list_node *node = list->head; -+ -+ while (node != NULL) { -+ if (list->destroy_fn != NULL) -+ list->destroy_fn((void *)node->cmd_data_addr); -+ -+ list->head = (struct kvm_csv_batch_list_node *)node->next_cmd_addr; -+ g_free(node); -+ node = list->head; -+ } -+ -+ g_free(list); -+ return 0; -+} -+ -+static void send_update_data_free(void *data) -+{ -+ struct kvm_sev_send_update_data *update = -+ (struct kvm_sev_send_update_data *)data; -+ g_free((guchar *)update->hdr_uaddr); -+ g_free((guchar *)update->trans_uaddr); -+ g_free(update); -+} -+ -+static int -+csv_send_queue_data(SevGuestState *s, uint8_t *ptr, -+ uint32_t size, uint64_t addr) -+{ -+ int ret = 0; -+ int fw_error; -+ guchar *trans; -+ guchar *packet_hdr; -+ struct kvm_sev_send_update_data *update; -+ struct kvm_csv_batch_list_node *new_node = NULL; -+ -+ /* If this is first call then query the packet header bytes and allocate -+ * the packet buffer. -+ */ -+ if (s->send_packet_hdr_len < 1) { -+ s->send_packet_hdr_len = sev_send_get_packet_len(&fw_error); -+ if (s->send_packet_hdr_len < 1) { -+ error_report("%s: SEND_UPDATE fw_error=%d '%s'", -+ __func__, fw_error, fw_error_to_str(fw_error)); -+ return 1; -+ } -+ } -+ -+ packet_hdr = g_new(guchar, s->send_packet_hdr_len); -+ memset(packet_hdr, 0, s->send_packet_hdr_len); -+ -+ update = g_new0(struct kvm_sev_send_update_data, 1); -+ -+ /* allocate transport buffer */ -+ trans = g_new(guchar, size); -+ -+ update->hdr_uaddr = (unsigned long)packet_hdr; -+ update->hdr_len = s->send_packet_hdr_len; -+ update->guest_uaddr = (unsigned long)ptr; -+ update->guest_len = size; -+ update->trans_uaddr = (unsigned long)trans; -+ update->trans_len = size; -+ -+ new_node = csv_batch_cmd_list_node_create((uint64_t)update, addr); -+ if (!new_node) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ if (s->csv_batch_cmd_list == NULL) { -+ s->csv_batch_cmd_list = csv_batch_cmd_list_create(new_node, -+ send_update_data_free); -+ if (s->csv_batch_cmd_list == NULL) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ } else { -+ /* Add new_node's command address to the last_node */ -+ csv_batch_cmd_list_add_after(s->csv_batch_cmd_list, new_node); -+ } -+ -+ trace_kvm_sev_send_update_data(ptr, trans, size); -+ -+ return ret; -+ -+err: -+ g_free(trans); -+ g_free(update); -+ g_free(packet_hdr); -+ g_free(new_node); -+ if (s->csv_batch_cmd_list) { -+ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list); -+ s->csv_batch_cmd_list = NULL; -+ } -+ return ret; -+} -+ -+int -+csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) -+{ -+ SevGuestState *s = sev_guest; -+ -+ /* Only support for HYGON CSV */ -+ if (!is_hygon_cpu()) { -+ error_report("Only support enqueue pages for HYGON CSV"); -+ return -EINVAL; -+ } -+ -+ return csv_send_queue_data(s, ptr, sz, addr); -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 7e53f8461..1eba67bcf 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -74,6 +74,8 @@ void sev_del_migrate_blocker(void); - - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - -+int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); -+ - struct sev_ops { - int (*sev_ioctl)(int fd, int cmd, void *data, int *error); - const char *(*fw_error_to_str)(int code); --- -2.31.1 - diff --git a/1058-anolis-target-i386-csv-add-support-to-encrypt-the-ou.patch b/1058-anolis-target-i386-csv-add-support-to-encrypt-the-ou.patch deleted file mode 100644 index 393b474..0000000 --- a/1058-anolis-target-i386-csv-add-support-to-encrypt-the-ou.patch +++ /dev/null @@ -1,204 +0,0 @@ -From 500646168eb4dc297d01dbc35759e38d0206a3b6 Mon Sep 17 00:00:00 2001 -From: fangbaoshun -Date: Mon, 2 Aug 2021 11:41:58 +0800 -Subject: [PATCH 21/29] anolis: target/i386: csv: add support to encrypt the - outgoing pages in the list queued before. - -The csv_save_queued_outgoing_pages() provide the implementation to encrypt -the guest private pages during transmission. The routines uses SEND_START -command to create the outgoing encryption context on the first call then -uses COMMAND_BATCH command to send the SEND_UPDATE_DATA commands queued -in the list to encrypt the data before writing it to the socket. While -encrypting the data SEND_UPDATE_DATA produces some metadata (e.g MAC, IV). -The metadata is also sent to the target machine. After migration is completed, -we issue the SEND_FINISH command to transition the SEV guest state from sending -to unrunnable state. - -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 4 + - linux-headers/linux/kvm.h | 8 ++ - target/i386/sev.c | 89 +++++++++++++++++++++++ - target/i386/sev.h | 4 + - 4 files changed, 105 insertions(+) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index 1f32519d4..1ff4823b6 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -80,6 +80,10 @@ struct ConfidentialGuestMemoryEncryptionOps { - - /* Queue the encrypted page and metadata associated with it into a list */ - int (*queue_outgoing_page)(uint8_t *ptr, uint32_t size, uint64_t addr); -+ -+ /* Write the list queued with encrypted pages and metadata associated -+ * with them */ -+ int (*save_queued_outgoing_pages)(QEMUFile *f, uint64_t *bytes_sent); - }; - - typedef struct ConfidentialGuestSupportClass { -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 8dd8c5e6a..951afc8b2 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1823,6 +1823,9 @@ enum sev_cmd_id { - /* Guest Migration Extension */ - KVM_SEV_SEND_CANCEL, - -+ /* Hygon CSV batch command */ -+ KVM_CSV_COMMAND_BATCH = 0x18, -+ - KVM_SEV_NR_MAX, - }; - -@@ -1944,6 +1947,11 @@ struct kvm_csv_batch_list_node { - __u64 next_cmd_addr; - }; - -+struct kvm_csv_command_batch { -+ __u32 command_id; -+ __u64 csv_batch_list_uaddr; -+}; -+ - #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) - #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) - #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) -diff --git a/target/i386/sev.c b/target/i386/sev.c -index e7ff3f4dd..6ff547a23 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -201,6 +201,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, - .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, - .queue_outgoing_page = csv_queue_outgoing_page, -+ .save_queued_outgoing_pages = csv_save_queued_outgoing_pages, - }; - - static int -@@ -1987,6 +1988,70 @@ err: - return ret; - } - -+static int -+csv_command_batch(uint32_t cmd_id, uint64_t head_uaddr, int *fw_err) -+{ -+ int ret; -+ struct kvm_csv_command_batch command_batch = { }; -+ -+ command_batch.command_id = cmd_id; -+ command_batch.csv_batch_list_uaddr = head_uaddr; -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_CSV_COMMAND_BATCH, -+ &command_batch, fw_err); -+ if (ret) { -+ error_report("%s: COMMAND_BATCH ret=%d fw_err=%d '%s'", -+ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); -+ } -+ -+ return ret; -+} -+ -+static int -+csv_send_update_data_batch(SevGuestState *s, QEMUFile *f, uint64_t *bytes_sent) -+{ -+ int ret, fw_error = 0; -+ struct kvm_sev_send_update_data *update; -+ struct kvm_csv_batch_list_node *node; -+ -+ ret = csv_command_batch(KVM_SEV_SEND_UPDATE_DATA, -+ (uint64_t)s->csv_batch_cmd_list->head, &fw_error); -+ if (ret) { -+ error_report("%s: csv_command_batch ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ *bytes_sent = 0; -+ for (node = s->csv_batch_cmd_list->head; -+ node != NULL; -+ node = (struct kvm_csv_batch_list_node *)node->next_cmd_addr) { -+ if (node != s->csv_batch_cmd_list->head) { -+ /* head's page header is saved before send_update_data */ -+ qemu_put_be64(f, node->addr); -+ *bytes_sent += 8; -+ if (node->next_cmd_addr != 0) -+ qemu_put_be32(f, RAM_SAVE_ENCRYPTED_PAGE_BATCH); -+ else -+ qemu_put_be32(f, RAM_SAVE_ENCRYPTED_PAGE_BATCH_END); -+ *bytes_sent += 4; -+ } -+ update = (struct kvm_sev_send_update_data *)node->cmd_data_addr; -+ qemu_put_be32(f, update->hdr_len); -+ qemu_put_buffer(f, (uint8_t *)update->hdr_uaddr, update->hdr_len); -+ *bytes_sent += (4 + update->hdr_len); -+ -+ qemu_put_be32(f, update->trans_len); -+ qemu_put_buffer(f, (uint8_t *)update->trans_uaddr, update->trans_len); -+ *bytes_sent += (4 + update->trans_len); -+ } -+ -+err: -+ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list); -+ s->csv_batch_cmd_list = NULL; -+ return ret; -+} -+ - int - csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) - { -@@ -2001,6 +2066,30 @@ csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) - return csv_send_queue_data(s, ptr, sz, addr); - } - -+int -+csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) -+{ -+ SevGuestState *s = sev_guest; -+ -+ /* Only support for HYGON CSV */ -+ if (!is_hygon_cpu()) { -+ error_report("Only support transfer queued pages for HYGON CSV"); -+ return -EINVAL; -+ } -+ -+ /* -+ * If this is a first buffer then create outgoing encryption context -+ * and write our PDH, policy and session data. -+ */ -+ if (!sev_check_state(s, SEV_STATE_SEND_UPDATE) && -+ sev_send_start(s, f, bytes_sent)) { -+ error_report("Failed to create outgoing context"); -+ return 1; -+ } -+ -+ return csv_send_update_data_batch(s, f, bytes_sent); -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 1eba67bcf..37ed17f32 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -41,6 +41,9 @@ typedef struct SevKernelLoaderContext { - #define RAM_SAVE_ENCRYPTED_PAGE 0x1 - #define RAM_SAVE_SHARED_REGIONS_LIST 0x2 - -+#define RAM_SAVE_ENCRYPTED_PAGE_BATCH 0x4 -+#define RAM_SAVE_ENCRYPTED_PAGE_BATCH_END 0x5 -+ - #ifdef CONFIG_SEV - bool sev_enabled(void); - bool sev_es_enabled(void); -@@ -75,6 +78,7 @@ void sev_del_migrate_blocker(void); - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - - int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); -+int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); - - struct sev_ops { - int (*sev_ioctl)(int fd, int cmd, void *data, int *error); --- -2.31.1 - diff --git a/1059-anolis-target-i386-csv-add-support-to-queue-the-inco.patch b/1059-anolis-target-i386-csv-add-support-to-queue-the-inco.patch deleted file mode 100644 index cc70aac..0000000 --- a/1059-anolis-target-i386-csv-add-support-to-queue-the-inco.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 8af625f3b5f4d2eb768b1eee2dc2e7938800d47e Mon Sep 17 00:00:00 2001 -From: fangbaoshun -Date: Mon, 2 Aug 2021 13:49:48 +0800 -Subject: [PATCH 22/29] anolis: target/i386: csv: add support to queue the - incoming page into a list - -The csv_queue_incoming_page() provide the implementation to queue the -guest private pages during transmission. The routines queues the incoming -socket which contains the guest private pages into a list then uses the -COMMAND_BATCH command to load the encrypted pages into the guest memory. - -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 3 + - target/i386/sev.c | 92 +++++++++++++++++++++++ - target/i386/sev.h | 1 + - 3 files changed, 96 insertions(+) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index 1ff4823b6..530b5057b 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -84,6 +84,9 @@ struct ConfidentialGuestMemoryEncryptionOps { - /* Write the list queued with encrypted pages and metadata associated - * with them */ - int (*save_queued_outgoing_pages)(QEMUFile *f, uint64_t *bytes_sent); -+ -+ /* Queue the incoming encrypted page into a list */ -+ int (*queue_incoming_page)(QEMUFile *f, uint8_t *ptr); - }; - - typedef struct ConfidentialGuestSupportClass { -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 6ff547a23..e235fb207 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -202,6 +202,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, - .queue_outgoing_page = csv_queue_outgoing_page, - .save_queued_outgoing_pages = csv_save_queued_outgoing_pages, -+ .queue_incoming_page = csv_queue_incoming_page, - }; - - static int -@@ -1916,6 +1917,15 @@ static void send_update_data_free(void *data) - g_free(update); - } - -+static void receive_update_data_free(void *data) -+{ -+ struct kvm_sev_receive_update_data *update = -+ (struct kvm_sev_receive_update_data *)data; -+ g_free((guchar *)update->hdr_uaddr); -+ g_free((guchar *)update->trans_uaddr); -+ g_free(update); -+} -+ - static int - csv_send_queue_data(SevGuestState *s, uint8_t *ptr, - uint32_t size, uint64_t addr) -@@ -1988,6 +1998,66 @@ err: - return ret; - } - -+static int -+csv_receive_queue_data(SevGuestState *s, QEMUFile *f, uint8_t *ptr) -+{ -+ int ret = 0; -+ gchar *hdr = NULL, *trans = NULL; -+ struct kvm_sev_receive_update_data *update; -+ struct kvm_csv_batch_list_node *new_node = NULL; -+ -+ update = g_new0(struct kvm_sev_receive_update_data, 1); -+ /* get packet header */ -+ update->hdr_len = qemu_get_be32(f); -+ hdr = g_new(gchar, update->hdr_len); -+ qemu_get_buffer(f, (uint8_t *)hdr, update->hdr_len); -+ update->hdr_uaddr = (unsigned long)hdr; -+ -+ /* get transport buffer */ -+ update->trans_len = qemu_get_be32(f); -+ trans = g_new(gchar, update->trans_len); -+ update->trans_uaddr = (unsigned long)trans; -+ qemu_get_buffer(f, (uint8_t *)update->trans_uaddr, update->trans_len); -+ -+ /* set guest address,guest len is page_size */ -+ update->guest_uaddr = (uint64_t)ptr; -+ update->guest_len = TARGET_PAGE_SIZE; -+ -+ new_node = csv_batch_cmd_list_node_create((uint64_t)update, 0); -+ if (!new_node) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ if (s->csv_batch_cmd_list == NULL) { -+ s->csv_batch_cmd_list = csv_batch_cmd_list_create(new_node, -+ receive_update_data_free); -+ if (s->csv_batch_cmd_list == NULL) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ } else { -+ /* Add new_node's command address to the last_node */ -+ csv_batch_cmd_list_add_after(s->csv_batch_cmd_list, new_node); -+ } -+ -+ trace_kvm_sev_receive_update_data(trans, (void *)ptr, update->guest_len, -+ (void *)hdr, update->hdr_len); -+ -+ return ret; -+ -+err: -+ g_free(trans); -+ g_free(update); -+ g_free(hdr); -+ g_free(new_node); -+ if (s->csv_batch_cmd_list) { -+ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list); -+ s->csv_batch_cmd_list = NULL; -+ } -+ return ret; -+} -+ - static int - csv_command_batch(uint32_t cmd_id, uint64_t head_uaddr, int *fw_err) - { -@@ -2066,6 +2136,28 @@ csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) - return csv_send_queue_data(s, ptr, sz, addr); - } - -+int csv_queue_incoming_page(QEMUFile *f, uint8_t *ptr) -+{ -+ SevGuestState *s = sev_guest; -+ -+ /* Only support for HYGON CSV */ -+ if (!is_hygon_cpu()) { -+ error_report("Only support enqueue received pages for HYGON CSV"); -+ return -EINVAL; -+ } -+ -+ /* -+ * If this is first buffer and SEV is not in recieiving state then -+ * use RECEIVE_START command to create a encryption context. -+ */ -+ if (!sev_check_state(s, SEV_STATE_RECEIVE_UPDATE) && -+ sev_receive_start(s, f)) { -+ return 1; -+ } -+ -+ return csv_receive_queue_data(s, f, ptr); -+} -+ - int - csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) - { -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 37ed17f32..6166be420 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -79,6 +79,7 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - - int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); - int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); -+int csv_queue_incoming_page(QEMUFile *f, uint8_t *ptr); - - struct sev_ops { - int (*sev_ioctl)(int fd, int cmd, void *data, int *error); --- -2.31.1 - diff --git a/1060-anolis-target-i386-csv-add-support-to-load-incoming-.patch b/1060-anolis-target-i386-csv-add-support-to-load-incoming-.patch deleted file mode 100644 index f54f872..0000000 --- a/1060-anolis-target-i386-csv-add-support-to-load-incoming-.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 8949b2ac9cc6d9a59a482ca76f81a417c9c38e6d Mon Sep 17 00:00:00 2001 -From: fangbaoshun -Date: Mon, 2 Aug 2021 14:11:43 +0800 -Subject: [PATCH 23/29] anolis: target/i386: csv: add support to load incoming - encrypted pages queued in the CMD list - -The csv_load_queued_incoming_pages() provide the implementation to read the -incoming guest private pages from the socket queued in the CMD list and load -them into the guest memory. The routines uses the RECEIVE_START command to -create the incoming encryption context on the first call then uses the -COMMAND_BATCH carried with RECEIEVE_UPDATE_DATA commands to load the encrypted -pages into the guest memory. After migration is completed, we issue the -RECEIVE_FINISH command to transition the SEV guest to the runnable state -so that it can be executed. - -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 3 +++ - target/i386/sev.c | 32 +++++++++++++++++++++++ - target/i386/sev.h | 1 + - 3 files changed, 36 insertions(+) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index 530b5057b..f6a30fab3 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -87,6 +87,9 @@ struct ConfidentialGuestMemoryEncryptionOps { - - /* Queue the incoming encrypted page into a list */ - int (*queue_incoming_page)(QEMUFile *f, uint8_t *ptr); -+ -+ /* Load the incoming encrypted pages queued in list into guest memory */ -+ int (*load_queued_incoming_pages)(QEMUFile *f); - }; - - typedef struct ConfidentialGuestSupportClass { -diff --git a/target/i386/sev.c b/target/i386/sev.c -index e235fb207..2f7d98be6 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -203,6 +203,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .queue_outgoing_page = csv_queue_outgoing_page, - .save_queued_outgoing_pages = csv_save_queued_outgoing_pages, - .queue_incoming_page = csv_queue_incoming_page, -+ .load_queued_incoming_pages = csv_load_queued_incoming_pages, - }; - - static int -@@ -2122,6 +2123,24 @@ err: - return ret; - } - -+static int -+csv_receive_update_data_batch(SevGuestState *s) -+{ -+ int ret; -+ int fw_error; -+ -+ ret = csv_command_batch(KVM_SEV_RECEIVE_UPDATE_DATA, -+ (uint64_t)s->csv_batch_cmd_list->head, &fw_error); -+ if (ret) { -+ error_report("%s: csv_command_batch ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ } -+ -+ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list); -+ s->csv_batch_cmd_list = NULL; -+ return ret; -+} -+ - int - csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) - { -@@ -2182,6 +2201,19 @@ csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) - return csv_send_update_data_batch(s, f, bytes_sent); - } - -+int csv_load_queued_incoming_pages(QEMUFile *f) -+{ -+ SevGuestState *s = sev_guest; -+ -+ /* Only support for HYGON CSV */ -+ if (!is_hygon_cpu()) { -+ error_report("Only support load queued pages for HYGON CSV"); -+ return -EINVAL; -+ } -+ -+ return csv_receive_update_data_batch(s); -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 6166be420..c53f96b04 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -80,6 +80,7 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); - int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); - int csv_queue_incoming_page(QEMUFile *f, uint8_t *ptr); -+int csv_load_queued_incoming_pages(QEMUFile *f); - - struct sev_ops { - int (*sev_ioctl)(int fd, int cmd, void *data, int *error); --- -2.31.1 - diff --git a/1061-anolis-migration-ram-Accelerate-the-transmission-of-.patch b/1061-anolis-migration-ram-Accelerate-the-transmission-of-.patch deleted file mode 100644 index a065a0e..0000000 --- a/1061-anolis-migration-ram-Accelerate-the-transmission-of-.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 379463820571f9ca239e68f2f5f588634b96bbff Mon Sep 17 00:00:00 2001 -From: fangbaoshun -Date: Mon, 2 Aug 2021 14:35:51 +0800 -Subject: [PATCH 24/29] anolis: migration/ram: Accelerate the transmission of - CSV guest's encrypted pages - -When memory encryption is enabled, the guest memory will be encrypted with -the guest specific key. The patch introduces an accelerate solution which -queued the pages into list and send them togather by COMMAND_BATCH. - -Signed-off-by: hanliyang ---- - configs/devices/i386-softmmu/default.mak | 1 + - hw/i386/Kconfig | 5 ++ - migration/ram.c | 106 +++++++++++++++++++++++ - target/i386/csv.h | 11 +++ - target/i386/sev.h | 1 + - 5 files changed, 124 insertions(+) - -diff --git a/configs/devices/i386-softmmu/default.mak b/configs/devices/i386-softmmu/default.mak -index db83ffcab..e948e54e4 100644 ---- a/configs/devices/i386-softmmu/default.mak -+++ b/configs/devices/i386-softmmu/default.mak -@@ -24,6 +24,7 @@ - #CONFIG_VTD=n - #CONFIG_SGX=n - #CONFIG_CSV=n -+#CONFIG_HYGON_CSV_MIG_ACCEL=n - - # Boards: - # -diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig -index ed35d762b..8876b360b 100644 ---- a/hw/i386/Kconfig -+++ b/hw/i386/Kconfig -@@ -4,6 +4,7 @@ config X86_FW_OVMF - config SEV - bool - select X86_FW_OVMF -+ select HYGON_CSV_MIG_ACCEL - depends on KVM - - config SGX -@@ -14,6 +15,10 @@ config CSV - bool - depends on SEV - -+config HYGON_CSV_MIG_ACCEL -+ bool -+ depends on SEV -+ - config PC - bool - imply APPLESMC -diff --git a/migration/ram.c b/migration/ram.c -index 33e2c9d5f..7e2d4e7df 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -59,6 +59,7 @@ - - /* Defines RAM_SAVE_ENCRYPTED_PAGE and RAM_SAVE_SHARED_REGION_LIST */ - #include "target/i386/sev.h" -+#include "target/i386/csv.h" - #include "sysemu/kvm.h" - - #include "hw/boards.h" /* for machine_dump_guest_core() */ -@@ -2348,6 +2349,99 @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss, - return ram_save_page(rs, pss, last_stage); - } - -+#ifdef CONFIG_HYGON_CSV_MIG_ACCEL -+/** -+ * ram_save_encrypted_pages_in_batch - send the given encrypted pages to -+ * the stream. -+ */ -+static int -+ram_save_encrypted_pages_in_batch(RAMState *rs, PageSearchStatus *pss, bool last_stage) -+{ -+ int ret; -+ int tmppages = 0, pages = 0; -+ RAMBlock *block = pss->block; -+ ram_addr_t offset = pss->page << TARGET_PAGE_BITS; -+ ram_addr_t start_offset = 0; -+ uint32_t host_len = 0; -+ uint8_t *p; -+ uint64_t bytes_xmit; -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *)object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ -+ do { -+ /* Check the pages is dirty and if it is send it */ -+ if (!migration_bitmap_clear_dirty(rs, block, pss->page)) { -+ pss->page++; -+ continue; -+ } -+ -+ /* Process the unencrypted page */ -+ if (!encrypted_test_list(rs, block, pss->page)) { -+ tmppages = ram_save_target_page(rs, pss, last_stage); -+ } else { -+ /* Caculate the offset and host virtual address of the page */ -+ offset = pss->page << TARGET_PAGE_BITS; -+ p = block->host + offset; -+ -+ /* Record the offset and host virtual address of the first -+ * page in this loop which will be used below. -+ */ -+ if (host_len == 0) { -+ start_offset = offset | RAM_SAVE_FLAG_ENCRYPTED_DATA; -+ } else { -+ offset |= (RAM_SAVE_FLAG_ENCRYPTED_DATA | RAM_SAVE_FLAG_CONTINUE); -+ } -+ -+ /* Queue the outgoing page if the page is not zero page. -+ * If the queued pages are up to the outgoing page window size, -+ * process them below. -+ */ -+ if (ops->queue_outgoing_page(p, TARGET_PAGE_SIZE, offset)) -+ return -1; -+ -+ tmppages = 1; -+ host_len += TARGET_PAGE_SIZE; -+ ram_counters.normal++; -+ } -+ -+ if (tmppages < 0) { -+ return tmppages; -+ } -+ -+ pages += tmppages; -+ -+ pss->page++; -+ } while (offset_in_ramblock(block, pss->page << TARGET_PAGE_BITS) && -+ host_len < CSV_OUTGOING_PAGE_WINDOW_SIZE); -+ -+ /* Check if there are any queued pages */ -+ if (host_len != 0) { -+ ram_counters.transferred += -+ save_page_header(rs, rs->f, block, start_offset); -+ /* if only one page queued, flag is BATCH_END, else flag is BATCH */ -+ if (host_len > TARGET_PAGE_SIZE) -+ qemu_put_be32(rs->f, RAM_SAVE_ENCRYPTED_PAGE_BATCH); -+ else -+ qemu_put_be32(rs->f, RAM_SAVE_ENCRYPTED_PAGE_BATCH_END); -+ ram_counters.transferred += 4; -+ /* Process the queued pages in batch */ -+ ret = ops->save_queued_outgoing_pages(rs->f, &bytes_xmit); -+ if (ret) { -+ return -1; -+ } -+ ram_counters.transferred += bytes_xmit; -+ } -+ -+ /* The offset we leave with is the last one we looked at */ -+ pss->page--; -+ -+ return pages; -+} -+#endif -+ - /** - * ram_save_host_page: save a whole host page - * -@@ -2382,6 +2476,18 @@ static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss, - return 0; - } - -+#ifdef CONFIG_HYGON_CSV_MIG_ACCEL -+ /* -+ * If command_batch function is enabled and memory encryption is enabled -+ * then use command batch APIs to accelerate the sending process -+ * to write the outgoing buffer to the wire. The encryption APIs -+ * will re-encrypt the data with transport key so that data is prototect -+ * on the wire. -+ */ -+ if (memcrypt_enabled() && is_hygon_cpu() && !migration_in_postcopy()) -+ return ram_save_encrypted_pages_in_batch(rs, pss, last_stage); -+#endif -+ - do { - /* Check the pages is dirty and if it is send it */ - if (migration_bitmap_clear_dirty(rs, pss->block, pss->page)) { -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 4f5b2773c..e51cc8302 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -16,6 +16,8 @@ - - #include "qapi/qapi-commands-misc-target.h" - -+#ifdef CONFIG_SEV -+ - #include "cpu.h" - - #define CPUID_VENDOR_HYGON_EBX 0x6f677948 /* "Hygo" */ -@@ -38,6 +40,15 @@ static __attribute__((unused)) bool is_hygon_cpu(void) - return false; - } - -+#else -+ -+static __attribute__((unused)) bool is_hygon_cpu(void) -+{ -+ return false; -+} -+ -+#endif -+ - #ifdef CONFIG_CSV - bool csv_enabled(void); - #else -diff --git a/target/i386/sev.h b/target/i386/sev.h -index c53f96b04..345dffac5 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -43,6 +43,7 @@ typedef struct SevKernelLoaderContext { - - #define RAM_SAVE_ENCRYPTED_PAGE_BATCH 0x4 - #define RAM_SAVE_ENCRYPTED_PAGE_BATCH_END 0x5 -+#define CSV_OUTGOING_PAGE_WINDOW_SIZE (4094 * TARGET_PAGE_SIZE) - - #ifdef CONFIG_SEV - bool sev_enabled(void); --- -2.31.1 - diff --git a/1062-anolis-migration-ram-Accelerate-the-loading-of-CSV-g.patch b/1062-anolis-migration-ram-Accelerate-the-loading-of-CSV-g.patch deleted file mode 100644 index 56c11eb..0000000 --- a/1062-anolis-migration-ram-Accelerate-the-loading-of-CSV-g.patch +++ /dev/null @@ -1,37 +0,0 @@ -From e9b70bcaf165cb163304ba68a1b1db078489d9e0 Mon Sep 17 00:00:00 2001 -From: fangbaoshun -Date: Mon, 2 Aug 2021 14:49:45 +0800 -Subject: [PATCH 25/29] anolis: migration/ram: Accelerate the loading of CSV - guest's encrypted pages - -When memory encryption is enabled, the guest memory will be encrypted with -the guest specific key. The patch introduces an accelerate solution which -queued the pages into list and load them togather by COMMAND_BATCH. - -Signed-off-by: hanliyang ---- - migration/ram.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/migration/ram.c b/migration/ram.c -index 7e2d4e7df..90f1bda83 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -1387,6 +1387,14 @@ static int load_encrypted_data(QEMUFile *f, uint8_t *ptr) - return ops->load_incoming_page(f, ptr); - } else if (flag == RAM_SAVE_SHARED_REGIONS_LIST) { - return ops->load_incoming_shared_regions_list(f); -+ } else if (flag == RAM_SAVE_ENCRYPTED_PAGE_BATCH) { -+ return ops->queue_incoming_page(f, ptr); -+ } else if (flag == RAM_SAVE_ENCRYPTED_PAGE_BATCH_END) { -+ if (ops->queue_incoming_page(f, ptr)) { -+ error_report("Failed to queue incoming data"); -+ return -EINVAL; -+ } -+ return ops->load_queued_incoming_pages(f); - } else { - error_report("unknown encrypted flag %x", flag); - return 1; --- -2.31.1 - diff --git a/1063-anolis-target-i386-csv-Add-support-for-migrate-VMSA-.patch b/1063-anolis-target-i386-csv-Add-support-for-migrate-VMSA-.patch deleted file mode 100644 index 166fb58..0000000 --- a/1063-anolis-target-i386-csv-Add-support-for-migrate-VMSA-.patch +++ /dev/null @@ -1,416 +0,0 @@ -From 133fe2e6a250623ccc9305fdacc1e8d990878fb4 Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Tue, 7 Jun 2022 15:19:32 +0800 -Subject: [PATCH 26/29] anolis: target/i386/csv: Add support for migrate VMSA - for CSV2 guest - -CSV2 can protect guest's cpu state through memory encryption. Each -vcpu has its corresponding memory, which is also called VMSA, and -is encrypted by guest's specific encrytion key. - -When CSV2 guest exit to host, the vcpu's state will be encrypted -and saved to VMSA, and the VMSA will be decrypted and loaded to cpu -when the guest's vcpu running at next time. - -If user wants to migrate one CSV2 guest to target machine, the VMSA -of the vcpus also should be migrated to target. CSV firmware provides -SEND_UPDATE_VMSA/RECEIVE_UPDATE_VMSA API through which VMSA can be -converted into secure data and transmitted to the remote end (for -example, network transmission). - -The migration of cpu state is identified by CPUState.cpu_index which -may not equals to vcpu id from KVM's perspective. - -When migrate the VMSA, the source QEMU will invoke SEND_UPDATE_VMSA to -generate data correspond to VMSA, after target QEMU received the data, -it will calc target vcpu id in the KVM by CPUState.cpu_index, and then -invoke RECEIVE_UPDATE_VMSA to restore VMSA correspond to vcpu. - -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 6 + - linux-headers/linux/kvm.h | 16 ++ - migration/ram.c | 30 ++++ - target/i386/sev.c | 196 ++++++++++++++++++++++ - target/i386/sev.h | 3 + - target/i386/trace-events | 2 + - 6 files changed, 253 insertions(+) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index f6a30fab3..a069bad9d 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -90,6 +90,12 @@ struct ConfidentialGuestMemoryEncryptionOps { - - /* Load the incoming encrypted pages queued in list into guest memory */ - int (*load_queued_incoming_pages)(QEMUFile *f); -+ -+ /* Write the encrypted cpu state */ -+ int (*save_outgoing_cpu_state)(QEMUFile *f); -+ -+ /* Load the encrypted cpu state */ -+ int (*load_incoming_cpu_state)(QEMUFile *f); - }; - - typedef struct ConfidentialGuestSupportClass { -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 951afc8b2..e5d282c75 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1904,6 +1904,14 @@ struct kvm_sev_send_update_data { - __u32 trans_len; - }; - -+struct kvm_sev_send_update_vmsa { -+ __u32 vcpu_id; -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+}; -+ - struct kvm_sev_receive_start { - __u32 handle; - __u32 policy; -@@ -1922,6 +1930,14 @@ struct kvm_sev_receive_update_data { - __u32 trans_len; - }; - -+struct kvm_sev_receive_update_vmsa { -+ __u32 vcpu_id; -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+}; -+ - /* CSV command */ - enum csv_cmd_id { - KVM_CSV_NR_MIN = 0xc0, -diff --git a/migration/ram.c b/migration/ram.c -index 90f1bda83..8c61eecb9 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -1371,6 +1371,23 @@ static int ram_save_shared_region_list(RAMState *rs, QEMUFile *f) - return ops->save_outgoing_shared_regions_list(rs->f); - } - -+/** -+ * ram_save_encrypted_cpu_state: send the encrypted cpu state -+ */ -+static int ram_save_encrypted_cpu_state(RAMState *rs, QEMUFile *f) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ -+ save_page_header(rs, rs->f, rs->last_seen_block, -+ RAM_SAVE_FLAG_ENCRYPTED_DATA); -+ qemu_put_be32(rs->f, RAM_SAVE_ENCRYPTED_CPU_STATE); -+ return ops->save_outgoing_cpu_state(rs->f); -+} -+ - static int load_encrypted_data(QEMUFile *f, uint8_t *ptr) - { - MachineState *ms = MACHINE(qdev_get_machine()); -@@ -1395,6 +1412,8 @@ static int load_encrypted_data(QEMUFile *f, uint8_t *ptr) - return -EINVAL; - } - return ops->load_queued_incoming_pages(f); -+ } else if (flag == RAM_SAVE_ENCRYPTED_CPU_STATE) { -+ return ops->load_incoming_cpu_state(f); - } else { - error_report("unknown encrypted flag %x", flag); - return 1; -@@ -3507,6 +3526,17 @@ static int ram_save_complete(QEMUFile *f, void *opaque) - if (memcrypt_enabled()) { - ret = ram_save_shared_region_list(rs, f); - } -+ -+ /* -+ * send the encrypted cpu state, for example, CSV2 guest's -+ * vmsa for each vcpu. -+ */ -+ if (!ret && memcrypt_enabled() && is_hygon_cpu()) { -+ ret = ram_save_encrypted_cpu_state(rs, f); -+ if (ret) { -+ error_report("Failed to save encrypted cpu state"); -+ } -+ } - } - - if (ret < 0) { -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 2f7d98be6..9cdf3e6bf 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -100,6 +100,10 @@ struct SevGuestState { - gchar *send_packet_hdr; - size_t send_packet_hdr_len; - -+ /* needed by live migration of HYGON CSV2 guest */ -+ gchar *send_vmsa_packet_hdr; -+ size_t send_vmsa_packet_hdr_len; -+ - uint32_t reset_cs; - uint32_t reset_ip; - bool reset_data_valid; -@@ -193,6 +197,9 @@ static const char *const sev_fw_errlist[] = { - #define SHARED_REGION_LIST_CONT 0x1 - #define SHARED_REGION_LIST_END 0x2 - -+#define ENCRYPTED_CPU_STATE_CONT 0x1 -+#define ENCRYPTED_CPU_STATE_END 0x2 -+ - static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_setup = sev_save_setup, - .save_outgoing_page = sev_save_outgoing_page, -@@ -204,6 +211,8 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_queued_outgoing_pages = csv_save_queued_outgoing_pages, - .queue_incoming_page = csv_queue_incoming_page, - .load_queued_incoming_pages = csv_load_queued_incoming_pages, -+ .save_outgoing_cpu_state = csv_save_outgoing_cpu_state, -+ .load_incoming_cpu_state = csv_load_incoming_cpu_state, - }; - - static int -@@ -1020,6 +1029,9 @@ sev_send_finish(void) - } - - g_free(sev_guest->send_packet_hdr); -+ if (sev_es_enabled() && is_hygon_cpu()) { -+ g_free(sev_guest->send_vmsa_packet_hdr); -+ } - sev_set_guest_state(sev_guest, SEV_STATE_RUNNING); - } - -@@ -2214,6 +2226,190 @@ int csv_load_queued_incoming_pages(QEMUFile *f) - return csv_receive_update_data_batch(s); - } - -+static int -+sev_send_vmsa_get_packet_len(int *fw_err) -+{ -+ int ret; -+ struct kvm_sev_send_update_vmsa update = { 0, }; -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_UPDATE_VMSA, -+ &update, fw_err); -+ if (*fw_err != SEV_RET_INVALID_LEN) { -+ ret = -1; -+ error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", -+ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); -+ goto err; -+ } -+ -+ ret = update.hdr_len; -+ -+err: -+ return ret; -+} -+ -+static int -+sev_send_update_vmsa(SevGuestState *s, QEMUFile *f, uint32_t cpu_id, -+ uint32_t cpu_index, uint32_t size) -+{ -+ int ret, fw_error; -+ guchar *trans = NULL; -+ struct kvm_sev_send_update_vmsa update = {}; -+ -+ /* -+ * If this is first call then query the packet header bytes and allocate -+ * the packet buffer. -+ */ -+ if (!s->send_vmsa_packet_hdr) { -+ s->send_vmsa_packet_hdr_len = sev_send_vmsa_get_packet_len(&fw_error); -+ if (s->send_vmsa_packet_hdr_len < 1) { -+ error_report("%s: SEND_UPDATE_VMSA fw_error=%d '%s'", -+ __func__, fw_error, fw_error_to_str(fw_error)); -+ return 1; -+ } -+ -+ s->send_vmsa_packet_hdr = g_new(gchar, s->send_vmsa_packet_hdr_len); -+ } -+ -+ /* allocate transport buffer */ -+ trans = g_new(guchar, size); -+ -+ update.vcpu_id = cpu_id; -+ update.hdr_uaddr = (uintptr_t)s->send_vmsa_packet_hdr; -+ update.hdr_len = s->send_vmsa_packet_hdr_len; -+ update.trans_uaddr = (uintptr_t)trans; -+ update.trans_len = size; -+ -+ trace_kvm_sev_send_update_vmsa(cpu_id, cpu_index, trans, size); -+ -+ ret = sev_ioctl(s->sev_fd, KVM_SEV_SEND_UPDATE_VMSA, &update, &fw_error); -+ if (ret) { -+ error_report("%s: SEND_UPDATE_VMSA ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ /* -+ * Migration of vCPU's VMState according to the instance_id -+ * (i.e. CPUState.cpu_index) -+ */ -+ qemu_put_be32(f, sizeof(uint32_t)); -+ qemu_put_buffer(f, (uint8_t *)&cpu_index, sizeof(uint32_t)); -+ -+ qemu_put_be32(f, update.hdr_len); -+ qemu_put_buffer(f, (uint8_t *)update.hdr_uaddr, update.hdr_len); -+ -+ qemu_put_be32(f, update.trans_len); -+ qemu_put_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ -+err: -+ g_free(trans); -+ return ret; -+} -+ -+int csv_save_outgoing_cpu_state(QEMUFile *f) -+{ -+ SevGuestState *s = sev_guest; -+ CPUState *cpu; -+ int ret = 0; -+ -+ /* Only support migrate VMSAs for HYGON CSV2 guest */ -+ if (!sev_es_enabled() || !is_hygon_cpu()) { -+ return 0; -+ } -+ -+ CPU_FOREACH(cpu) { -+ qemu_put_be32(f, ENCRYPTED_CPU_STATE_CONT); -+ ret = sev_send_update_vmsa(s, f, kvm_arch_vcpu_id(cpu), -+ cpu->cpu_index, TARGET_PAGE_SIZE); -+ if (ret) { -+ goto err; -+ } -+ } -+ -+ qemu_put_be32(f, ENCRYPTED_CPU_STATE_END); -+ -+err: -+ return ret; -+} -+ -+static int sev_receive_update_vmsa(QEMUFile *f) -+{ -+ int ret = 1, fw_error = 0; -+ CPUState *cpu; -+ uint32_t cpu_index, cpu_id = 0; -+ gchar *hdr = NULL, *trans = NULL; -+ struct kvm_sev_receive_update_vmsa update = {}; -+ -+ /* get cpu index buffer */ -+ assert(qemu_get_be32(f) == sizeof(uint32_t)); -+ qemu_get_buffer(f, (uint8_t *)&cpu_index, sizeof(uint32_t)); -+ -+ CPU_FOREACH(cpu) { -+ if (cpu->cpu_index == cpu_index) { -+ cpu_id = kvm_arch_vcpu_id(cpu); -+ break; -+ } -+ } -+ update.vcpu_id = cpu_id; -+ -+ /* get packet header */ -+ update.hdr_len = qemu_get_be32(f); -+ if (!check_blob_length(update.hdr_len)) { -+ return 1; -+ } -+ -+ hdr = g_new(gchar, update.hdr_len); -+ qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len); -+ update.hdr_uaddr = (uintptr_t)hdr; -+ -+ /* get transport buffer */ -+ update.trans_len = qemu_get_be32(f); -+ if (!check_blob_length(update.trans_len)) { -+ goto err; -+ } -+ -+ trans = g_new(gchar, update.trans_len); -+ update.trans_uaddr = (uintptr_t)trans; -+ qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ -+ trace_kvm_sev_receive_update_vmsa(cpu_id, cpu_index, -+ trans, update.trans_len, hdr, update.hdr_len); -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_RECEIVE_UPDATE_VMSA, -+ &update, &fw_error); -+ if (ret) { -+ error_report("Error RECEIVE_UPDATE_VMSA ret=%d fw_error=%d '%s'", -+ ret, fw_error, fw_error_to_str(fw_error)); -+ } -+ -+err: -+ g_free(trans); -+ g_free(hdr); -+ return ret; -+} -+ -+int csv_load_incoming_cpu_state(QEMUFile *f) -+{ -+ int status, ret = 0; -+ -+ /* Only support migrate VMSAs for HYGON CSV2 guest */ -+ if (!sev_es_enabled() || !is_hygon_cpu()) { -+ return 0; -+ } -+ -+ status = qemu_get_be32(f); -+ while (status == ENCRYPTED_CPU_STATE_CONT) { -+ ret = sev_receive_update_vmsa(f); -+ if (ret) { -+ break; -+ } -+ -+ status = qemu_get_be32(f); -+ } -+ -+ return ret; -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 345dffac5..8b38567c3 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -44,6 +44,7 @@ typedef struct SevKernelLoaderContext { - #define RAM_SAVE_ENCRYPTED_PAGE_BATCH 0x4 - #define RAM_SAVE_ENCRYPTED_PAGE_BATCH_END 0x5 - #define CSV_OUTGOING_PAGE_WINDOW_SIZE (4094 * TARGET_PAGE_SIZE) -+#define RAM_SAVE_ENCRYPTED_CPU_STATE 0x6 - - #ifdef CONFIG_SEV - bool sev_enabled(void); -@@ -82,6 +83,8 @@ int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); - int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); - int csv_queue_incoming_page(QEMUFile *f, uint8_t *ptr); - int csv_load_queued_incoming_pages(QEMUFile *f); -+int csv_save_outgoing_cpu_state(QEMUFile *f); -+int csv_load_incoming_cpu_state(QEMUFile *f); - - struct sev_ops { - int (*sev_ioctl)(int fd, int cmd, void *data, int *error); -diff --git a/target/i386/trace-events b/target/i386/trace-events -index e32b0319b..60a4609c0 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -17,6 +17,8 @@ kvm_sev_send_finish(void) "" - kvm_sev_receive_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p" - kvm_sev_receive_update_data(void *src, void *dst, int len, void *hdr, int hdr_len) "guest %p trans %p len %d hdr %p hdr_len %d" - kvm_sev_receive_finish(void) "" -+kvm_sev_send_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *dst, int len) "cpu_id %d cpu_index %d trans %p len %d" -+kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int len, void *hdr, int hdr_len) "cpu_id %d cpu_index %d trans %p len %d hdr %p hdr_len %d" - - # csv.c - kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 --- -2.31.1 - diff --git a/1064-anolis-target-i386-get-set-migrate-GHCB-state.patch b/1064-anolis-target-i386-get-set-migrate-GHCB-state.patch deleted file mode 100644 index a58e394..0000000 --- a/1064-anolis-target-i386-get-set-migrate-GHCB-state.patch +++ /dev/null @@ -1,175 +0,0 @@ -From a95faafa015e094f7252ef35afb74933d07a9334 Mon Sep 17 00:00:00 2001 -From: panpingsheng -Date: Sat, 12 Jun 2021 15:15:29 +0800 -Subject: [PATCH 27/29] anolis: target/i386: get/set/migrate GHCB state - -GHCB state is necessary to CSV2 guest when migrating to target. - -Add GHCB related definition, it also adds corresponding part -to kvm_get/put, and vmstate. - -Signed-off-by: hanliyang ---- - include/sysemu/kvm.h | 1 + - linux-headers/linux/kvm.h | 1 + - target/i386/cpu.h | 4 ++++ - target/i386/kvm/kvm.c | 11 +++++++++++ - target/i386/machine.c | 24 ++++++++++++++++++++++++ - target/i386/sev.c | 10 ++++++++++ - 6 files changed, 51 insertions(+) - -diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h -index 7b22aeb6a..9f8099f48 100644 ---- a/include/sysemu/kvm.h -+++ b/include/sysemu/kvm.h -@@ -46,6 +46,7 @@ extern bool kvm_readonly_mem_allowed; - extern bool kvm_direct_msi_allowed; - extern bool kvm_ioeventfd_any_length_allowed; - extern bool kvm_msi_use_devid; -+extern bool kvm_has_msr_ghcb; - - #define kvm_enabled() (kvm_allowed) - /** -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index e5d282c75..4a177f81d 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1154,6 +1154,7 @@ struct kvm_ppc_resize_hpt { - #define KVM_CAP_S390_PROTECTED_DUMP 217 - #define KVM_CAP_S390_ZPCI_OP 221 - #define KVM_CAP_S390_CPU_TOPOLOGY 222 -+#define KVM_CAP_SEV_ES_GHCB 500 - - #define KVM_EXIT_HYPERCALL_VALID_MASK (1 << KVM_HC_MAP_GPA_RANGE) - -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 5d2ddd81b..5c476a029 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -505,6 +505,8 @@ typedef enum X86Seg { - - #define MSR_VM_HSAVE_PA 0xc0010117 - -+#define MSR_AMD64_SEV_ES_GHCB 0xc0010130 -+ - #define MSR_IA32_XFD 0x000001c4 - #define MSR_IA32_XFD_ERR 0x000001c5 - -@@ -1732,6 +1734,8 @@ typedef struct CPUX86State { - TPRAccess tpr_access_type; - - unsigned nr_dies; -+ -+ uint64_t ghcb_gpa; - } CPUX86State; - - struct kvm_msrs; -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index f0b61ec3c..fb85cc698 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -3346,6 +3346,10 @@ static int kvm_put_msrs(X86CPU *cpu, int level) - } - } - -+ if (kvm_has_msr_ghcb) { -+ kvm_msr_entry_add(cpu, MSR_AMD64_SEV_ES_GHCB, env->ghcb_gpa); -+ } -+ - return kvm_buf_set_msrs(cpu); - } - -@@ -3686,6 +3690,10 @@ static int kvm_get_msrs(X86CPU *cpu) - kvm_msr_entry_add(cpu, MSR_IA32_XFD_ERR, 0); - } - -+ if (kvm_has_msr_ghcb) { -+ kvm_msr_entry_add(cpu, MSR_AMD64_SEV_ES_GHCB, 0); -+ } -+ - ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, cpu->kvm_msr_buf); - if (ret < 0) { - return ret; -@@ -3991,6 +3999,9 @@ static int kvm_get_msrs(X86CPU *cpu) - case MSR_IA32_XFD_ERR: - env->msr_xfd_err = msrs[i].data; - break; -+ case MSR_AMD64_SEV_ES_GHCB: -+ env->ghcb_gpa = msrs[i].data; -+ break; - } - } - -diff --git a/target/i386/machine.c b/target/i386/machine.c -index 3977e9d8f..8aa54432d 100644 ---- a/target/i386/machine.c -+++ b/target/i386/machine.c -@@ -1497,6 +1497,27 @@ static const VMStateDescription vmstate_amx_xtile = { - }; - #endif - -+#if defined(CONFIG_KVM) && defined(TARGET_X86_64) -+static bool msr_ghcb_gpa_needed(void *opaque) -+{ -+ X86CPU *cpu = opaque; -+ CPUX86State *env = &cpu->env; -+ -+ return env->ghcb_gpa != 0; -+} -+ -+static const VMStateDescription vmstate_msr_ghcb_gpa = { -+ .name = "cpu/svm_msr_ghcb_gpa", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .needed = msr_ghcb_gpa_needed, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT64(env.ghcb_gpa, X86CPU), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+#endif -+ - const VMStateDescription vmstate_x86_cpu = { - .name = "cpu", - .version_id = 12, -@@ -1638,6 +1659,9 @@ const VMStateDescription vmstate_x86_cpu = { - &vmstate_msr_xfd, - #ifdef TARGET_X86_64 - &vmstate_amx_xtile, -+#endif -+#if defined(CONFIG_KVM) && defined(TARGET_X86_64) -+ &vmstate_msr_ghcb_gpa, - #endif - NULL - } -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 9cdf3e6bf..26b6e84d3 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -215,6 +215,8 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .load_incoming_cpu_state = csv_load_incoming_cpu_state, - }; - -+bool kvm_has_msr_ghcb; -+ - static int - sev_ioctl(int fd, int cmd, void *data, int *error) - { -@@ -1174,6 +1176,14 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; - QTAILQ_INIT(&sev->shared_regions_list); - -+ /* Determine whether support MSR_AMD64_SEV_ES_GHCB */ -+ if (sev_es_enabled()) { -+ kvm_has_msr_ghcb = -+ kvm_vm_check_extension(kvm_state, KVM_CAP_SEV_ES_GHCB); -+ } else { -+ kvm_has_msr_ghcb = false; -+ } -+ - cgs->ready = true; - - return 0; --- -2.31.1 - diff --git a/1065-anolis-target-i386-kvm-Return-resettable-when-emulat.patch b/1065-anolis-target-i386-kvm-Return-resettable-when-emulat.patch deleted file mode 100644 index 966d6ff..0000000 --- a/1065-anolis-target-i386-kvm-Return-resettable-when-emulat.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 84ea1a98ae7cb888eba8f9be9f51955a4402355c Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Sun, 19 Jun 2022 16:49:45 +0800 -Subject: [PATCH 28/29] anolis: target/i386/kvm: Return resettable when emulate - HYGON CSV2 guest - -SEV-ES guest will be terminated by QEMU when receive reboot request. -In order to support reboot for CSV2 guest, report resettable in -kvm_arch_cpu_check_are_resettable(). - -Signed-off-by: hanliyang ---- - target/i386/kvm/kvm.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index fb85cc698..19c622bb0 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -30,6 +30,7 @@ - #include "sysemu/runstate.h" - #include "kvm_i386.h" - #include "sev.h" -+#include "csv.h" - #include "hyperv.h" - #include "hyperv-proto.h" - -@@ -5363,7 +5364,7 @@ bool kvm_has_waitpkg(void) - - bool kvm_arch_cpu_check_are_resettable(void) - { -- return !sev_es_enabled(); -+ return !(sev_es_enabled() && !is_hygon_cpu()) && !csv_enabled(); - } - - #define ARCH_REQ_XCOMP_GUEST_PERM 0x1025 --- -2.31.1 - diff --git a/1066-anolis-kvm-Add-support-for-CSV2-reboot.patch b/1066-anolis-kvm-Add-support-for-CSV2-reboot.patch deleted file mode 100644 index 3c246b0..0000000 --- a/1066-anolis-kvm-Add-support-for-CSV2-reboot.patch +++ /dev/null @@ -1,170 +0,0 @@ -From a165dedbb9121f948738e5265198410487aa7acf Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Thu, 15 Apr 2021 08:32:24 -0400 -Subject: [PATCH 29/29] anolis: kvm: Add support for CSV2 reboot - -Linux will set vcpu.arch.guest_state_protected to true after execute -LAUNCH_UPDATE_VMSA successfully, and then KVM will prevent any changes -to VMCB State Save Area. - -In order to support CSV2 guest reboot, calls cpus_control_pre_system_reset() -to set vcpu.arch.guest_state_protected to false, and calls -cpus_control_post_system_reset() to restore VMSA of guest's vcpu with -data generated by LAUNCH_UPDATE_VMSA. - -In addition, for memory encrypted guest, additional works may be -required during system reset, such as flushing the cache. The function -cpus_control_post_system_reset() hints linux to flush caches of guest -memory. - -Signed-off-by: hanliyang ---- - accel/kvm/kvm-accel-ops.c | 3 +++ - accel/kvm/kvm-all.c | 10 ++++++++++ - accel/kvm/kvm-cpus.h | 3 +++ - include/sysemu/accel-ops.h | 3 +++ - include/sysemu/cpus.h | 2 ++ - linux-headers/linux/kvm.h | 4 ++++ - softmmu/cpus.c | 14 ++++++++++++++ - softmmu/runstate.c | 4 ++++ - 8 files changed, 43 insertions(+) - -diff --git a/accel/kvm/kvm-accel-ops.c b/accel/kvm/kvm-accel-ops.c -index 7516c67a3..9602f9609 100644 ---- a/accel/kvm/kvm-accel-ops.c -+++ b/accel/kvm/kvm-accel-ops.c -@@ -83,6 +83,9 @@ static void kvm_accel_ops_class_init(ObjectClass *oc, void *data) - ops->synchronize_post_init = kvm_cpu_synchronize_post_init; - ops->synchronize_state = kvm_cpu_synchronize_state; - ops->synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm; -+ -+ ops->control_pre_system_reset = kvm_cpus_control_pre_system_reset; -+ ops->control_post_system_reset = kvm_cpus_control_post_system_reset; - } - - static const TypeInfo kvm_accel_ops_type = { -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 6d63f0ab0..10af4170d 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2848,6 +2848,16 @@ void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu) - run_on_cpu(cpu, do_kvm_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL); - } - -+void kvm_cpus_control_pre_system_reset(void) -+{ -+ kvm_vm_ioctl(kvm_state, KVM_CONTROL_VCPU_PRE_SYSTEM_RESET, NULL); -+} -+ -+void kvm_cpus_control_post_system_reset(void) -+{ -+ kvm_vm_ioctl(kvm_state, KVM_CONTROL_VCPU_POST_SYSTEM_RESET, NULL); -+} -+ - #ifdef KVM_HAVE_MCE_INJECTION - static __thread void *pending_sigbus_addr; - static __thread int pending_sigbus_code; -diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h -index bf0bd1bee..8ba363e0b 100644 ---- a/accel/kvm/kvm-cpus.h -+++ b/accel/kvm/kvm-cpus.h -@@ -19,4 +19,7 @@ void kvm_cpu_synchronize_post_reset(CPUState *cpu); - void kvm_cpu_synchronize_post_init(CPUState *cpu); - void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu); - -+void kvm_cpus_control_pre_system_reset(void); -+void kvm_cpus_control_post_system_reset(void); -+ - #endif /* KVM_CPUS_H */ -diff --git a/include/sysemu/accel-ops.h b/include/sysemu/accel-ops.h -index 032f6979d..43893c1a4 100644 ---- a/include/sysemu/accel-ops.h -+++ b/include/sysemu/accel-ops.h -@@ -40,6 +40,9 @@ struct AccelOpsClass { - - int64_t (*get_virtual_clock)(void); - int64_t (*get_elapsed_ticks)(void); -+ -+ void (*control_pre_system_reset)(void); -+ void (*control_post_system_reset)(void); - }; - - #endif /* ACCEL_OPS_H */ -diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h -index 868f1192d..70d6e8ad3 100644 ---- a/include/sysemu/cpus.h -+++ b/include/sysemu/cpus.h -@@ -42,6 +42,8 @@ extern int icount_align_option; - void qemu_cpu_kick_self(void); - - bool cpus_are_resettable(void); -+void cpus_control_pre_system_reset(void); -+void cpus_control_post_system_reset(void); - - void cpu_synchronize_all_states(void); - void cpu_synchronize_all_post_reset(void); -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 4a177f81d..d5278df1c 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1528,6 +1528,10 @@ struct kvm_s390_ucas_mapping { - #define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr) - #define KVM_HAS_DEVICE_ATTR _IOW(KVMIO, 0xe3, struct kvm_device_attr) - -+/* ioctls for control vcpu setup during system reset */ -+#define KVM_CONTROL_VCPU_PRE_SYSTEM_RESET _IO(KVMIO, 0xe8) -+#define KVM_CONTROL_VCPU_POST_SYSTEM_RESET _IO(KVMIO, 0xe9) -+ - /* - * ioctls for vcpu fds - */ -diff --git a/softmmu/cpus.c b/softmmu/cpus.c -index 071085f84..319a72d92 100644 ---- a/softmmu/cpus.c -+++ b/softmmu/cpus.c -@@ -200,6 +200,20 @@ bool cpus_are_resettable(void) - return cpu_check_are_resettable(); - } - -+void cpus_control_pre_system_reset(void) -+{ -+ if (cpus_accel->control_pre_system_reset) { -+ cpus_accel->control_pre_system_reset(); -+ } -+} -+ -+void cpus_control_post_system_reset(void) -+{ -+ if (cpus_accel->control_post_system_reset) { -+ cpus_accel->control_post_system_reset(); -+ } -+} -+ - int64_t cpus_get_virtual_clock(void) - { - /* -diff --git a/softmmu/runstate.c b/softmmu/runstate.c -index 10d9b7365..4b9c9f9e0 100644 ---- a/softmmu/runstate.c -+++ b/softmmu/runstate.c -@@ -437,6 +437,8 @@ void qemu_system_reset(ShutdownCause reason) - - mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL; - -+ cpus_control_pre_system_reset(); -+ - cpu_synchronize_all_states(); - - if (mc && mc->reset) { -@@ -448,6 +450,8 @@ void qemu_system_reset(ShutdownCause reason) - qapi_event_send_reset(shutdown_caused_by_guest(reason), reason); - } - cpu_synchronize_all_post_reset(); -+ -+ cpus_control_post_system_reset(); - } - - /* --- -2.31.1 - diff --git a/1067-anolis-vfio-only-map-shared-region-for-CSV-virtual-m.patch b/1067-anolis-vfio-only-map-shared-region-for-CSV-virtual-m.patch deleted file mode 100644 index 6e1d418..0000000 --- a/1067-anolis-vfio-only-map-shared-region-for-CSV-virtual-m.patch +++ /dev/null @@ -1,384 +0,0 @@ -From 3b532188e4eac7fd291cf66970126a18af024364 Mon Sep 17 00:00:00 2001 -From: liuyafei -Date: Mon, 22 May 2023 20:37:40 +0800 -Subject: [PATCH 1067/1072] anolis: vfio: only map shared region for CSV - virtual machine - -qemu vfio listener map/unmap all of the virtual machine's memory. -It does not work for CSV virtual machine, as only shared memory -should be accessed by device. - -Change-Id: I3f281c28166a36f2bed8ea193523715af9ff3271 ---- - hw/vfio/common.c | 40 +++++++++- - include/exec/memory.h | 11 +++ - softmmu/memory.c | 18 +++++ - target/i386/csv-sysemu-stub.c | 10 +++ - target/i386/csv.c | 134 ++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 12 +++ - target/i386/kvm/kvm.c | 2 + - 7 files changed, 225 insertions(+), 2 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 080046e3f5..7cc03a7ef9 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -41,6 +41,9 @@ - #include "qapi/error.h" - #include "migration/migration.h" - -+#include "target/i386/sev.h" -+#include "target/i386/csv.h" -+ - VFIOGroupList vfio_group_list = - QLIST_HEAD_INITIALIZER(vfio_group_list); - static QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces = -@@ -1251,6 +1254,30 @@ static void vfio_listener_log_global_stop(MemoryListener *listener) - vfio_set_dirty_page_tracking(container, false); - } - -+static SharedRegionListener *g_shl; -+static void shared_memory_listener_register(MemoryListener *listener, AddressSpace *as) -+{ -+ SharedRegionListener *shl; -+ -+ shl = g_new0(SharedRegionListener, 1); -+ -+ shl->listener = listener; -+ shl->as = as; -+ -+ shared_region_register_listener(shl); -+ g_shl = shl; -+} -+ -+static void shared_memory_listener_unregister(void) -+{ -+ SharedRegionListener *shl = g_shl; -+ -+ shared_region_unregister_listener(shl); -+ -+ g_free(shl); -+ g_shl = NULL; -+} -+ - static int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, - uint64_t size, ram_addr_t ram_addr) - { -@@ -1453,7 +1480,12 @@ static const MemoryListener vfio_memory_listener = { - - static void vfio_listener_release(VFIOContainer *container) - { -- memory_listener_unregister(&container->listener); -+ if (csv_enabled()) { -+ shared_memory_listener_unregister(); -+ } else { -+ memory_listener_unregister(&container->listener); -+ } -+ - if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) { - memory_listener_unregister(&container->prereg_listener); - } -@@ -2183,7 +2215,11 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - - container->listener = vfio_memory_listener; - -- memory_listener_register(&container->listener, container->space->as); -+ if (csv_enabled()) { -+ shared_memory_listener_register(&container->listener, container->space->as); -+ } else { -+ memory_listener_register(&container->listener, container->space->as); -+ } - - if (container->error) { - ret = -1; -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 20f1b27377..d4bd90dfcc 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -710,6 +710,17 @@ void ram_discard_manager_register_listener(RamDiscardManager *rdm, - void ram_discard_manager_unregister_listener(RamDiscardManager *rdm, - RamDiscardListener *rdl); - -+typedef struct SharedRegionListener SharedRegionListener; -+struct SharedRegionListener { -+ MemoryListener *listener; -+ AddressSpace *as; -+ QTAILQ_ENTRY(SharedRegionListener) next; -+}; -+ -+void shared_region_register_listener(SharedRegionListener *shl); -+void shared_region_unregister_listener(SharedRegionListener *shl); -+void *shared_region_listeners_get(void); -+ - typedef struct CoalescedMemoryRange CoalescedMemoryRange; - typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd; - -diff --git a/softmmu/memory.c b/softmmu/memory.c -index 7340e19ff5..b435bb4aa3 100644 ---- a/softmmu/memory.c -+++ b/softmmu/memory.c -@@ -47,6 +47,9 @@ static QTAILQ_HEAD(, MemoryListener) memory_listeners - static QTAILQ_HEAD(, AddressSpace) address_spaces - = QTAILQ_HEAD_INITIALIZER(address_spaces); - -+static QTAILQ_HEAD(, SharedRegionListener) shared_region_listeners -+ = QTAILQ_HEAD_INITIALIZER(shared_region_listeners); -+ - static GHashTable *flat_views; - - typedef struct AddrRange AddrRange; -@@ -2111,6 +2114,21 @@ void ram_discard_manager_unregister_listener(RamDiscardManager *rdm, - rdmc->unregister_listener(rdm, rdl); - } - -+void shared_region_register_listener(SharedRegionListener *shl) -+{ -+ QTAILQ_INSERT_TAIL(&shared_region_listeners, shl, next); -+} -+ -+void shared_region_unregister_listener(SharedRegionListener *shl) -+{ -+ QTAILQ_REMOVE(&shared_region_listeners, shl, next); -+} -+ -+void *shared_region_listeners_get(void) -+{ -+ return &shared_region_listeners; -+} -+ - void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client) - { - uint8_t mask = 1 << client; -diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c -index a5ce986e3c..96ca055270 100644 ---- a/target/i386/csv-sysemu-stub.c -+++ b/target/i386/csv-sysemu-stub.c -@@ -29,3 +29,13 @@ int csv_launch_encrypt_vmcb(void) - { - g_assert_not_reached(); - } -+ -+int csv_shared_region_dma_map(uint64_t start, uint64_t end) -+{ -+ return 0; -+} -+ -+void csv_shared_region_dma_unmap(uint64_t start, uint64_t end) -+{ -+ -+} -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 161cad39ae..6d05382fb2 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -24,6 +24,7 @@ - #include "cpu.h" - #include "sev.h" - #include "csv.h" -+#include "exec/address-spaces.h" - - CsvGuestState csv_guest = { 0 }; - -@@ -63,6 +64,8 @@ csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) - csv_guest.state = state; - csv_guest.sev_ioctl = ops->sev_ioctl; - csv_guest.fw_error_to_str = ops->fw_error_to_str; -+ QTAILQ_INIT(&csv_guest.dma_map_regions_list); -+ qemu_mutex_init(&csv_guest.dma_map_regions_list_mutex); - } - return 0; - } -@@ -163,3 +166,134 @@ csv_launch_encrypt_vmcb(void) - err: - return ret; - } -+ -+int csv_shared_region_dma_map(uint64_t start, uint64_t end) -+{ -+ MemoryRegionSection section; -+ AddressSpace *as; -+ QTAILQ_HEAD(, SharedRegionListener) *shared_region_listeners; -+ SharedRegionListener *shl; -+ MemoryListener *listener; -+ uint64_t size; -+ CsvGuestState *s = &csv_guest; -+ struct dma_map_region *region, *pos; -+ int ret = 0; -+ -+ if (!csv_enabled()) -+ return 0; -+ -+ if (end <= start) -+ return 0; -+ -+ shared_region_listeners = shared_region_listeners_get(); -+ if (QTAILQ_EMPTY(shared_region_listeners)) -+ return 0; -+ -+ size = end - start; -+ -+ qemu_mutex_lock(&s->dma_map_regions_list_mutex); -+ QTAILQ_FOREACH(pos, &s->dma_map_regions_list, list) { -+ if (start >= (pos->start + pos->size)) { -+ continue; -+ } else if ((start + size) <= pos->start) { -+ break; -+ } else { -+ goto end; -+ } -+ } -+ QTAILQ_FOREACH(shl, shared_region_listeners, next) { -+ listener = shl->listener; -+ as = shl->as; -+ section = memory_region_find(as->root, start, size); -+ if (!section.mr) { -+ goto end; -+ } -+ -+ if (!memory_region_is_ram(section.mr)) { -+ memory_region_unref(section.mr); -+ goto end; -+ } -+ -+ if (listener->region_add) { -+ listener->region_add(listener, §ion); -+ } -+ memory_region_unref(section.mr); -+ } -+ -+ region = g_malloc0(sizeof(*region)); -+ if (!region) { -+ ret = -1; -+ goto end; -+ } -+ region->start = start; -+ region->size = size; -+ -+ if (pos) { -+ QTAILQ_INSERT_BEFORE(pos, region, list); -+ } else { -+ QTAILQ_INSERT_TAIL(&s->dma_map_regions_list, region, list); -+ } -+ -+end: -+ qemu_mutex_unlock(&s->dma_map_regions_list_mutex); -+ return ret; -+} -+ -+void csv_shared_region_dma_unmap(uint64_t start, uint64_t end) -+{ -+ MemoryRegionSection section; -+ AddressSpace *as; -+ QTAILQ_HEAD(, SharedRegionListener) *shared_region_listeners; -+ SharedRegionListener *shl; -+ MemoryListener *listener; -+ uint64_t size; -+ CsvGuestState *s = &csv_guest; -+ struct dma_map_region *pos, *next_pos; -+ -+ if (!csv_enabled()) -+ return; -+ -+ if (end <= start) -+ return; -+ -+ shared_region_listeners = shared_region_listeners_get(); -+ if (QTAILQ_EMPTY(shared_region_listeners)) -+ return; -+ -+ size = end - start; -+ -+ qemu_mutex_lock(&s->dma_map_regions_list_mutex); -+ QTAILQ_FOREACH_SAFE(pos, &s->dma_map_regions_list, list, next_pos) { -+ uint64_t l, r; -+ uint64_t curr_end = pos->start + pos->size; -+ -+ l = MAX(start, pos->start); -+ r = MIN(start + size, pos->start + pos->size); -+ if (l < r) { -+ if ((start <= pos->start) && (start + size >= pos->start + pos->size)) { -+ QTAILQ_FOREACH(shl, shared_region_listeners, next) { -+ listener = shl->listener; -+ as = shl->as; -+ section = memory_region_find(as->root, pos->start, pos->size); -+ if (!section.mr) { -+ goto end; -+ } -+ if (listener->region_del) { -+ listener->region_del(listener, §ion); -+ } -+ memory_region_unref(section.mr); -+ } -+ -+ QTAILQ_REMOVE(&s->dma_map_regions_list, pos, list); -+ g_free(pos); -+ } -+ break; -+ } -+ if ((start + size) <= curr_end) { -+ break; -+ } -+ } -+end: -+ qemu_mutex_unlock(&s->dma_map_regions_list_mutex); -+ return; -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index e51cc83022..6412c0c70b 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -15,6 +15,8 @@ - #define QEMU_CSV_H - - #include "qapi/qapi-commands-misc-target.h" -+#include "qemu/thread.h" -+#include "qemu/queue.h" - - #ifdef CONFIG_SEV - -@@ -55,12 +57,19 @@ bool csv_enabled(void); - #define csv_enabled() 0 - #endif - -+struct dma_map_region { -+ uint64_t start, size; -+ QTAILQ_ENTRY(dma_map_region) list; -+}; -+ - struct CsvGuestState { - uint32_t policy; - int sev_fd; - void *state; - int (*sev_ioctl)(int fd, int cmd, void *data, int *error); - const char *(*fw_error_to_str)(int code); -+ QTAILQ_HEAD(, dma_map_region) dma_map_regions_list; -+ QemuMutex dma_map_regions_list_mutex; - }; - - typedef struct CsvGuestState CsvGuestState; -@@ -71,4 +80,7 @@ extern int csv_launch_encrypt_vmcb(void); - - int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); - -+int csv_shared_region_dma_map(uint64_t start, uint64_t end); -+void csv_shared_region_dma_unmap(uint64_t start, uint64_t end); -+ - #endif -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 6192bcd36e..090800257f 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -4626,8 +4626,10 @@ static int kvm_handle_exit_hypercall(X86CPU *cpu, struct kvm_run *run) - - if (enc) { - sev_remove_shared_regions_list(gfn_start, gfn_end); -+ csv_shared_region_dma_unmap(gpa, gfn_end << TARGET_PAGE_BITS); - } else { - sev_add_shared_regions_list(gfn_start, gfn_end); -+ csv_shared_region_dma_map(gpa, gfn_end << TARGET_PAGE_BITS); - } - } - return 0; --- -2.17.1 - diff --git a/1068-anolis-linux-headers-update-kernel-headers-to-includ.patch b/1068-anolis-linux-headers-update-kernel-headers-to-includ.patch deleted file mode 100644 index 209ebd9..0000000 --- a/1068-anolis-linux-headers-update-kernel-headers-to-includ.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 69976084e81798c275286b5bd3641d4b58896b72 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Fri, 17 Jun 2022 09:25:19 +0800 -Subject: [PATCH 1068/1072] anolis: linux-headers: update kernel headers to - include CSV migration cmds - -Four new migration commands are added to support CSV migration. - -KVM_CSV_SEND_ENCRYPT_DATA/KVM_CSV_RECEIVE_ENCRYPT_DATA cmds are -used to migrate guest's pages. - -KVM_CSV_SEND_ENCRYPT_CONTEXT/KVM_CSV_RECEIVE_ENCRYPT_CONTEXT cmds -are used to migration guest's runtime context. - -Change-Id: Ib3b733c7b5713aa6a6648c65e03cf8c9618ff1af -Signed-off-by: Xin Jiang ---- - linux-headers/linux/kvm.h | 38 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 1a2c3ea87d..cbf4fe4ecb 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1842,6 +1842,12 @@ enum csv_cmd_id { - KVM_CSV_INIT = KVM_CSV_NR_MIN, - KVM_CSV_LAUNCH_ENCRYPT_DATA, - KVM_CSV_LAUNCH_ENCRYPT_VMCB, -+ KVM_CSV_SEND_ENCRYPT_DATA, -+ KVM_CSV_SEND_ENCRYPT_CONTEXT, -+ KVM_CSV_RECEIVE_ENCRYPT_DATA, -+ KVM_CSV_RECEIVE_ENCRYPT_CONTEXT, -+ -+ KVM_CSV_NR_MAX, - }; - - struct kvm_csv_launch_encrypt_data { -@@ -1865,6 +1871,38 @@ struct kvm_csv_command_batch { - __u64 csv_batch_list_uaddr; - }; - -+struct kvm_csv_send_encrypt_data { -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u64 guest_addr_data; -+ __u32 guest_addr_len; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+}; -+ -+struct kvm_csv_send_encrypt_context { -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+}; -+ -+struct kvm_csv_receive_encrypt_data { -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u64 guest_addr_data; -+ __u32 guest_addr_len; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+}; -+ -+struct kvm_csv_receive_encrypt_context { -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+}; -+ - #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) - #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) - #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) --- -2.17.1 - diff --git a/1069-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch b/1069-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch deleted file mode 100644 index 1d941ca..0000000 --- a/1069-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch +++ /dev/null @@ -1,453 +0,0 @@ -From 967c7ad199c55223cc03d0217c6f256d3d418be2 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Fri, 17 Jun 2022 09:37:56 +0800 -Subject: [PATCH 1069/1072] anolis: csv/i386: add support to migrate the - outgoing page - -The csv_send_encrypt_data() provides the method to encrypt the -guest's private pages during migration. The routine is similar to -CSV2's. Usually, it starts with a SEND_START command to create the -migration context. Then SEND_ENCRYPT_DATA command is performed to -encrypt guest pages. After migration is completed, a SEND_FINISH -command is performed to the firmware. - -Change-Id: I6781119890036636d8f5c0a19c6647fa8a33a37d ---- - migration/ram.c | 83 ++++++++++++++++++ - target/i386/csv.c | 185 +++++++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 22 +++++ - target/i386/sev.c | 13 ++- - target/i386/sev.h | 1 + - target/i386/trace-events | 1 + - 6 files changed, 304 insertions(+), 1 deletion(-) - -diff --git a/migration/ram.c b/migration/ram.c -index 1dcd5c8553..c962496684 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -2452,6 +2452,86 @@ ram_save_encrypted_pages_in_batch(RAMState *rs, PageSearchStatus *pss, bool last - } - #endif - -+/** -+ * ram_save_csv_pages - send the given csv VM pages to the stream -+ */ -+static int ram_save_csv_pages(RAMState *rs, PageSearchStatus *pss, -+ bool last_stage) -+{ -+ int ret; -+ int tmppages = 0, pages = 0; -+ RAMBlock *block = pss->block; -+ ram_addr_t offset = 0; -+ hwaddr paddr = RAM_ADDR_INVALID; -+ uint32_t host_len = 0; -+ uint8_t *p; -+ uint64_t bytes_xmit; -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ -+ if (!csv_enabled()) -+ return 0; -+ -+ do { -+ /* Check the pages is dirty and if it is send it */ -+ if (!migration_bitmap_clear_dirty(rs, block, pss->page)) { -+ pss->page++; -+ continue; -+ } -+ -+ ret = kvm_physical_memory_addr_from_host(kvm_state, -+ block->host + (pss->page << TARGET_PAGE_BITS), &paddr); -+ /* Process ROM or MMIO */ -+ if (paddr == RAM_ADDR_INVALID || memory_region_is_rom(block->mr)) -+ tmppages = ram_save_target_page(rs, pss, last_stage); -+ else { -+ /* Caculate the offset and host virtual address of the page */ -+ offset = pss->page << TARGET_PAGE_BITS; -+ p = block->host + offset; -+ -+ if (ops->queue_outgoing_page(p, TARGET_PAGE_SIZE, offset)) -+ return -1; -+ -+ tmppages = 1; -+ host_len += TARGET_PAGE_SIZE; -+ ram_counters.normal++; -+ } -+ -+ if (tmppages < 0) { -+ return tmppages; -+ } -+ -+ pages += tmppages; -+ -+ pss->page++; -+ } while (offset_in_ramblock(block, pss->page << TARGET_PAGE_BITS) && -+ host_len < CSV3_OUTGOING_PAGE_WINDOW_SIZE); -+ -+ /* Check if there are any queued pages */ -+ if (host_len != 0) { -+ /* Always set offset as 0 for csv. */ -+ ram_counters.transferred += -+ save_page_header(rs, rs->f, block, 0 | RAM_SAVE_FLAG_ENCRYPTED_DATA); -+ -+ qemu_put_be32(rs->f, RAM_SAVE_ENCRYPTED_PAGE); -+ ram_counters.transferred += 4; -+ /* Process the queued pages in batch */ -+ ret = ops->save_queued_outgoing_pages(rs->f, &bytes_xmit); -+ if (ret) { -+ return -1; -+ } -+ ram_counters.transferred += bytes_xmit; -+ } -+ -+ /* The offset we leave with is the last one we looked at */ -+ pss->page--; -+ -+ return pages; -+} -+ - /** - * ram_save_host_page: save a whole host page - * -@@ -2486,6 +2566,9 @@ static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss, - return 0; - } - -+ if (csv_enabled()) -+ return ram_save_csv_pages(rs, pss, last_stage); -+ - #ifdef CONFIG_HYGON_CSV_MIG_ACCEL - /* - * If command_batch function is enabled and memory encryption is enabled -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 6d05382fb2..c5a2bc9924 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -13,6 +13,7 @@ - - #include "qemu/osdep.h" - -+#include - #include - #include "qapi/error.h" - -@@ -20,12 +21,30 @@ - #include - #endif - -+#include "migration/blocker.h" -+#include "migration/qemu-file.h" -+#include "migration/misc.h" -+#include "monitor/monitor.h" -+#include "sysemu/kvm.h" -+ - #include "trace.h" - #include "cpu.h" - #include "sev.h" - #include "csv.h" - #include "exec/address-spaces.h" - -+struct ConfidentialGuestMemoryEncryptionOps csv_memory_encryption_ops = { -+ .save_setup = sev_save_setup, -+ .save_outgoing_page = NULL, -+ .is_gfn_in_unshared_region = NULL, -+ .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, -+ .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, -+ .queue_outgoing_page = csv3_queue_outgoing_page, -+ .save_queued_outgoing_pages = csv3_save_queued_outgoing_pages, -+}; -+ -+#define CSV_OUTGOING_PAGE_NUM (CSV3_OUTGOING_PAGE_WINDOW_SIZE/TARGET_PAGE_SIZE) -+ - CsvGuestState csv_guest = { 0 }; - - #define GUEST_POLICY_CSV_BIT (1 << 6) -@@ -66,6 +85,7 @@ csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) - csv_guest.fw_error_to_str = ops->fw_error_to_str; - QTAILQ_INIT(&csv_guest.dma_map_regions_list); - qemu_mutex_init(&csv_guest.dma_map_regions_list_mutex); -+ csv_guest.sev_send_start = ops->sev_send_start; - } - return 0; - } -@@ -297,3 +317,168 @@ end: - qemu_mutex_unlock(&s->dma_map_regions_list_mutex); - return; - } -+ -+static inline hwaddr csv_hva_to_gfn(uint8_t *ptr) -+{ -+ ram_addr_t offset = RAM_ADDR_INVALID; -+ -+ kvm_physical_memory_addr_from_host(kvm_state, ptr, &offset); -+ -+ return offset >> TARGET_PAGE_BITS; -+} -+ -+static int -+csv_send_start(QEMUFile *f, uint64_t *bytes_sent) -+{ -+ if (csv_guest.sev_send_start) -+ return csv_guest.sev_send_start(f, bytes_sent); -+ else -+ return -1; -+} -+ -+static int -+csv_send_get_packet_len(int *fw_err) -+{ -+ int ret; -+ struct kvm_csv_send_encrypt_data update = {0}; -+ -+ update.hdr_len = 0; -+ update.trans_len = 0; -+ ret = csv_ioctl(KVM_CSV_SEND_ENCRYPT_DATA, &update, fw_err); -+ if (*fw_err != SEV_RET_INVALID_LEN) { -+ error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", -+ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); -+ ret = 0; -+ goto err; -+ } -+ -+ if (update.hdr_len <= INT_MAX) -+ ret = update.hdr_len; -+ else -+ ret = 0; -+ -+err: -+ return ret; -+} -+ -+static int -+csv_send_encrypt_data(CsvGuestState *s, QEMUFile *f, uint8_t *ptr, uint32_t size, -+ uint64_t *bytes_sent) -+{ -+ int ret, fw_error = 0; -+ guchar *trans; -+ uint32_t guest_addr_entry_num; -+ uint32_t i; -+ struct kvm_csv_send_encrypt_data update = { }; -+ -+ /* -+ * If this is first call then query the packet header bytes and allocate -+ * the packet buffer. -+ */ -+ if (!s->send_packet_hdr) { -+ s->send_packet_hdr_len = csv_send_get_packet_len(&fw_error); -+ if (s->send_packet_hdr_len < 1) { -+ error_report("%s: SEND_UPDATE fw_error=%d '%s'", -+ __func__, fw_error, fw_error_to_str(fw_error)); -+ return 1; -+ } -+ -+ s->send_packet_hdr = g_new(gchar, s->send_packet_hdr_len); -+ } -+ -+ if (!s->guest_addr_len || !s->guest_addr_data) { -+ error_report("%s: invalid host address or size", __func__); -+ return 1; -+ } else { -+ guest_addr_entry_num = s->guest_addr_len / sizeof(struct guest_addr_entry); -+ } -+ -+ /* allocate transport buffer */ -+ trans = g_new(guchar, guest_addr_entry_num * TARGET_PAGE_SIZE); -+ -+ update.hdr_uaddr = (uintptr_t)s->send_packet_hdr; -+ update.hdr_len = s->send_packet_hdr_len; -+ update.guest_addr_data = (uintptr_t)s->guest_addr_data; -+ update.guest_addr_len = s->guest_addr_len; -+ update.trans_uaddr = (uintptr_t)trans; -+ update.trans_len = guest_addr_entry_num * TARGET_PAGE_SIZE; -+ -+ trace_kvm_csv_send_encrypt_data(trans, update.trans_len); -+ -+ ret = csv_ioctl(KVM_CSV_SEND_ENCRYPT_DATA, &update, &fw_error); -+ if (ret) { -+ error_report("%s: SEND_ENCRYPT_DATA ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ for (i = 0; i < guest_addr_entry_num; i++) { -+ if (s->guest_addr_data[i].share) -+ memcpy(trans + i * TARGET_PAGE_SIZE, (guchar *)s->guest_hva_data[i].hva, -+ TARGET_PAGE_SIZE); -+ } -+ -+ qemu_put_be32(f, update.hdr_len); -+ qemu_put_buffer(f, (uint8_t *)update.hdr_uaddr, update.hdr_len); -+ *bytes_sent = 4 + update.hdr_len; -+ -+ qemu_put_be32(f, update.guest_addr_len); -+ qemu_put_buffer(f, (uint8_t *)update.guest_addr_data, update.guest_addr_len); -+ *bytes_sent = 4 + update.guest_addr_len; -+ -+ qemu_put_be32(f, update.trans_len); -+ qemu_put_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ *bytes_sent += (4 + update.trans_len); -+ -+err: -+ s->guest_addr_len = 0; -+ g_free(trans); -+ return ret; -+} -+ -+int -+csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) -+{ -+ CsvGuestState *s = &csv_guest; -+ uint32_t i = 0; -+ -+ (void) addr; -+ -+ if (!s->guest_addr_data) { -+ s->guest_hva_data = g_new0(struct guest_hva_entry, CSV_OUTGOING_PAGE_NUM); -+ s->guest_addr_data = g_new0(struct guest_addr_entry, CSV_OUTGOING_PAGE_NUM); -+ s->guest_addr_len = 0; -+ } -+ -+ if (s->guest_addr_len >= sizeof(struct guest_addr_entry) * CSV_OUTGOING_PAGE_NUM) { -+ error_report("Failed to queue outgoing page"); -+ return 1; -+ } -+ -+ i = s->guest_addr_len / sizeof(struct guest_addr_entry); -+ s->guest_hva_data[i].hva = (uintptr_t)ptr; -+ s->guest_addr_data[i].share = 0; -+ s->guest_addr_data[i].reserved = 0; -+ s->guest_addr_data[i].gfn = csv_hva_to_gfn(ptr); -+ s->guest_addr_len += sizeof(struct guest_addr_entry); -+ -+ return 0; -+} -+ -+int -+csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) -+{ -+ CsvGuestState *s = &csv_guest; -+ -+ /* -+ * If this is a first buffer then create outgoing encryption context -+ * and write our PDH, policy and session data. -+ */ -+ if (!csv_check_state(SEV_STATE_SEND_UPDATE) && -+ csv_send_start(f, bytes_sent)) { -+ error_report("Failed to create outgoing context"); -+ return 1; -+ } -+ -+ return csv_send_encrypt_data(s, f, NULL, 0, bytes_sent); -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 6412c0c70b..273d69d12c 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -62,6 +62,18 @@ struct dma_map_region { - QTAILQ_ENTRY(dma_map_region) list; - }; - -+#define CSV3_OUTGOING_PAGE_WINDOW_SIZE (512 * TARGET_PAGE_SIZE) -+ -+struct guest_addr_entry { -+ uint64_t share: 1; -+ uint64_t reserved: 11; -+ uint64_t gfn: 52; -+}; -+ -+struct guest_hva_entry { -+ uint64_t hva; -+}; -+ - struct CsvGuestState { - uint32_t policy; - int sev_fd; -@@ -70,6 +82,13 @@ struct CsvGuestState { - const char *(*fw_error_to_str)(int code); - QTAILQ_HEAD(, dma_map_region) dma_map_regions_list; - QemuMutex dma_map_regions_list_mutex; -+ gchar *send_packet_hdr; -+ size_t send_packet_hdr_len; -+ struct guest_hva_entry *guest_hva_data; -+ struct guest_addr_entry *guest_addr_data; -+ size_t guest_addr_len; -+ -+ int (*sev_send_start)(QEMUFile *f, uint64_t *bytes_sent); - }; - - typedef struct CsvGuestState CsvGuestState; -@@ -77,10 +96,13 @@ typedef struct CsvGuestState CsvGuestState; - extern struct CsvGuestState csv_guest; - extern int csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops); - extern int csv_launch_encrypt_vmcb(void); -+extern struct ConfidentialGuestMemoryEncryptionOps csv_memory_encryption_ops; - - int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); - - int csv_shared_region_dma_map(uint64_t start, uint64_t end); - void csv_shared_region_dma_unmap(uint64_t start, uint64_t end); -+int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); -+int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); - - #endif -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 26b6e84d3f..31af1ecdf3 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1173,7 +1173,10 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - qemu_add_vm_change_state_handler(sev_vm_state_change, sev); - add_migration_state_change_notifier(&sev_migration_state_notify); - -- cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; -+ if (csv_enabled()) -+ cgs_class->memory_encryption_ops = &csv_memory_encryption_ops; -+ else -+ cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; - QTAILQ_INIT(&sev->shared_regions_list); - - /* Determine whether support MSR_AMD64_SEV_ES_GHCB */ -@@ -2552,9 +2555,17 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) - return ret; - } - -+static int _sev_send_start(QEMUFile *f, uint64_t *bytes_sent) -+{ -+ SevGuestState *s = sev_guest; -+ -+ return sev_send_start(s, f, bytes_sent); -+} -+ - struct sev_ops sev_ops = { - .sev_ioctl = sev_ioctl, - .fw_error_to_str = fw_error_to_str, -+ .sev_send_start = _sev_send_start, - }; - - static void -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 8b38567c3d..6d1a918413 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -89,6 +89,7 @@ int csv_load_incoming_cpu_state(QEMUFile *f); - struct sev_ops { - int (*sev_ioctl)(int fd, int cmd, void *data, int *error); - const char *(*fw_error_to_str)(int code); -+ int (*sev_send_start)(QEMUFile *f, uint64_t *bytes_sent); - }; - - #endif -diff --git a/target/i386/trace-events b/target/i386/trace-events -index 60a4609c0f..8db3e36385 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -22,3 +22,4 @@ kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int - - # csv.c - kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 -+kvm_csv_send_encrypt_data(void *dst, int len) "trans %p len %d" --- -2.17.1 - diff --git a/1070-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch b/1070-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch deleted file mode 100644 index 39a15d4..0000000 --- a/1070-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch +++ /dev/null @@ -1,204 +0,0 @@ -From e6b96ff4918864bfb3ace811d46cdee74b7a7d91 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Fri, 17 Jun 2022 09:45:45 +0800 -Subject: [PATCH 1070/1072] anolis: csv/i386: add support to migrate the - incoming page - -The csv_receive_encrypt_data() provides the method to read incoming -guest private pages from socket and load them into guest memory. -The routine is similar to CSV2's. Usually, it starts with a RECEIVE -START command to create the migration context. Then RECEIVE ENCRYPT -DATA command is performed to let the firmware load incoming pages -into guest memory. After migration is completed, a RECEIVE FINISH -command is performed to the firmware. - -Change-Id: I53bc350e379fa747c7b3c3b3be9f2fef0bf1af9f ---- - target/i386/csv.c | 87 ++++++++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 2 + - target/i386/sev.c | 8 ++++ - target/i386/sev.h | 1 + - target/i386/trace-events | 1 + - 5 files changed, 99 insertions(+) - -diff --git a/target/i386/csv.c b/target/i386/csv.c -index c5a2bc9924..00ff7d20a5 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -36,11 +36,14 @@ - struct ConfidentialGuestMemoryEncryptionOps csv_memory_encryption_ops = { - .save_setup = sev_save_setup, - .save_outgoing_page = NULL, -+ .load_incoming_page = csv3_load_incoming_page, - .is_gfn_in_unshared_region = NULL, - .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, - .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, - .queue_outgoing_page = csv3_queue_outgoing_page, - .save_queued_outgoing_pages = csv3_save_queued_outgoing_pages, -+ .queue_incoming_page = NULL, -+ .load_queued_incoming_pages = NULL, - }; - - #define CSV_OUTGOING_PAGE_NUM (CSV3_OUTGOING_PAGE_WINDOW_SIZE/TARGET_PAGE_SIZE) -@@ -86,6 +89,7 @@ csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) - QTAILQ_INIT(&csv_guest.dma_map_regions_list); - qemu_mutex_init(&csv_guest.dma_map_regions_list_mutex); - csv_guest.sev_send_start = ops->sev_send_start; -+ csv_guest.sev_receive_start = ops->sev_receive_start; - } - return 0; - } -@@ -482,3 +486,86 @@ csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) - - return csv_send_encrypt_data(s, f, NULL, 0, bytes_sent); - } -+ -+static int -+csv_receive_start(QEMUFile *f) -+{ -+ if (csv_guest.sev_receive_start) -+ return csv_guest.sev_receive_start(f); -+ else -+ return -1; -+} -+ -+static int csv_receive_encrypt_data(QEMUFile *f, uint8_t *ptr) -+{ -+ int ret = 1, fw_error = 0; -+ uint32_t i, guest_addr_entry_num; -+ gchar *hdr = NULL, *trans = NULL; -+ struct guest_addr_entry *guest_addr_data; -+ struct kvm_csv_receive_encrypt_data update = {}; -+ void *hva = NULL; -+ MemoryRegion *mr = NULL; -+ -+ /* get packet header */ -+ update.hdr_len = qemu_get_be32(f); -+ -+ hdr = g_new(gchar, update.hdr_len); -+ qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len); -+ update.hdr_uaddr = (uintptr_t)hdr; -+ -+ /* get guest addr data */ -+ update.guest_addr_len = qemu_get_be32(f); -+ -+ guest_addr_data = (struct guest_addr_entry *)g_new(gchar, update.guest_addr_len); -+ qemu_get_buffer(f, (uint8_t *)guest_addr_data, update.guest_addr_len); -+ update.guest_addr_data = (uintptr_t)guest_addr_data; -+ -+ /* get transport buffer */ -+ update.trans_len = qemu_get_be32(f); -+ -+ trans = g_new(gchar, update.trans_len); -+ update.trans_uaddr = (uintptr_t)trans; -+ qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ -+ /* update share memory. */ -+ guest_addr_entry_num = update.guest_addr_len / sizeof(struct guest_addr_entry); -+ for (i = 0; i < guest_addr_entry_num; i++) { -+ if (guest_addr_data[i].share) { -+ hva = gpa2hva(&mr, -+ ((uint64_t)guest_addr_data[i].gfn << TARGET_PAGE_BITS), -+ TARGET_PAGE_SIZE, -+ NULL); -+ if (hva) -+ memcpy(hva, trans + i * TARGET_PAGE_SIZE, TARGET_PAGE_SIZE); -+ } -+ } -+ -+ trace_kvm_csv_receive_encrypt_data(trans, update.trans_len, hdr, update.hdr_len); -+ -+ ret = csv_ioctl(KVM_CSV_RECEIVE_ENCRYPT_DATA, &update, &fw_error); -+ if (ret) { -+ error_report("Error RECEIVE_ENCRYPT_DATA ret=%d fw_error=%d '%s'", -+ ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+err: -+ g_free(trans); -+ g_free(guest_addr_data); -+ g_free(hdr); -+ return ret; -+} -+ -+int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr) -+{ -+ /* -+ * If this is first buffer and SEV is not in recieiving state then -+ * use RECEIVE_START command to create a encryption context. -+ */ -+ if (!csv_check_state(SEV_STATE_RECEIVE_UPDATE) && -+ csv_receive_start(f)) { -+ return 1; -+ } -+ -+ return csv_receive_encrypt_data(f, ptr); -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 273d69d12c..c8639cfa9a 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -89,6 +89,7 @@ struct CsvGuestState { - size_t guest_addr_len; - - int (*sev_send_start)(QEMUFile *f, uint64_t *bytes_sent); -+ int (*sev_receive_start)(QEMUFile *f); - }; - - typedef struct CsvGuestState CsvGuestState; -@@ -102,6 +103,7 @@ int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); - - int csv_shared_region_dma_map(uint64_t start, uint64_t end); - void csv_shared_region_dma_unmap(uint64_t start, uint64_t end); -+int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr); - int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); - int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 31af1ecdf3..40e52985ac 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -2562,10 +2562,18 @@ static int _sev_send_start(QEMUFile *f, uint64_t *bytes_sent) - return sev_send_start(s, f, bytes_sent); - } - -+static int _sev_receive_start(QEMUFile *f) -+{ -+ SevGuestState *s = sev_guest; -+ -+ return sev_receive_start(s, f); -+} -+ - struct sev_ops sev_ops = { - .sev_ioctl = sev_ioctl, - .fw_error_to_str = fw_error_to_str, - .sev_send_start = _sev_send_start, -+ .sev_receive_start = _sev_receive_start, - }; - - static void -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 6d1a918413..9e5c6506c8 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -90,6 +90,7 @@ struct sev_ops { - int (*sev_ioctl)(int fd, int cmd, void *data, int *error); - const char *(*fw_error_to_str)(int code); - int (*sev_send_start)(QEMUFile *f, uint64_t *bytes_sent); -+ int (*sev_receive_start)(QEMUFile *f); - }; - - #endif -diff --git a/target/i386/trace-events b/target/i386/trace-events -index 8db3e36385..1854356fc5 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -23,3 +23,4 @@ kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int - # csv.c - kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 - kvm_csv_send_encrypt_data(void *dst, int len) "trans %p len %d" -+kvm_csv_receive_encrypt_data(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" --- -2.17.1 - diff --git a/1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch b/1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch deleted file mode 100644 index 629f713..0000000 --- a/1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch +++ /dev/null @@ -1,137 +0,0 @@ -From cd3f19da06a1691a790221a06a2899427e2140cd Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Fri, 17 Jun 2022 09:52:31 +0800 -Subject: [PATCH 1071/1072] anolis: csv/i386: add support to migrate the - outgoing context - -CSV needs to migrate guest cpu's context pages. Prior to migration -of the context, it should query transfer buffer length and header -data length by SEND ENCRYPT CONTEXT command. New migration flag -RAM_SAVE_ENCRYPTED_CSV_CONTEXT is defined for CSV. - -Change-Id: I1989e76bd5c91c78074fb31eff075deacfa16078 ---- - target/i386/csv.c | 79 ++++++++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 1 + - target/i386/trace-events | 1 + - 3 files changed, 81 insertions(+) - -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 00ff7d20a5..271c48867e 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -44,6 +44,7 @@ struct ConfidentialGuestMemoryEncryptionOps csv_memory_encryption_ops = { - .save_queued_outgoing_pages = csv3_save_queued_outgoing_pages, - .queue_incoming_page = NULL, - .load_queued_incoming_pages = NULL, -+ .save_outgoing_cpu_state = csv3_save_outgoing_context, - }; - - #define CSV_OUTGOING_PAGE_NUM (CSV3_OUTGOING_PAGE_WINDOW_SIZE/TARGET_PAGE_SIZE) -@@ -569,3 +570,81 @@ int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr) - - return csv_receive_encrypt_data(f, ptr); - } -+ -+static int -+csv_send_get_context_len(int *fw_err, int *context_len, int *hdr_len) -+{ -+ int ret = 0; -+ struct kvm_csv_send_encrypt_context update = {}; -+ -+ ret = csv_ioctl(KVM_CSV_SEND_ENCRYPT_CONTEXT, &update, fw_err); -+ if (*fw_err != SEV_RET_INVALID_LEN) { -+ error_report("%s: failed to get context length ret=%d fw_error=%d '%s'", -+ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); -+ ret = -1; -+ goto err; -+ } -+ -+ if (update.trans_len <= INT_MAX && update.hdr_len <= INT_MAX) { -+ *context_len = update.trans_len; -+ *hdr_len = update.hdr_len; -+ } -+ ret = 0; -+err: -+ return ret; -+} -+ -+static int -+csv_send_encrypt_context(CsvGuestState *s, QEMUFile *f) -+{ -+ int ret, fw_error = 0; -+ int context_len = 0; -+ int hdr_len = 0; -+ guchar *trans; -+ guchar *hdr; -+ struct kvm_csv_send_encrypt_context update = { }; -+ -+ ret = csv_send_get_context_len(&fw_error, &context_len, &hdr_len); -+ if (context_len < 1 || hdr_len < 1) { -+ error_report("%s: fail to get context length fw_error=%d '%s'", -+ __func__, fw_error, fw_error_to_str(fw_error)); -+ return 1; -+ } -+ -+ /* allocate transport buffer */ -+ trans = g_new(guchar, context_len); -+ hdr = g_new(guchar, hdr_len); -+ -+ update.hdr_uaddr = (uintptr_t)hdr; -+ update.hdr_len = hdr_len; -+ update.trans_uaddr = (uintptr_t)trans; -+ update.trans_len = context_len; -+ -+ trace_kvm_csv_send_encrypt_context(trans, update.trans_len); -+ -+ ret = csv_ioctl(KVM_CSV_SEND_ENCRYPT_CONTEXT, &update, &fw_error); -+ if (ret) { -+ error_report("%s: SEND_ENCRYPT_CONTEXT ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ qemu_put_be32(f, update.hdr_len); -+ qemu_put_buffer(f, (uint8_t *)update.hdr_uaddr, update.hdr_len); -+ -+ qemu_put_be32(f, update.trans_len); -+ qemu_put_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ -+err: -+ g_free(trans); -+ g_free(hdr); -+ return ret; -+} -+ -+int csv3_save_outgoing_context(QEMUFile *f) -+{ -+ CsvGuestState *s = &csv_guest; -+ -+ /* send csv context. */ -+ return csv_send_encrypt_context(s, f); -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index c8639cfa9a..9def1611d8 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -103,6 +103,7 @@ int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); - - int csv_shared_region_dma_map(uint64_t start, uint64_t end); - void csv_shared_region_dma_unmap(uint64_t start, uint64_t end); -+int csv3_save_outgoing_context(QEMUFile *f); - int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr); - int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); - int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); -diff --git a/target/i386/trace-events b/target/i386/trace-events -index 1854356fc5..08a782ce15 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -23,4 +23,5 @@ kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int - # csv.c - kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 - kvm_csv_send_encrypt_data(void *dst, int len) "trans %p len %d" -+kvm_csv_send_encrypt_context(void *dst, int len) "trans %p len %d" - kvm_csv_receive_encrypt_data(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" --- -2.17.1 - diff --git a/1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch b/1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch deleted file mode 100644 index 1c6084b..0000000 --- a/1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 40741ce0d0bb68d789d84407c77d2282ecd4f67f Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Fri, 17 Jun 2022 10:00:46 +0800 -Subject: [PATCH 1072/1072] anolis: csv/i386: add support to migrate the - incoming context - -The csv_load_incoming_context() provides the method to read incoming -guest's context from socket. It loads them into guest private memory. -This is the last step during migration and RECEIVE FINISH command is -performed by then to complete the whole migration. - -Change-Id: I7290e0e9527bb819eee5813038110d981908a880 ---- - target/i386/csv.c | 45 ++++++++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 1 + - target/i386/trace-events | 1 + - 3 files changed, 47 insertions(+) - -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 271c48867e..b0ca16980d 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -45,6 +45,7 @@ struct ConfidentialGuestMemoryEncryptionOps csv_memory_encryption_ops = { - .queue_incoming_page = NULL, - .load_queued_incoming_pages = NULL, - .save_outgoing_cpu_state = csv3_save_outgoing_context, -+ .load_incoming_cpu_state = csv3_load_incoming_context, - }; - - #define CSV_OUTGOING_PAGE_NUM (CSV3_OUTGOING_PAGE_WINDOW_SIZE/TARGET_PAGE_SIZE) -@@ -641,6 +642,42 @@ err: - return ret; - } - -+static int -+csv_receive_encrypt_context(CsvGuestState *s, QEMUFile *f) -+{ -+ int ret = 1, fw_error = 0; -+ gchar *hdr = NULL, *trans = NULL; -+ struct kvm_csv_receive_encrypt_context update = {}; -+ -+ /* get packet header */ -+ update.hdr_len = qemu_get_be32(f); -+ -+ hdr = g_new(gchar, update.hdr_len); -+ qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len); -+ update.hdr_uaddr = (uintptr_t)hdr; -+ -+ /* get transport buffer */ -+ update.trans_len = qemu_get_be32(f); -+ -+ trans = g_new(gchar, update.trans_len); -+ update.trans_uaddr = (uintptr_t)trans; -+ qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ -+ trace_kvm_csv_receive_encrypt_context(trans, update.trans_len, hdr, update.hdr_len); -+ -+ ret = csv_ioctl(KVM_CSV_RECEIVE_ENCRYPT_CONTEXT, &update, &fw_error); -+ if (ret) { -+ error_report("Error RECEIVE_ENCRYPT_CONTEXT ret=%d fw_error=%d '%s'", -+ ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+err: -+ g_free(trans); -+ g_free(hdr); -+ return ret; -+} -+ - int csv3_save_outgoing_context(QEMUFile *f) - { - CsvGuestState *s = &csv_guest; -@@ -648,3 +685,11 @@ int csv3_save_outgoing_context(QEMUFile *f) - /* send csv context. */ - return csv_send_encrypt_context(s, f); - } -+ -+int csv3_load_incoming_context(QEMUFile *f) -+{ -+ CsvGuestState *s = &csv_guest; -+ -+ /* receive csv context. */ -+ return csv_receive_encrypt_context(s, f); -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 9def1611d8..2e0506313d 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -104,6 +104,7 @@ int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); - int csv_shared_region_dma_map(uint64_t start, uint64_t end); - void csv_shared_region_dma_unmap(uint64_t start, uint64_t end); - int csv3_save_outgoing_context(QEMUFile *f); -+int csv3_load_incoming_context(QEMUFile *f); - int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr); - int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); - int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); -diff --git a/target/i386/trace-events b/target/i386/trace-events -index 08a782ce15..47ab390de6 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -25,3 +25,4 @@ kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PR - kvm_csv_send_encrypt_data(void *dst, int len) "trans %p len %d" - kvm_csv_send_encrypt_context(void *dst, int len) "trans %p len %d" - kvm_csv_receive_encrypt_data(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" -+kvm_csv_receive_encrypt_context(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" --- -2.17.1 - diff --git a/1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch b/1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch deleted file mode 100644 index 7e6f98e..0000000 --- a/1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 9cd331388ce95e3d7365fceab30016756eae2483 Mon Sep 17 00:00:00 2001 -From: appleLin -Date: Wed, 3 Aug 2022 21:02:41 +0800 -Subject: [PATCH] anolis: target/i386/sev: Add support for reuse ASID for - different CSV guests - -In you want to reuse one ASID for many CSV guests, you should provide a -label (i.e. userid) and the length of the label when launch CSV guest. -The CSV guests which were provided the same userid will share the same -ASID. - -Signed-off-by: hanliyang ---- - linux-headers/linux/kvm.h | 5 +++++ - qapi/qom.json | 5 ++++- - qemu-options.hx | 5 ++++- - target/i386/csv.c | 2 -- - target/i386/csv.h | 3 +++ - target/i386/sev.c | 47 ++++++++++++++++++++++++++++++++++++++- - 6 files changed, 62 insertions(+), 5 deletions(-) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 5fe2f8d04..3875127a3 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2011,6 +2011,11 @@ struct kvm_csv_receive_encrypt_context { - __u32 trans_len; - }; - -+struct kvm_csv_init { -+ __u64 userid_addr; -+ __u32 len; -+}; -+ - #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) - #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) - #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) -diff --git a/qapi/qom.json b/qapi/qom.json -index eeb5395ff..387c0a142 100644 ---- a/qapi/qom.json -+++ b/qapi/qom.json -@@ -773,6 +773,8 @@ - # designated guest firmware page for measured boot - # with -kernel (default: false) (since 6.2) - # -+# @user-id: the user id of the guest owner, only support on Hygon CPUs -+# - # Since: 2.12 - ## - { 'struct': 'SevGuestProperties', -@@ -783,7 +785,8 @@ - '*handle': 'uint32', - '*cbitpos': 'uint32', - 'reduced-phys-bits': 'uint32', -- '*kernel-hashes': 'bool' } } -+ '*kernel-hashes': 'bool', -+ '*user-id': 'str' } } - - ## - # @ObjectType: -diff --git a/qemu-options.hx b/qemu-options.hx -index 8997969d5..115e1835f 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -5189,7 +5189,7 @@ SRST - -object secret,id=sec0,keyid=secmaster0,format=base64,\\ - data=$SECRET,iv=$(dh_cert_file = g_strdup(value); - } - -+static char * -+sev_guest_get_user_id(Object *obj, Error **errp) -+{ -+ SevGuestState *s = SEV_GUEST(obj); -+ -+ return g_strdup(s->user_id); -+} -+ -+static void -+sev_guest_set_user_id(Object *obj, const char *value, Error **errp) -+{ -+ SevGuestState *s = SEV_GUEST(obj); -+ -+ s->user_id = g_strdup(value); -+} -+ - static char * - sev_guest_get_sev_device(Object *obj, Error **errp) - { -@@ -436,6 +453,11 @@ sev_guest_class_init(ObjectClass *oc, void *data) - sev_guest_set_kernel_hashes); - object_class_property_set_description(oc, "kernel-hashes", - "add kernel hashes to guest firmware for measured Linux boot"); -+ object_class_property_add_str(oc, "user-id", -+ sev_guest_get_user_id, -+ sev_guest_set_user_id); -+ object_class_property_set_description(oc, "user-id", -+ "user id of the guest owner"); - } - - static void -@@ -1137,7 +1159,30 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - } - - trace_kvm_sev_init(); -- ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); -+ -+ /* Only support reuse asid for CSV/CSV2 guest */ -+ if (is_hygon_cpu() && -+ (sev_guest->policy & GUEST_POLICY_REUSE_ASID) && -+ !(sev_guest->policy & GUEST_POLICY_CSV_BIT)) { -+ char *user_id = NULL; -+ struct kvm_csv_init *init_cmd_buf = NULL; -+ -+ user_id = object_property_get_str(OBJECT(sev), "user-id", NULL); -+ if (user_id && strlen(user_id)) { -+ init_cmd_buf = g_new0(struct kvm_csv_init, 1); -+ init_cmd_buf->len = strlen(user_id); -+ init_cmd_buf->userid_addr = (__u64)user_id; -+ } -+ ret = sev_ioctl(sev->sev_fd, cmd, init_cmd_buf, &fw_error); -+ -+ if (user_id) { -+ g_free(user_id); -+ g_free(init_cmd_buf); -+ } -+ } else { -+ ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); -+ } -+ - if (ret) { - error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'", - __func__, ret, fw_error, fw_error_to_str(fw_error)); --- -2.31.1 - diff --git a/1074-newfeature-support-vpsp.patch b/1074-newfeature-support-vpsp.patch deleted file mode 100644 index 2efaa12..0000000 --- a/1074-newfeature-support-vpsp.patch +++ /dev/null @@ -1,190 +0,0 @@ -From fd593b7516631ed0dce757cdce4d10b28971c553 Mon Sep 17 00:00:00 2001 -From: xiongmengbiao -Date: Wed, 6 Mar 2024 17:43:57 +0800 -Subject: [PATCH] [newfeature]: support vpsp - -simulate a psp misc device for support tkm's key isolation - -Signed-off-by: xiongmengbiao ---- - hw/misc/Kconfig | 4 ++ - hw/misc/meson.build | 1 + - hw/misc/psp.c | 141 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 146 insertions(+) - create mode 100644 hw/misc/psp.c - -diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig -index 507058d8b..d1d05442d 100644 ---- a/hw/misc/Kconfig -+++ b/hw/misc/Kconfig -@@ -171,4 +171,8 @@ config SIFIVE_U_PRCI - config VIRT_CTRL - bool - -+config PSP_DEV -+ bool -+ default y -+ - source macio/Kconfig -diff --git a/hw/misc/meson.build b/hw/misc/meson.build -index 3f41a3a5b..39e583631 100644 ---- a/hw/misc/meson.build -+++ b/hw/misc/meson.build -@@ -10,6 +10,7 @@ softmmu_ss.add(when: 'CONFIG_UNIMP', if_true: files('unimp.c')) - softmmu_ss.add(when: 'CONFIG_EMPTY_SLOT', if_true: files('empty_slot.c')) - softmmu_ss.add(when: 'CONFIG_LED', if_true: files('led.c')) - softmmu_ss.add(when: 'CONFIG_PVPANIC_COMMON', if_true: files('pvpanic.c')) -+softmmu_ss.add(when: 'CONFIG_PSP_DEV', if_true: files('psp.c')) - - # ARM devices - softmmu_ss.add(when: 'CONFIG_PL310', if_true: files('arm_l2x0.c')) -diff --git a/hw/misc/psp.c b/hw/misc/psp.c -new file mode 100644 -index 000000000..1cfbab859 ---- /dev/null -+++ b/hw/misc/psp.c -@@ -0,0 +1,141 @@ -+/* -+ * hygon psp device emulation -+ * -+ * Copyright 2024 HYGON Corp. -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or (at -+ * your option) any later version. See the COPYING file in the top-level -+ * directory. -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/compiler.h" -+#include "qemu/error-report.h" -+#include "qapi/error.h" -+#include "migration/vmstate.h" -+#include "hw/qdev-properties.h" -+#include "sysemu/runstate.h" -+#include -+ -+#define TYPE_PSP_DEV "psp" -+OBJECT_DECLARE_SIMPLE_TYPE(PSPDevState, PSP_DEV) -+ -+struct PSPDevState { -+ /* Private */ -+ DeviceState pdev; -+ -+ /* Public */ -+ Notifier shutdown_notifier; -+ int dev_fd; -+ uint8_t enabled; -+ -+ /** -+ * vid is used to identify a virtual machine in qemu. -+ * When a virtual machine accesses a tkm key, -+ * the TKM module uses different key spaces based on different vids. -+ */ -+ uint32_t vid; -+}; -+ -+#define PSP_DEV_PATH "/dev/hygon_psp_config" -+#define HYGON_PSP_IOC_TYPE 'H' -+#define PSP_IOC_MUTEX_ENABLE _IOWR(HYGON_PSP_IOC_TYPE, 1, NULL) -+#define PSP_IOC_MUTEX_DISABLE _IOWR(HYGON_PSP_IOC_TYPE, 2, NULL) -+#define PSP_IOC_VPSP_OPT _IOWR(HYGON_PSP_IOC_TYPE, 3, NULL) -+ -+enum VPSP_DEV_CTRL_OPCODE { -+ VPSP_OP_VID_ADD, -+ VPSP_OP_VID_DEL, -+}; -+ -+struct psp_dev_ctrl { -+ unsigned char op; -+ union { -+ unsigned int vid; -+ unsigned char reserved[128]; -+ } data; -+}; -+ -+static void psp_dev_destroy(PSPDevState *state) -+{ -+ struct psp_dev_ctrl ctrl = { 0 }; -+ if (state && state->dev_fd) { -+ if (state->enabled) { -+ ctrl.op = VPSP_OP_VID_DEL; -+ if (ioctl(state->dev_fd, PSP_IOC_VPSP_OPT, &ctrl) < 0) { -+ error_report("VPSP_OP_VID_DEL: %d", -errno); -+ } else { -+ state->enabled = false; -+ } -+ } -+ qemu_close(state->dev_fd); -+ state->dev_fd = 0; -+ } -+} -+ -+/** -+ * Guest OS performs shut down operations through 'shutdown' and 'powerdown' event. -+ * The 'powerdown' event will also trigger 'shutdown' in the end, -+ * so only attention to the 'shutdown' event. -+ * -+ * When Guest OS trigger 'reboot' or 'reset' event, to do nothing. -+*/ -+static void psp_dev_shutdown_notify(Notifier *notifier, void *data) -+{ -+ PSPDevState *state = container_of(notifier, PSPDevState, shutdown_notifier); -+ psp_dev_destroy(state); -+} -+ -+static void psp_dev_realize(DeviceState *dev, Error **errp) -+{ -+ struct psp_dev_ctrl ctrl = { 0 }; -+ PSPDevState *state = PSP_DEV(dev); -+ -+ state->dev_fd = qemu_open_old(PSP_DEV_PATH, O_RDWR); -+ if (state->dev_fd < 0) { -+ error_setg(errp, "fail to open %s, errno %d.", PSP_DEV_PATH, errno); -+ goto end; -+ } -+ -+ ctrl.op = VPSP_OP_VID_ADD; -+ ctrl.data.vid = state->vid; -+ if (ioctl(state->dev_fd, PSP_IOC_VPSP_OPT, &ctrl) < 0) { -+ error_setg(errp, "psp_dev_realize VPSP_OP_VID_ADD vid %d, return %d", ctrl.data.vid, -errno); -+ goto end; -+ } -+ -+ state->enabled = true; -+ state->shutdown_notifier.notify = psp_dev_shutdown_notify; -+ qemu_register_shutdown_notifier(&state->shutdown_notifier); -+end: -+ return; -+} -+ -+static struct Property psp_dev_properties[] = { -+ DEFINE_PROP_UINT32("vid", PSPDevState, vid, 0), -+ DEFINE_PROP_END_OF_LIST(), -+}; -+ -+static void psp_dev_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ -+ dc->desc = "PSP Device"; -+ dc->realize = psp_dev_realize; -+ set_bit(DEVICE_CATEGORY_MISC, dc->categories); -+ device_class_set_props(dc, psp_dev_properties); -+} -+ -+static const TypeInfo psp_dev_info = { -+ .name = TYPE_PSP_DEV, -+ .parent = TYPE_DEVICE, -+ .instance_size = sizeof(PSPDevState), -+ .class_init = psp_dev_class_init, -+}; -+ -+static void psp_dev_register_types(void) -+{ -+ type_register_static(&psp_dev_info); -+} -+ -+type_init(psp_dev_register_types) --- -2.36.6 - diff --git a/1075-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch b/1075-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch deleted file mode 100644 index abbf1da..0000000 --- a/1075-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 858884a2a18df9bcb07176fc14a6ea5ee872f8dc Mon Sep 17 00:00:00 2001 -From: Yanjing Zhou -Date: Tue, 11 Jun 2024 14:28:12 +0800 -Subject: [PATCH 1/2] target/i386: Add Hygon Dhyana-v3 CPU model - -Add the following feature bits for Dhyana CPU model: -perfctr-core, clzero, xsaveerptr, aes, pclmulqdq, sha-ni - -Disable xsaves feature bit for Erratum 1386 - -Signed-off-by: Yanjing Zhou ---- - target/i386/cpu.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index aa9e63680..43a57be0b 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -4057,6 +4057,20 @@ static const X86CPUDefinition builtin_x86_defs[] = { - { /* end of list */ } - }, - }, -+ { .version = 3, -+ .props = (PropValue[]) { -+ { "xsaves", "off" }, -+ { "perfctr-core", "on" }, -+ { "clzero", "on" }, -+ { "xsaveerptr", "on" }, -+ { "aes", "on" }, -+ { "pclmulqdq", "on" }, -+ { "sha-ni", "on" }, -+ { "model-id", -+ "Hygon Dhyana-v3 processor" }, -+ { /* end of list */ } -+ }, -+ }, - { /* end of list */ } - } - }, --- -2.39.3 - diff --git a/1076-target-i386-Add-new-Hygon-Dharma-CPU-model.patch b/1076-target-i386-Add-new-Hygon-Dharma-CPU-model.patch deleted file mode 100644 index d12c1a5..0000000 --- a/1076-target-i386-Add-new-Hygon-Dharma-CPU-model.patch +++ /dev/null @@ -1,133 +0,0 @@ -From b3dfdd0e3cf7795fb66b094ffd821e193b9a773a Mon Sep 17 00:00:00 2001 -From: Yanjing Zhou -Date: Tue, 11 Jun 2024 14:29:34 +0800 -Subject: [PATCH 2/2] target/i386: Add new Hygon 'Dharma' CPU model - -Add the following feature bits compare to Dhyana CPU model: -stibp, ibrs, umip, ssbd - -Signed-off-by: Yanjing Zhou ---- - target/i386/cpu.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 99 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 43a57be0b..07b65da92 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1731,6 +1731,56 @@ static const CPUCaches epyc_milan_cache_info = { - }, - }; - -+static const CPUCaches dharma_cache_info = { -+ .l1d_cache = &(CPUCacheInfo) { -+ .type = DATA_CACHE, -+ .level = 1, -+ .size = 32 * KiB, -+ .line_size = 64, -+ .associativity = 8, -+ .partitions = 1, -+ .sets = 64, -+ .lines_per_tag = 1, -+ .self_init = 1, -+ .no_invd_sharing = true, -+ }, -+ .l1i_cache = &(CPUCacheInfo) { -+ .type = INSTRUCTION_CACHE, -+ .level = 1, -+ .size = 32 * KiB, -+ .line_size = 64, -+ .associativity = 8, -+ .partitions = 1, -+ .sets = 64, -+ .lines_per_tag = 1, -+ .self_init = 1, -+ .no_invd_sharing = true, -+ }, -+ .l2_cache = &(CPUCacheInfo) { -+ .type = UNIFIED_CACHE, -+ .level = 2, -+ .size = 512 * KiB, -+ .line_size = 64, -+ .associativity = 8, -+ .partitions = 1, -+ .sets = 1024, -+ .lines_per_tag = 1, -+ }, -+ .l3_cache = &(CPUCacheInfo) { -+ .type = UNIFIED_CACHE, -+ .level = 3, -+ .size = 16 * MiB, -+ .line_size = 64, -+ .associativity = 16, -+ .partitions = 1, -+ .sets = 16384, -+ .lines_per_tag = 1, -+ .self_init = true, -+ .inclusive = true, -+ .complex_indexing = true, -+ }, -+}; -+ - /* The following VMX features are not supported by KVM and are left out in the - * CPU definitions: - * -@@ -4191,6 +4241,55 @@ static const X86CPUDefinition builtin_x86_defs[] = { - .model_id = "AMD EPYC-Milan Processor", - .cache_info = &epyc_milan_cache_info, - }, -+ { -+ .name = "Dharma", -+ .level = 0xd, -+ .vendor = CPUID_VENDOR_HYGON, -+ .family = 24, -+ .model = 4, -+ .stepping = 0, -+ .features[FEAT_1_EDX] = -+ CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH | -+ CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE | -+ CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE | -+ CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE | -+ CPUID_VME | CPUID_FP87, -+ .features[FEAT_1_ECX] = -+ CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX | -+ CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT | -+ CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | -+ CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 | -+ CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3, -+ .features[FEAT_8000_0001_EDX] = -+ CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB | -+ CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX | -+ CPUID_EXT2_SYSCALL, -+ .features[FEAT_8000_0001_ECX] = -+ CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH | -+ CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | -+ CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM | -+ CPUID_EXT3_TOPOEXT | CPUID_EXT3_PERFCORE, -+ .features[FEAT_8000_0008_EBX] = -+ CPUID_8000_0008_EBX_CLZERO | CPUID_8000_0008_EBX_XSAVEERPTR | -+ CPUID_8000_0008_EBX_IBPB | CPUID_8000_0008_EBX_IBRS | -+ CPUID_8000_0008_EBX_STIBP | CPUID_8000_0008_EBX_AMD_SSBD, -+ .features[FEAT_7_0_EBX] = -+ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 | -+ CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED | -+ CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT | -+ CPUID_7_0_EBX_SHA_NI, -+ .features[FEAT_7_0_ECX] = CPUID_7_0_ECX_UMIP, -+ .features[FEAT_XSAVE] = -+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | -+ CPUID_XSAVE_XGETBV1, -+ .features[FEAT_6_EAX] = -+ CPUID_6_EAX_ARAT, -+ .features[FEAT_SVM] = -+ CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE, -+ .xlevel = 0x8000001E, -+ .model_id = "Hygon Dharma Processor", -+ .cache_info = &dharma_cache_info, -+ }, - }; - - /* --- -2.39.3 - diff --git a/1077-target-i386-add-FSRM-to-TCG.patch b/1077-target-i386-add-FSRM-to-TCG.patch deleted file mode 100644 index bf309ac..0000000 --- a/1077-target-i386-add-FSRM-to-TCG.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Paolo Bonzini -Date: Mon, 27 Feb 2023 10:57:09 +0100 -Subject: [PATCH] target/i386: add FSRM to TCG - -commit c0728d4e3d23356691e4182eac54c67e1ca26618 upstream. - -Fast short REP MOVS can be added to TCG, since a trivial translation -of string operation is a good option for short lengths. - -Intel-SIG: commit c0728d4e3d23 target/i386: add FSRM to TCG. -Add SPR/GNR/SRA new ISAs backporting - -Reviewed-by: Xiaoyao Li -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 7d779c6a8..e54a60d3c 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -661,7 +661,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, - #define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | \ - /* CPUID_7_0_ECX_OSPKE is dynamic */ \ - CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS) --#define TCG_7_0_EDX_FEATURES 0 -+#define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM - #define TCG_7_1_EAX_FEATURES 0 - #define TCG_APM_FEATURES 0 - #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT --- -2.25.1 diff --git a/1078-target-i386-add-FZRM-FSRS-FSRC.patch b/1078-target-i386-add-FZRM-FSRS-FSRC.patch deleted file mode 100644 index 5b872b3..0000000 --- a/1078-target-i386-add-FZRM-FSRS-FSRC.patch +++ /dev/null @@ -1,67 +0,0 @@ -From: Paolo Bonzini -Date: Mon, 27 Feb 2023 10:55:46 +0100 -Subject: [PATCH] target/i386: add FZRM, FSRS, FSRC - -commit 58794f644e43ef8e60ed05395c58099311c1fcd1 upstream. - -These are three more markers for string operation optimizations. -They can all be added to TCG, whose string operations are more or -less as fast as they can be for short lengths. - -Intel-SIG: commit 58794f644e43 target/i386: add FZRM, FSRS, FSRC. -Add SPR/GNR/SRA new ISAs backporting - -Reviewed-by: Xiaoyao Li -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 7 ++++--- - target/i386/cpu.h | 7 +++++++ - 2 files changed, 11 insertions(+), 3 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index e54a60d3c..04cb9292b 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -662,7 +662,8 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, - /* CPUID_7_0_ECX_OSPKE is dynamic */ \ - CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS) - #define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM --#define TCG_7_1_EAX_FEATURES 0 -+#define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \ -+ CPUID_7_1_EAX_FSRC) - #define TCG_APM_FEATURES 0 - #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT - #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1) -@@ -872,8 +873,8 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .feat_names = { - NULL, NULL, NULL, NULL, - "avx-vnni", "avx512-bf16", NULL, NULL, -- NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ NULL, NULL, "fzrm", "fsrs", -+ "fsrc", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 1415a33fb..98f885ace 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -879,6 +879,13 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EAX_AVX_VNNI (1U << 4) - /* AVX512 BFloat16 Instruction */ - #define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) -+/* Fast Zero REP MOVS */ -+#define CPUID_7_1_EAX_FZRM (1U << 10) -+/* Fast Short REP STOS */ -+#define CPUID_7_1_EAX_FSRS (1U << 11) -+/* Fast Short REP CMPS/SCAS */ -+#define CPUID_7_1_EAX_FSRC (1U << 12) -+ - /* XFD Extend Feature Disabled */ - #define CPUID_D_1_EAX_XFD (1U << 4) - --- -2.25.1 diff --git a/1079-i386-Add-new-CPU-model-SapphireRapids.patch b/1079-i386-Add-new-CPU-model-SapphireRapids.patch deleted file mode 100644 index 6176a1a..0000000 --- a/1079-i386-Add-new-CPU-model-SapphireRapids.patch +++ /dev/null @@ -1,226 +0,0 @@ -From: "Wang, Lei" -Date: Thu, 11 Aug 2022 22:57:51 -0700 -Subject: [PATCH] i386: Add new CPU model SapphireRapids - -commit 7eb061b06e97af9a8da7f31b839d78997ae737fc upstream. - -The new CPU model mostly inherits features from Icelake-Server, while -adding new features: - - AMX (Advance Matrix eXtensions) - - Bus Lock Debug Exception -and new instructions: - - AVX VNNI (Vector Neural Network Instruction): - - VPDPBUS: Multiply and Add Unsigned and Signed Bytes - - VPDPBUSDS: Multiply and Add Unsigned and Signed Bytes with Saturation - - VPDPWSSD: Multiply and Add Signed Word Integers - - VPDPWSSDS: Multiply and Add Signed Integers with Saturation - - FP16: Replicates existing AVX512 computational SP (FP32) instructions - using FP16 instead of FP32 for ~2X performance gain - - SERIALIZE: Provide software with a simple way to force the processor to - complete all modifications, faster, allowed in all privilege levels and - not causing an unconditional VM exit - - TSX Suspend Load Address Tracking: Allows programmers to choose which - memory accesses do not need to be tracked in the TSX read set - - AVX512_BF16: Vector Neural Network Instructions supporting BFLOAT16 - inputs and conversion instructions from IEEE single precision - - fast zero-length MOVSB (KVM doesn't support yet) - - fast short STOSB (KVM doesn't support yet) - - fast short CMPSB, SCASB (KVM doesn't support yet) - -Features that may be added in future versions: - - CET (virtualization support hasn't been merged) - -Intel-SIG: commit 7eb061b06e97 i386: Add new CPU model SapphireRapids. -Add SPR/GNR/SRA new ISAs backporting - -Signed-off-by: Wang, Lei -Reviewed-by: Robert Hoo -Message-Id: <20220812055751.14553-1-lei4.wang@intel.com> -Reviewed-by: Xiaoyao Li -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 133 +++++++++++++++++++++++++++++++++++++++++++++- - target/i386/cpu.h | 4 ++ - 2 files changed, 135 insertions(+), 2 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 04cb9292b..30d19b794 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -3546,6 +3546,135 @@ static const X86CPUDefinition builtin_x86_defs[] = { - { /* end of list */ } - } - }, -+ { -+ .name = "SapphireRapids", -+ .level = 0x20, -+ .vendor = CPUID_VENDOR_INTEL, -+ .family = 6, -+ .model = 143, -+ .stepping = 4, -+ /* -+ * please keep the ascending order so that we can have a clear view of -+ * bit position of each feature. -+ */ -+ .features[FEAT_1_EDX] = -+ CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | -+ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | -+ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | -+ CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR | -+ CPUID_SSE | CPUID_SSE2, -+ .features[FEAT_1_ECX] = -+ CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 | -+ CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | CPUID_EXT_SSE41 | -+ CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE | -+ CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES | -+ CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND, -+ .features[FEAT_8000_0001_EDX] = -+ CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB | -+ CPUID_EXT2_RDTSCP | CPUID_EXT2_LM, -+ .features[FEAT_8000_0001_ECX] = -+ CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH, -+ .features[FEAT_8000_0008_EBX] = -+ CPUID_8000_0008_EBX_WBNOINVD, -+ .features[FEAT_7_0_EBX] = -+ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_HLE | -+ CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | -+ CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RTM | -+ CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ | -+ CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | -+ CPUID_7_0_EBX_AVX512IFMA | CPUID_7_0_EBX_CLFLUSHOPT | -+ CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_AVX512CD | CPUID_7_0_EBX_SHA_NI | -+ CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL, -+ .features[FEAT_7_0_ECX] = -+ CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | -+ CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI | -+ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ | -+ CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG | -+ CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57 | -+ CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT, -+ .features[FEAT_7_0_EDX] = -+ CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_SERIALIZE | -+ CPUID_7_0_EDX_TSX_LDTRK | CPUID_7_0_EDX_AMX_BF16 | -+ CPUID_7_0_EDX_AVX512_FP16 | CPUID_7_0_EDX_AMX_TILE | -+ CPUID_7_0_EDX_AMX_INT8 | CPUID_7_0_EDX_SPEC_CTRL | -+ CPUID_7_0_EDX_ARCH_CAPABILITIES | CPUID_7_0_EDX_SPEC_CTRL_SSBD, -+ .features[FEAT_ARCH_CAPABILITIES] = -+ MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL | -+ MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO | -+ MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_TAA_NO, -+ .features[FEAT_XSAVE] = -+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | -+ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES | CPUID_D_1_EAX_XFD, -+ .features[FEAT_6_EAX] = -+ CPUID_6_EAX_ARAT, -+ .features[FEAT_7_1_EAX] = -+ CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_AVX512_BF16 | -+ CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_FSRC, -+ .features[FEAT_VMX_BASIC] = -+ MSR_VMX_BASIC_INS_OUTS | MSR_VMX_BASIC_TRUE_CTLS, -+ .features[FEAT_VMX_ENTRY_CTLS] = -+ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_IA32E_MODE | -+ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | -+ VMX_VM_ENTRY_LOAD_IA32_PAT | VMX_VM_ENTRY_LOAD_IA32_EFER, -+ .features[FEAT_VMX_EPT_VPID_CAPS] = -+ MSR_VMX_EPT_EXECONLY | -+ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_PAGE_WALK_LENGTH_5 | -+ MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB | -+ MSR_VMX_EPT_INVEPT | MSR_VMX_EPT_AD_BITS | -+ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | -+ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | -+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | -+ MSR_VMX_EPT_INVVPID_ALL_CONTEXT | -+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, -+ .features[FEAT_VMX_EXIT_CTLS] = -+ VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | -+ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | -+ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_IA32_PAT | -+ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | -+ VMX_VM_EXIT_LOAD_IA32_EFER | VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, -+ .features[FEAT_VMX_MISC] = -+ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_ACTIVITY_HLT | -+ MSR_VMX_MISC_VMWRITE_VMEXIT, -+ .features[FEAT_VMX_PINBASED_CTLS] = -+ VMX_PIN_BASED_EXT_INTR_MASK | VMX_PIN_BASED_NMI_EXITING | -+ VMX_PIN_BASED_VIRTUAL_NMIS | VMX_PIN_BASED_VMX_PREEMPTION_TIMER | -+ VMX_PIN_BASED_POSTED_INTR, -+ .features[FEAT_VMX_PROCBASED_CTLS] = -+ VMX_CPU_BASED_VIRTUAL_INTR_PENDING | -+ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | -+ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | -+ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | -+ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | -+ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | -+ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_VIRTUAL_NMI_PENDING | -+ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING | -+ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_TRAP_FLAG | -+ VMX_CPU_BASED_USE_MSR_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING | -+ VMX_CPU_BASED_PAUSE_EXITING | -+ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, -+ .features[FEAT_VMX_SECONDARY_CTLS] = -+ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | -+ VMX_SECONDARY_EXEC_ENABLE_EPT | VMX_SECONDARY_EXEC_DESC | -+ VMX_SECONDARY_EXEC_RDTSCP | -+ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | -+ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_WBINVD_EXITING | -+ VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | -+ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | -+ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | -+ VMX_SECONDARY_EXEC_RDRAND_EXITING | -+ VMX_SECONDARY_EXEC_ENABLE_INVPCID | -+ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | -+ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML | -+ VMX_SECONDARY_EXEC_XSAVES, -+ .features[FEAT_VMX_VMFUNC] = -+ MSR_VMX_VMFUNC_EPT_SWITCHING, -+ .xlevel = 0x80000008, -+ .model_id = "Intel Xeon Processor (SapphireRapids)", -+ .versions = (X86CPUVersionDefinition[]) { -+ { .version = 1 }, -+ { /* end of list */ }, -+ }, -+ }, - { - .name = "Denverton", - .level = 21, -@@ -5616,7 +5745,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - break; - } - case 0x1D: { -- /* AMX TILE */ -+ /* AMX TILE, for now hardcoded for Sapphire Rapids*/ - *eax = 0; - *ebx = 0; - *ecx = 0; -@@ -5637,7 +5766,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - break; - } - case 0x1E: { -- /* AMX TMUL */ -+ /* AMX TMUL, for now hardcoded for Sapphire Rapids */ - *eax = 0; - *ebx = 0; - *ecx = 0; -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 98f885ace..d156ccd17 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -858,10 +858,14 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_0_EDX_SERIALIZE (1U << 14) - /* TSX Suspend Load Address Tracking instruction */ - #define CPUID_7_0_EDX_TSX_LDTRK (1U << 16) -+/* AMX_BF16 instruction */ -+#define CPUID_7_0_EDX_AMX_BF16 (1U << 22) - /* AVX512_FP16 instruction */ - #define CPUID_7_0_EDX_AVX512_FP16 (1U << 23) - /* AMX tile (two-dimensional register) */ - #define CPUID_7_0_EDX_AMX_TILE (1U << 24) -+/* AMX_INT8 instruction */ -+#define CPUID_7_0_EDX_AMX_INT8 (1U << 25) - /* Speculation Control */ - #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) - /* Single Thread Indirect Branch Predictors */ --- -2.25.1 diff --git a/1080-target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch b/1080-target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch deleted file mode 100644 index de83c11..0000000 --- a/1080-target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch +++ /dev/null @@ -1,59 +0,0 @@ -From: Jiaxi Chen -Date: Fri, 3 Mar 2023 14:59:08 +0800 -Subject: [PATCH] target/i386: Add support for CMPCCXADD in CPUID enumeration - -commit a9ce107fd0f2017af84255a9cf6542fa3eb3e214 upstream. - -CMPccXADD is a new set of instructions in the latest Intel platform -Sierra Forest. This new instruction set includes a semaphore operation -that can compare and add the operands if condition is met, which can -improve database performance. - -The bit definition: -CPUID.(EAX=7,ECX=1):EAX[bit 7] - -Add CPUID definition for CMPCCXADD. - -Intel-SIG: commit a9ce107fd0f2 target/i386: Add support for CMPCCXADD in CPUID enumeration. -Add SPR/GNR/SRA new ISAs backporting - -Signed-off-by: Jiaxi Chen -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-Id: <20230303065913.1246327-2-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 30d19b794..6a8e07904 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -872,7 +872,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .type = CPUID_FEATURE_WORD, - .feat_names = { - NULL, NULL, NULL, NULL, -- "avx-vnni", "avx512-bf16", NULL, NULL, -+ "avx-vnni", "avx512-bf16", NULL, "cmpccxadd", - NULL, NULL, "fzrm", "fsrs", - "fsrc", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index d156ccd17..f8f5c1d85 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -883,6 +883,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EAX_AVX_VNNI (1U << 4) - /* AVX512 BFloat16 Instruction */ - #define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) -+/* CMPCCXADD Instructions */ -+#define CPUID_7_1_EAX_CMPCCXADD (1U << 7) - /* Fast Zero REP MOVS */ - #define CPUID_7_1_EAX_FZRM (1U << 10) - /* Fast Short REP STOS */ --- -2.25.1 diff --git a/1081-target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch b/1081-target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch deleted file mode 100644 index b4d6ebc..0000000 --- a/1081-target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch +++ /dev/null @@ -1,60 +0,0 @@ -From: Jiaxi Chen -Date: Fri, 3 Mar 2023 14:59:09 +0800 -Subject: [PATCH] target/i386: Add support for AMX-FP16 in CPUID enumeration - -commit 99ed8445ea27742a4df40f51a3a5fbd6f8e76fa5 upstream. - -Latest Intel platform Granite Rapids has introduced a new instruction - -AMX-FP16, which performs dot-products of two FP16 tiles and accumulates -the results into a packed single precision tile. AMX-FP16 adds FP16 -capability and allows a FP16 GPU trained model to run faster without -loss of accuracy or added SW overhead. - -The bit definition: -CPUID.(EAX=7,ECX=1):EAX[bit 21] - -Add CPUID definition for AMX-FP16. - -Intel-SIG: commit 99ed8445ea27 target/i386: Add support for AMX-FP16 in CPUID enumeration. -Add SPR/GNR/SRA new ISAs backporting - -Signed-off-by: Jiaxi Chen -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-Id: <20230303065913.1246327-3-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 6a8e07904..074dcb573 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -876,7 +876,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - NULL, NULL, "fzrm", "fsrs", - "fsrc", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ NULL, "amx-fp16", NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - }, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index f8f5c1d85..62f61cefb 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -891,6 +891,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EAX_FSRS (1U << 11) - /* Fast Short REP CMPS/SCAS */ - #define CPUID_7_1_EAX_FSRC (1U << 12) -+/* Support Tile Computational Operations on FP16 Numbers */ -+#define CPUID_7_1_EAX_AMX_FP16 (1U << 21) - - /* XFD Extend Feature Disabled */ - #define CPUID_D_1_EAX_XFD (1U << 4) --- -2.25.1 diff --git a/1082-target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch b/1082-target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch deleted file mode 100644 index 1234f5d..0000000 --- a/1082-target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Jiaxi Chen -Date: Fri, 3 Mar 2023 14:59:10 +0800 -Subject: [PATCH] target/i386: Add support for AVX-IFMA in CPUID enumeration - -commit a957a88416ecbec51e147cba9fe89b93f6646b3b upstream. - -AVX-IFMA is a new instruction in the latest Intel platform Sierra -Forest. This instruction packed multiplies unsigned 52-bit integers and -adds the low/high 52-bit products to Qword Accumulators. - -The bit definition: -CPUID.(EAX=7,ECX=1):EAX[bit 23] - -Add CPUID definition for AVX-IFMA. - -Intel-SIG: commit a957a88416ec target/i386: Add support for AVX-IFMA in CPUID enumeration. -Add SPR/GNR/SRA new ISAs backporting - -Signed-off-by: Jiaxi Chen -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-Id: <20230303065913.1246327-4-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 074dcb573..556810da8 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -876,7 +876,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - NULL, NULL, "fzrm", "fsrs", - "fsrc", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -- NULL, "amx-fp16", NULL, NULL, -+ NULL, "amx-fp16", NULL, "avx-ifma", - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - }, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 62f61cefb..4f5e1f35d 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -893,6 +893,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EAX_FSRC (1U << 12) - /* Support Tile Computational Operations on FP16 Numbers */ - #define CPUID_7_1_EAX_AMX_FP16 (1U << 21) -+/* Support for VPMADD52[H,L]UQ */ -+#define CPUID_7_1_EAX_AVX_IFMA (1U << 23) - - /* XFD Extend Feature Disabled */ - #define CPUID_D_1_EAX_XFD (1U << 4) --- -2.25.1 diff --git a/1083-target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch b/1083-target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch deleted file mode 100644 index 066813d..0000000 --- a/1083-target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch +++ /dev/null @@ -1,108 +0,0 @@ -From: Jiaxi Chen -Date: Fri, 3 Mar 2023 14:59:11 +0800 -Subject: [PATCH] target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration - -commit eaaa197d5b112ea2758b54df58881a2626de3af5 upstream. - -AVX-VNNI-INT8 is a new set of instructions in the latest Intel platform -Sierra Forest, aims for the platform to have superior AI capabilities. -This instruction multiplies the individual bytes of two unsigned or -unsigned source operands, then adds and accumulates the results into the -destination dword element size operand. - -The bit definition: -CPUID.(EAX=7,ECX=1):EDX[bit 4] - -AVX-VNNI-INT8 is on a new feature bits leaf. Add a CPUID feature word -FEAT_7_1_EDX for this leaf. - -Add CPUID definition for AVX-VNNI-INT8. - -Intel-SIG: commit eaaa197d5b11 target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration. -Add SPR/GNR/SRA new ISAs backporting - -Signed-off-by: Jiaxi Chen -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-Id: <20230303065913.1246327-5-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 22 +++++++++++++++++++++- - target/i386/cpu.h | 4 ++++ - 2 files changed, 25 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 556810da8..cd7ee2473 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -664,6 +664,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, - #define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM - #define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \ - CPUID_7_1_EAX_FSRC) -+#define TCG_7_1_EDX_FEATURES 0 - #define TCG_APM_FEATURES 0 - #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT - #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1) -@@ -887,6 +888,25 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - }, - .tcg_features = TCG_7_1_EAX_FEATURES, - }, -+ [FEAT_7_1_EDX] = { -+ .type = CPUID_FEATURE_WORD, -+ .feat_names = { -+ NULL, NULL, NULL, NULL, -+ "avx-vnni-int8", NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ }, -+ .cpuid = { -+ .eax = 7, -+ .needs_ecx = true, .ecx = 1, -+ .reg = R_EDX, -+ }, -+ .tcg_features = TCG_7_1_EDX_FEATURES, -+ }, - [FEAT_8000_0007_EDX] = { - .type = CPUID_FEATURE_WORD, - .feat_names = { -@@ -5525,9 +5545,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - } - } else if (count == 1) { - *eax = env->features[FEAT_7_1_EAX]; -+ *edx = env->features[FEAT_7_1_EDX]; - *ebx = 0; - *ecx = 0; -- *edx = 0; - } else { - *eax = 0; - *ebx = 0; -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 4f5e1f35d..79e456d47 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -602,6 +602,7 @@ typedef enum FeatureWord { - FEAT_SGX_12_0_EAX, /* CPUID[EAX=0x12,ECX=0].EAX (SGX) */ - FEAT_SGX_12_0_EBX, /* CPUID[EAX=0x12,ECX=0].EBX (SGX MISCSELECT[31:0]) */ - FEAT_SGX_12_1_EAX, /* CPUID[EAX=0x12,ECX=1].EAX (SGX ATTRIBUTES[31:0]) */ -+ FEAT_7_1_EDX, /* CPUID[EAX=7,ECX=1].EDX */ - FEATURE_WORDS, - } FeatureWord; - -@@ -896,6 +897,9 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - /* Support for VPMADD52[H,L]UQ */ - #define CPUID_7_1_EAX_AVX_IFMA (1U << 23) - -+/* Support for VPDPB[SU,UU,SS]D[,S] */ -+#define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4) -+ - /* XFD Extend Feature Disabled */ - #define CPUID_D_1_EAX_XFD (1U << 4) - --- -2.25.1 diff --git a/1084-target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch b/1084-target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch deleted file mode 100644 index 3672e8b..0000000 --- a/1084-target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch +++ /dev/null @@ -1,59 +0,0 @@ -From: Jiaxi Chen -Date: Fri, 3 Mar 2023 14:59:12 +0800 -Subject: [PATCH] target/i386: Add support for AVX-NE-CONVERT in CPUID enumeration - -commit ecd2e6ca037d7bf3673c5478590d686d5cd6135a upstream. - -AVX-NE-CONVERT is a new set of instructions which can convert low -precision floating point like BF16/FP16 to high precision floating point -FP32, as well as convert FP32 elements to BF16. This instruction allows -the platform to have improved AI capabilities and better compatibility. - -The bit definition: -CPUID.(EAX=7,ECX=1):EDX[bit 5] - -Add CPUID definition for AVX-NE-CONVERT. - -Intel-SIG: commit ecd2e6ca037d target/i386: Add support for AVX-NE-CONVERT in CPUID enumeration. -Add SPR/GNR/SRA new ISAs backporting - -Signed-off-by: Jiaxi Chen -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-Id: <20230303065913.1246327-6-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index cd7ee2473..eb5e0b0b7 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -892,7 +892,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .type = CPUID_FEATURE_WORD, - .feat_names = { - NULL, NULL, NULL, NULL, -- "avx-vnni-int8", NULL, NULL, NULL, -+ "avx-vnni-int8", "avx-ne-convert", NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 79e456d47..4757479ac 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -899,6 +899,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - - /* Support for VPDPB[SU,UU,SS]D[,S] */ - #define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4) -+/* AVX NE CONVERT Instructions */ -+#define CPUID_7_1_EDX_AVX_NE_CONVERT (1U << 5) - - /* XFD Extend Feature Disabled */ - #define CPUID_D_1_EAX_XFD (1U << 4) --- -2.25.1 diff --git a/1085-target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch b/1085-target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch deleted file mode 100644 index 38b6f03..0000000 --- a/1085-target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Jiaxi Chen -Date: Fri, 3 Mar 2023 14:59:13 +0800 -Subject: [PATCH] target/i386: Add support for PREFETCHIT0/1 in CPUID enumeration - -commit d1a1111514333e46a98b136235f71eef90d610fa upstream. - -Latest Intel platform Granite Rapids has introduced a new instruction - -PREFETCHIT0/1, which moves code to memory (cache) closer to the -processor depending on specific hints. - -The bit definition: -CPUID.(EAX=7,ECX=1):EDX[bit 14] - -Add CPUID definition for PREFETCHIT0/1. - -Intel-SIG: commit d1a111151433 target/i386: Add support for PREFETCHIT0/1 in CPUID enumeration. -Add SPR/GNR/SRA new ISAs backporting - -Signed-off-by: Jiaxi Chen -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-Id: <20230303065913.1246327-7-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index eb5e0b0b7..7738d29e8 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -894,7 +894,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - NULL, NULL, NULL, NULL, - "avx-vnni-int8", "avx-ne-convert", NULL, NULL, - NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ NULL, NULL, "prefetchiti", NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 4757479ac..435f458cf 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -901,6 +901,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4) - /* AVX NE CONVERT Instructions */ - #define CPUID_7_1_EDX_AVX_NE_CONVERT (1U << 5) -+/* PREFETCHIT0/1 Instructions */ -+#define CPUID_7_1_EDX_PREFETCHITI (1U << 14) - - /* XFD Extend Feature Disabled */ - #define CPUID_D_1_EAX_XFD (1U << 4) --- -2.25.1 diff --git a/1086-target-i386-Adjust-feature-level-according-to-FEAT_7.patch b/1086-target-i386-Adjust-feature-level-according-to-FEAT_7.patch deleted file mode 100644 index d4990f0..0000000 --- a/1086-target-i386-Adjust-feature-level-according-to-FEAT_7.patch +++ /dev/null @@ -1,43 +0,0 @@ -From: Tao Su -Date: Thu, 6 Jul 2023 13:49:44 +0800 -Subject: [PATCH] target/i386: Adjust feature level according to FEAT_7_1_EDX - -commit 8731336e90dea3dd04948127e775c9f087f97a4c upstream. - -If FEAT_7_1_EAX is 0 and FEAT_7_1_EDX is non-zero, as is the case -with a Granite Rapids host and -'-cpu host,-avx-vnni,-avx512-bf16,-fzrm,-fsrs,-fsrc,-amx-fp16', we can't -get CPUID_7_1 leaf even though CPUID_7_1_EDX has non-zero value. - -Update cpuid_level_func7 according to CPUID_7_1_EDX, otherwise -guest may report wrong maximum number sub-leaves in leaf 07H. - -Fixes: eaaa197d5b11 ("target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration") -Intel-SIG: commit 8731336e90de target/i386: Adjust feature level according to FEAT_7_1_EDX. -Add SPR/GNR/SRA new ISAs backporting - -Cc: qemu-stable@nongnu.org -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-ID: <20230706054949.66556-2-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 7738d29e8..32937b0d0 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -6369,6 +6369,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) - x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX); - x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX); - x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EAX); -+ x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EDX); - x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX); - x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX); - x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX); --- -2.25.1 diff --git a/1087-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch b/1087-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch deleted file mode 100644 index 69cacca..0000000 --- a/1087-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch +++ /dev/null @@ -1,40 +0,0 @@ -From: Tao Su -Date: Thu, 6 Jul 2023 13:49:47 +0800 -Subject: [PATCH] target/i386: Add new bit definitions of MSR_IA32_ARCH_CAPABILITIES - -commit 6c43ec3b206956a8a3008accafe9eb2dfd885190 upstream. - -Currently, bit 13, 14, 15 and 24 of MSR_IA32_ARCH_CAPABILITIES are -disclosed for fixing security issues, so add those bit definitions. - -Intel-SIG: commit 6c43ec3b2069 target/i386: Add new bit definitions of MSR_IA32_ARCH_CAPABILITIES. -Add SPR/GNR/SRA new ISAs backporting - -Signed-off-by: Tao Su -Reviewed-by: Igor Mammedov -Message-ID: <20230706054949.66556-5-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.h | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 435f458cf..c65133ab6 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -977,7 +977,11 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define MSR_ARCH_CAP_PSCHANGE_MC_NO (1U << 6) - #define MSR_ARCH_CAP_TSX_CTRL_MSR (1U << 7) - #define MSR_ARCH_CAP_TAA_NO (1U << 8) -+#define MSR_ARCH_CAP_SBDR_SSDP_NO (1U << 13) -+#define MSR_ARCH_CAP_FBSDP_NO (1U << 14) -+#define MSR_ARCH_CAP_PSDP_NO (1U << 15) - #define MSR_ARCH_CAP_FB_CLEAR (1U << 17) -+#define MSR_ARCH_CAP_PBRSB_NO (1U << 24) - - #define MSR_CORE_CAP_SPLIT_LOCK_DETECT (1U << 5) - --- -2.25.1 diff --git a/1088-target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch b/1088-target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch deleted file mode 100644 index 0fcfd8e..0000000 --- a/1088-target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch +++ /dev/null @@ -1,110 +0,0 @@ -From: Tao Su -Date: Thu, 6 Jul 2023 13:49:45 +0800 -Subject: [PATCH] target/i386: Add support for MCDT_NO in CPUID enumeration - -commit 9dd8b71091f47bac395f543779269c14d8d93c60 upstream. - -CPUID.(EAX=7,ECX=2):EDX[bit 5] enumerates MCDT_NO. Processors enumerate -this bit as 1 do not exhibit MXCSR Configuration Dependent Timing (MCDT) -behavior and do not need to be mitigated to avoid data-dependent behavior -for certain instructions. - -Since MCDT_NO is in a new sub-leaf, add a new CPUID feature word -FEAT_7_2_EDX. Also update cpuid_level_func7 by FEAT_7_2_EDX. - -Intel-SIG: commit 9dd8b71091f4 target/i386: Add support for MCDT_NO in CPUID enumeration. -Add SPR/GNR/SRA new ISAs backporting - -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-ID: <20230706054949.66556-3-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 26 ++++++++++++++++++++++++++ - target/i386/cpu.h | 4 ++++ - 2 files changed, 30 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 32937b0d0..0547dda2e 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -665,6 +665,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, - #define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \ - CPUID_7_1_EAX_FSRC) - #define TCG_7_1_EDX_FEATURES 0 -+#define TCG_7_2_EDX_FEATURES 0 - #define TCG_APM_FEATURES 0 - #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT - #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1) -@@ -907,6 +908,25 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - }, - .tcg_features = TCG_7_1_EDX_FEATURES, - }, -+ [FEAT_7_2_EDX] = { -+ .type = CPUID_FEATURE_WORD, -+ .feat_names = { -+ NULL, NULL, NULL, NULL, -+ NULL, "mcdt-no", NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ }, -+ .cpuid = { -+ .eax = 7, -+ .needs_ecx = true, .ecx = 2, -+ .reg = R_EDX, -+ }, -+ .tcg_features = TCG_7_2_EDX_FEATURES, -+ }, - [FEAT_8000_0007_EDX] = { - .type = CPUID_FEATURE_WORD, - .feat_names = { -@@ -5548,6 +5568,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - *edx = env->features[FEAT_7_1_EDX]; - *ebx = 0; - *ecx = 0; -+ } else if (count == 2) { -+ *edx = env->features[FEAT_7_2_EDX]; -+ *eax = 0; -+ *ebx = 0; -+ *ecx = 0; - } else { - *eax = 0; - *ebx = 0; -@@ -6370,6 +6395,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) - x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX); - x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EAX); - x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EDX); -+ x86_cpu_adjust_feat_level(cpu, FEAT_7_2_EDX); - x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX); - x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX); - x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX); -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index c65133ab6..26572b846 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -603,6 +603,7 @@ typedef enum FeatureWord { - FEAT_SGX_12_0_EBX, /* CPUID[EAX=0x12,ECX=0].EBX (SGX MISCSELECT[31:0]) */ - FEAT_SGX_12_1_EAX, /* CPUID[EAX=0x12,ECX=1].EAX (SGX ATTRIBUTES[31:0]) */ - FEAT_7_1_EDX, /* CPUID[EAX=7,ECX=1].EDX */ -+ FEAT_7_2_EDX, /* CPUID[EAX=7,ECX=2].EDX */ - FEATURE_WORDS, - } FeatureWord; - -@@ -904,6 +905,9 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - /* PREFETCHIT0/1 Instructions */ - #define CPUID_7_1_EDX_PREFETCHITI (1U << 14) - -+/* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */ -+#define CPUID_7_2_EDX_MCDT_NO (1U << 5) -+ - /* XFD Extend Feature Disabled */ - #define CPUID_D_1_EAX_XFD (1U << 4) - --- -2.25.1 diff --git a/1089-target-i386-Add-new-CPU-model-GraniteRapids.patch b/1089-target-i386-Add-new-CPU-model-GraniteRapids.patch deleted file mode 100644 index 938ced8..0000000 --- a/1089-target-i386-Add-new-CPU-model-GraniteRapids.patch +++ /dev/null @@ -1,181 +0,0 @@ -From: Tao Su -Date: Thu, 6 Jul 2023 13:49:49 +0800 -Subject: [PATCH] target/i386: Add new CPU model GraniteRapids - -commit 6d5e9694ef374159072984c0958c3eaab6dd1d52 upstream. - -The GraniteRapids CPU model mainly adds the following new features -based on SapphireRapids: -- PREFETCHITI CPUID.(EAX=7,ECX=1):EDX[bit 14] -- AMX-FP16 CPUID.(EAX=7,ECX=1):EAX[bit 21] - -And adds the following security fix for corresponding vulnerabilities: -- MCDT_NO CPUID.(EAX=7,ECX=2):EDX[bit 5] -- SBDR_SSDP_NO MSR_IA32_ARCH_CAPABILITIES[bit 13] -- FBSDP_NO MSR_IA32_ARCH_CAPABILITIES[bit 14] -- PSDP_NO MSR_IA32_ARCH_CAPABILITIES[bit 15] -- PBRSB_NO MSR_IA32_ARCH_CAPABILITIES[bit 24] - -Intel-SIG: commit 6d5e9694ef37 target/i386: Add new CPU model GraniteRapids. -Add SPR/GNR/SRA new ISAs backporting - -Signed-off-by: Tao Su -Tested-by: Xuelian Guo -Reviewed-by: Xiaoyao Li -Message-ID: <20230706054949.66556-7-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 136 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 0547dda2e..b7cdca7cc 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -3966,6 +3966,142 @@ static const X86CPUDefinition builtin_x86_defs[] = { - { /* end of list */ }, - }, - }, -+ { -+ .name = "GraniteRapids", -+ .level = 0x20, -+ .vendor = CPUID_VENDOR_INTEL, -+ .family = 6, -+ .model = 173, -+ .stepping = 0, -+ /* -+ * please keep the ascending order so that we can have a clear view of -+ * bit position of each feature. -+ */ -+ .features[FEAT_1_EDX] = -+ CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | -+ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | -+ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | -+ CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR | -+ CPUID_SSE | CPUID_SSE2, -+ .features[FEAT_1_ECX] = -+ CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 | -+ CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | CPUID_EXT_SSE41 | -+ CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE | -+ CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES | -+ CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND, -+ .features[FEAT_8000_0001_EDX] = -+ CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB | -+ CPUID_EXT2_RDTSCP | CPUID_EXT2_LM, -+ .features[FEAT_8000_0001_ECX] = -+ CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH, -+ .features[FEAT_8000_0008_EBX] = -+ CPUID_8000_0008_EBX_WBNOINVD, -+ .features[FEAT_7_0_EBX] = -+ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_HLE | -+ CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | -+ CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RTM | -+ CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ | -+ CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | -+ CPUID_7_0_EBX_AVX512IFMA | CPUID_7_0_EBX_CLFLUSHOPT | -+ CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_AVX512CD | CPUID_7_0_EBX_SHA_NI | -+ CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL, -+ .features[FEAT_7_0_ECX] = -+ CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | -+ CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI | -+ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ | -+ CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG | -+ CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57 | -+ CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT, -+ .features[FEAT_7_0_EDX] = -+ CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_SERIALIZE | -+ CPUID_7_0_EDX_TSX_LDTRK | CPUID_7_0_EDX_AMX_BF16 | -+ CPUID_7_0_EDX_AVX512_FP16 | CPUID_7_0_EDX_AMX_TILE | -+ CPUID_7_0_EDX_AMX_INT8 | CPUID_7_0_EDX_SPEC_CTRL | -+ CPUID_7_0_EDX_ARCH_CAPABILITIES | CPUID_7_0_EDX_SPEC_CTRL_SSBD, -+ .features[FEAT_ARCH_CAPABILITIES] = -+ MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL | -+ MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO | -+ MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_TAA_NO | -+ MSR_ARCH_CAP_SBDR_SSDP_NO | MSR_ARCH_CAP_FBSDP_NO | -+ MSR_ARCH_CAP_PSDP_NO | MSR_ARCH_CAP_PBRSB_NO, -+ .features[FEAT_XSAVE] = -+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | -+ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES | CPUID_D_1_EAX_XFD, -+ .features[FEAT_6_EAX] = -+ CPUID_6_EAX_ARAT, -+ .features[FEAT_7_1_EAX] = -+ CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_AVX512_BF16 | -+ CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_FSRC | -+ CPUID_7_1_EAX_AMX_FP16, -+ .features[FEAT_7_1_EDX] = -+ CPUID_7_1_EDX_PREFETCHITI, -+ .features[FEAT_7_2_EDX] = -+ CPUID_7_2_EDX_MCDT_NO, -+ .features[FEAT_VMX_BASIC] = -+ MSR_VMX_BASIC_INS_OUTS | MSR_VMX_BASIC_TRUE_CTLS, -+ .features[FEAT_VMX_ENTRY_CTLS] = -+ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_IA32E_MODE | -+ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | -+ VMX_VM_ENTRY_LOAD_IA32_PAT | VMX_VM_ENTRY_LOAD_IA32_EFER, -+ .features[FEAT_VMX_EPT_VPID_CAPS] = -+ MSR_VMX_EPT_EXECONLY | -+ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_PAGE_WALK_LENGTH_5 | -+ MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB | -+ MSR_VMX_EPT_INVEPT | MSR_VMX_EPT_AD_BITS | -+ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | -+ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | -+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | -+ MSR_VMX_EPT_INVVPID_ALL_CONTEXT | -+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, -+ .features[FEAT_VMX_EXIT_CTLS] = -+ VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | -+ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | -+ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_IA32_PAT | -+ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | -+ VMX_VM_EXIT_LOAD_IA32_EFER | VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, -+ .features[FEAT_VMX_MISC] = -+ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_ACTIVITY_HLT | -+ MSR_VMX_MISC_VMWRITE_VMEXIT, -+ .features[FEAT_VMX_PINBASED_CTLS] = -+ VMX_PIN_BASED_EXT_INTR_MASK | VMX_PIN_BASED_NMI_EXITING | -+ VMX_PIN_BASED_VIRTUAL_NMIS | VMX_PIN_BASED_VMX_PREEMPTION_TIMER | -+ VMX_PIN_BASED_POSTED_INTR, -+ .features[FEAT_VMX_PROCBASED_CTLS] = -+ VMX_CPU_BASED_VIRTUAL_INTR_PENDING | -+ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | -+ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | -+ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | -+ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | -+ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | -+ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_VIRTUAL_NMI_PENDING | -+ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING | -+ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_TRAP_FLAG | -+ VMX_CPU_BASED_USE_MSR_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING | -+ VMX_CPU_BASED_PAUSE_EXITING | -+ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, -+ .features[FEAT_VMX_SECONDARY_CTLS] = -+ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | -+ VMX_SECONDARY_EXEC_ENABLE_EPT | VMX_SECONDARY_EXEC_DESC | -+ VMX_SECONDARY_EXEC_RDTSCP | -+ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | -+ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_WBINVD_EXITING | -+ VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | -+ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | -+ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | -+ VMX_SECONDARY_EXEC_RDRAND_EXITING | -+ VMX_SECONDARY_EXEC_ENABLE_INVPCID | -+ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | -+ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML | -+ VMX_SECONDARY_EXEC_XSAVES, -+ .features[FEAT_VMX_VMFUNC] = -+ MSR_VMX_VMFUNC_EPT_SWITCHING, -+ .xlevel = 0x80000008, -+ .model_id = "Intel Xeon Processor (GraniteRapids)", -+ .versions = (X86CPUVersionDefinition[]) { -+ { .version = 1 }, -+ { /* end of list */ }, -+ }, -+ }, - { - .name = "KnightsMill", - .level = 0xd, --- -2.25.1 diff --git a/1090-target-i386-Add-support-for-AMX-COMPLEX-in-CPUID-enu.patch b/1090-target-i386-Add-support-for-AMX-COMPLEX-in-CPUID-enu.patch deleted file mode 100644 index 5d175da..0000000 --- a/1090-target-i386-Add-support-for-AMX-COMPLEX-in-CPUID-enu.patch +++ /dev/null @@ -1,57 +0,0 @@ -From: Tao Su -Date: Wed, 30 Aug 2023 15:43:24 +0800 -Subject: [PATCH] target/i386: Add support for AMX-COMPLEX in CPUID enumeration - -commit 3e76bafb28c8292be5c4a32cab873b3a82cbcc87 upstream. - -Latest Intel platform GraniteRapids-D introduces AMX-COMPLEX, which adds -two instructions to perform matrix multiplication of two tiles containing -complex elements and accumulate the results into a packed single precision -tile. - -AMX-COMPLEX is enumerated via CPUID.(EAX=7,ECX=1):EDX[bit 8]. Add the CPUID -definition for AMX-COMPLEX, AMX-COMPLEX will be enabled automatically when -using '-cpu host' and KVM advertises AMX-COMPLEX to userspace. - -Intel-SIG: commit 3e76bafb28c8 target/i386: Add support for AMX-COMPLEX in CPUID enumeration. -Add SPR/GNR/SRA new ISAs backporting - -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-ID: <20230830074324.84059-1-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index b7cdca7cc..4a33baade 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -894,7 +894,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .feat_names = { - NULL, NULL, NULL, NULL, - "avx-vnni-int8", "avx-ne-convert", NULL, NULL, -- NULL, NULL, NULL, NULL, -+ "amx-complex", NULL, NULL, NULL, - NULL, NULL, "prefetchiti", NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 26572b846..e84cb8265 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -902,6 +902,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4) - /* AVX NE CONVERT Instructions */ - #define CPUID_7_1_EDX_AVX_NE_CONVERT (1U << 5) -+/* AMX COMPLEX Instructions */ -+#define CPUID_7_1_EDX_AMX_COMPLEX (1U << 8) - /* PREFETCHIT0/1 Instructions */ - #define CPUID_7_1_EDX_PREFETCHITI (1U << 14) - --- -2.25.1 diff --git a/1091-target-i386-Add-new-CPU-model-SierraForest.patch b/1091-target-i386-Add-new-CPU-model-SierraForest.patch deleted file mode 100644 index 8ab9a09..0000000 --- a/1091-target-i386-Add-new-CPU-model-SierraForest.patch +++ /dev/null @@ -1,207 +0,0 @@ -From: Tao Su -Date: Wed, 20 Mar 2024 10:10:44 +0800 -Subject: [PATCH] target/i386: Add new CPU model SierraForest - -commit 6e82d3b6220777667968a04c87e1667f164ebe88 upstream. - -According to table 1-2 in Intel Architecture Instruction Set Extensions and -Future Features (rev 051) [1], SierraForest has the following new features -which have already been virtualized: - -- CMPCCXADD CPUID.(EAX=7,ECX=1):EAX[bit 7] -- AVX-IFMA CPUID.(EAX=7,ECX=1):EAX[bit 23] -- AVX-VNNI-INT8 CPUID.(EAX=7,ECX=1):EDX[bit 4] -- AVX-NE-CONVERT CPUID.(EAX=7,ECX=1):EDX[bit 5] - -Add above features to new CPU model SierraForest. Comparing with GraniteRapids -CPU model, SierraForest bare-metal removes the following features: - -- HLE CPUID.(EAX=7,ECX=0):EBX[bit 4] -- RTM CPUID.(EAX=7,ECX=0):EBX[bit 11] -- AVX512F CPUID.(EAX=7,ECX=0):EBX[bit 16] -- AVX512DQ CPUID.(EAX=7,ECX=0):EBX[bit 17] -- AVX512_IFMA CPUID.(EAX=7,ECX=0):EBX[bit 21] -- AVX512CD CPUID.(EAX=7,ECX=0):EBX[bit 28] -- AVX512BW CPUID.(EAX=7,ECX=0):EBX[bit 30] -- AVX512VL CPUID.(EAX=7,ECX=0):EBX[bit 31] -- AVX512_VBMI CPUID.(EAX=7,ECX=0):ECX[bit 1] -- AVX512_VBMI2 CPUID.(EAX=7,ECX=0):ECX[bit 6] -- AVX512_VNNI CPUID.(EAX=7,ECX=0):ECX[bit 11] -- AVX512_BITALG CPUID.(EAX=7,ECX=0):ECX[bit 12] -- AVX512_VPOPCNTDQ CPUID.(EAX=7,ECX=0):ECX[bit 14] -- LA57 CPUID.(EAX=7,ECX=0):ECX[bit 16] -- TSXLDTRK CPUID.(EAX=7,ECX=0):EDX[bit 16] -- AMX-BF16 CPUID.(EAX=7,ECX=0):EDX[bit 22] -- AVX512_FP16 CPUID.(EAX=7,ECX=0):EDX[bit 23] -- AMX-TILE CPUID.(EAX=7,ECX=0):EDX[bit 24] -- AMX-INT8 CPUID.(EAX=7,ECX=0):EDX[bit 25] -- AVX512_BF16 CPUID.(EAX=7,ECX=1):EAX[bit 5] -- fast zero-length MOVSB CPUID.(EAX=7,ECX=1):EAX[bit 10] -- fast short CMPSB, SCASB CPUID.(EAX=7,ECX=1):EAX[bit 12] -- AMX-FP16 CPUID.(EAX=7,ECX=1):EAX[bit 21] -- PREFETCHI CPUID.(EAX=7,ECX=1):EDX[bit 14] -- XFD CPUID.(EAX=0xD,ECX=1):EAX[bit 4] -- EPT_PAGE_WALK_LENGTH_5 VMX_EPT_VPID_CAP(0x48c)[bit 7] - -Add all features of GraniteRapids CPU model except above features to -SierraForest CPU model. - -SierraForest doesn’t support TSX and RTM but supports TAA_NO. When RTM is -not enabled in host, KVM will not report TAA_NO. So, just don't include -TAA_NO in SierraForest CPU model. - -[1] https://cdrdv2.intel.com/v1/dl/getContent/671368 - -Intel-SIG: commit 6e82d3b62207 target/i386: Add new CPU model SierraForest. -Add SPR/GNR/SRA new ISAs backporting - -Reviewed-by: Zhao Liu -Reviewed-by: Xiaoyao Li -Signed-off-by: Tao Su -Message-ID: <20240320021044.508263-1-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 126 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 4a33baade..00157dae9 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -3715,6 +3715,132 @@ static const X86CPUDefinition builtin_x86_defs[] = { - { /* end of list */ }, - }, - }, -+ { -+ .name = "SierraForest", -+ .level = 0x23, -+ .vendor = CPUID_VENDOR_INTEL, -+ .family = 6, -+ .model = 175, -+ .stepping = 0, -+ /* -+ * please keep the ascending order so that we can have a clear view of -+ * bit position of each feature. -+ */ -+ .features[FEAT_1_EDX] = -+ CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | -+ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | -+ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | -+ CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR | -+ CPUID_SSE | CPUID_SSE2, -+ .features[FEAT_1_ECX] = -+ CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 | -+ CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | CPUID_EXT_SSE41 | -+ CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE | -+ CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES | -+ CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND, -+ .features[FEAT_8000_0001_EDX] = -+ CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB | -+ CPUID_EXT2_RDTSCP | CPUID_EXT2_LM, -+ .features[FEAT_8000_0001_ECX] = -+ CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH, -+ .features[FEAT_8000_0008_EBX] = -+ CPUID_8000_0008_EBX_WBNOINVD, -+ .features[FEAT_7_0_EBX] = -+ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 | -+ CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | -+ CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | -+ CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT | CPUID_7_0_EBX_CLWB | -+ CPUID_7_0_EBX_SHA_NI, -+ .features[FEAT_7_0_ECX] = -+ CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_GFNI | -+ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ | -+ CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT, -+ .features[FEAT_7_0_EDX] = -+ CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_SERIALIZE | -+ CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_ARCH_CAPABILITIES | -+ CPUID_7_0_EDX_SPEC_CTRL_SSBD, -+ .features[FEAT_ARCH_CAPABILITIES] = -+ MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL | -+ MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO | -+ MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_SBDR_SSDP_NO | -+ MSR_ARCH_CAP_FBSDP_NO | MSR_ARCH_CAP_PSDP_NO | -+ MSR_ARCH_CAP_PBRSB_NO, -+ .features[FEAT_XSAVE] = -+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | -+ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES, -+ .features[FEAT_6_EAX] = -+ CPUID_6_EAX_ARAT, -+ .features[FEAT_7_1_EAX] = -+ CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_CMPCCXADD | -+ CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_AVX_IFMA, -+ .features[FEAT_7_1_EDX] = -+ CPUID_7_1_EDX_AVX_VNNI_INT8 | CPUID_7_1_EDX_AVX_NE_CONVERT, -+ .features[FEAT_7_2_EDX] = -+ CPUID_7_2_EDX_MCDT_NO, -+ .features[FEAT_VMX_BASIC] = -+ MSR_VMX_BASIC_INS_OUTS | MSR_VMX_BASIC_TRUE_CTLS, -+ .features[FEAT_VMX_ENTRY_CTLS] = -+ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_IA32E_MODE | -+ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | -+ VMX_VM_ENTRY_LOAD_IA32_PAT | VMX_VM_ENTRY_LOAD_IA32_EFER, -+ .features[FEAT_VMX_EPT_VPID_CAPS] = -+ MSR_VMX_EPT_EXECONLY | MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | -+ MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB | -+ MSR_VMX_EPT_INVEPT | MSR_VMX_EPT_AD_BITS | -+ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | -+ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | -+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | -+ MSR_VMX_EPT_INVVPID_ALL_CONTEXT | -+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, -+ .features[FEAT_VMX_EXIT_CTLS] = -+ VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | -+ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | -+ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_IA32_PAT | -+ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | -+ VMX_VM_EXIT_LOAD_IA32_EFER | VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, -+ .features[FEAT_VMX_MISC] = -+ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_ACTIVITY_HLT | -+ MSR_VMX_MISC_VMWRITE_VMEXIT, -+ .features[FEAT_VMX_PINBASED_CTLS] = -+ VMX_PIN_BASED_EXT_INTR_MASK | VMX_PIN_BASED_NMI_EXITING | -+ VMX_PIN_BASED_VIRTUAL_NMIS | VMX_PIN_BASED_VMX_PREEMPTION_TIMER | -+ VMX_PIN_BASED_POSTED_INTR, -+ .features[FEAT_VMX_PROCBASED_CTLS] = -+ VMX_CPU_BASED_VIRTUAL_INTR_PENDING | -+ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | -+ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | -+ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | -+ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | -+ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | -+ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_VIRTUAL_NMI_PENDING | -+ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING | -+ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_TRAP_FLAG | -+ VMX_CPU_BASED_USE_MSR_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING | -+ VMX_CPU_BASED_PAUSE_EXITING | -+ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, -+ .features[FEAT_VMX_SECONDARY_CTLS] = -+ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | -+ VMX_SECONDARY_EXEC_ENABLE_EPT | VMX_SECONDARY_EXEC_DESC | -+ VMX_SECONDARY_EXEC_RDTSCP | -+ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | -+ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_WBINVD_EXITING | -+ VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | -+ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | -+ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | -+ VMX_SECONDARY_EXEC_RDRAND_EXITING | -+ VMX_SECONDARY_EXEC_ENABLE_INVPCID | -+ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | -+ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML | -+ VMX_SECONDARY_EXEC_XSAVES, -+ .features[FEAT_VMX_VMFUNC] = -+ MSR_VMX_VMFUNC_EPT_SWITCHING, -+ .xlevel = 0x80000008, -+ .model_id = "Intel Xeon Processor (SierraForest)", -+ .versions = (X86CPUVersionDefinition[]) { -+ { .version = 1 }, -+ { /* end of list */ }, -+ }, -+ }, - { - .name = "Denverton", - .level = 21, --- -2.25.1 diff --git a/1092-target-i386-Export-RFDS-bit-to-guests.patch b/1092-target-i386-Export-RFDS-bit-to-guests.patch deleted file mode 100644 index 87d9465..0000000 --- a/1092-target-i386-Export-RFDS-bit-to-guests.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Pawan Gupta -Date: Wed, 13 Mar 2024 07:53:23 -0700 -Subject: [PATCH] target/i386: Export RFDS bit to guests - -commit 41bdd9812863c150284a9339a048ed88c40f4df7 upstream. - -Register File Data Sampling (RFDS) is a CPU side-channel vulnerability -that may expose stale register value. CPUs that set RFDS_NO bit in MSR -IA32_ARCH_CAPABILITIES indicate that they are not vulnerable to RFDS. -Similarly, RFDS_CLEAR indicates that CPU is affected by RFDS, and has -the microcode to help mitigate RFDS. - -Make RFDS_CLEAR and RFDS_NO bits available to guests. - -Intel-SIG: commit 41bdd9812863 target/i386: Export RFDS bit to guests. -Add SPR/GNR/SRA new ISAs backporting - -Signed-off-by: Pawan Gupta -Reviewed-by: Xiaoyao Li -Reviewed-by: Zhao Liu -Message-ID: <9a38877857392b5c2deae7e7db1b170d15510314.1710341348.git.pawan.kumar.gupta@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 00157dae9..80c3b58d1 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1025,8 +1025,8 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - NULL, NULL, NULL, NULL, - NULL, "fb-clear", NULL, NULL, - NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, "rfds-no", -+ "rfds-clear", NULL, NULL, NULL, - }, - .msr = { - .index = MSR_IA32_ARCH_CAPABILITIES, --- -2.25.1 diff --git a/1093-target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch b/1093-target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch deleted file mode 100644 index 48bd838..0000000 --- a/1093-target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: Lei Wang -Date: Thu, 6 Jul 2023 13:49:48 +0800 -Subject: [PATCH] target/i386: Add few security fix bits in ARCH_CAPABILITIES into SapphireRapids CPU model - -commit 3baf7ae63505eb1652d1e52d65798307fead8539 upstream. - -SapphireRapids has bit 13, 14 and 15 of MSR_IA32_ARCH_CAPABILITIES -enabled, which are related to some security fixes. - -Add version 2 of SapphireRapids CPU model with those bits enabled also. - -Intel-SIG: commit 3baf7ae63505 target/i386: Add few security fix bits in ARCH_CAPABILITIES into SapphireRapids CPU model. -6.2-SPR new model support - -Signed-off-by: Lei Wang -Signed-off-by: Tao Su -Message-ID: <20230706054949.66556-6-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 0a3c76854..8a045e065 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -3762,8 +3762,17 @@ static const X86CPUDefinition builtin_x86_defs[] = { - .model_id = "Intel Xeon Processor (SapphireRapids)", - .versions = (X86CPUVersionDefinition[]) { - { .version = 1 }, -- { /* end of list */ }, -- }, -+ { -+ .version = 2, -+ .props = (PropValue[]) { -+ { "sbdr-ssdp-no", "on" }, -+ { "fbsdp-no", "on" }, -+ { "psdp-no", "on" }, -+ { /* end of list */ } -+ } -+ }, -+ { /* end of list */ } -+ } - }, - { - .name = "SierraForest", --- -2.25.1 diff --git a/1094-target-i386-Introduce-SapphireRapids-v3-to-add-missi.patch b/1094-target-i386-Introduce-SapphireRapids-v3-to-add-missi.patch deleted file mode 100644 index a035ee1..0000000 --- a/1094-target-i386-Introduce-SapphireRapids-v3-to-add-missi.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Lei Wang -Date: Wed, 24 Apr 2024 03:29:12 -0400 -Subject: [PATCH] target/i386: Introduce SapphireRapids-v3 to add missing features - -commit b10b2481738304db13d28252e86c10555121a5b3 upstream. - -Add the missing features(ss, tsc-adjust, cldemote, movdiri, movdir64b) in -the SapphireRapids-v3 CPU model. - -Intel-SIG: commit b10b24817383 target/i386: Introduce SapphireRapids-v3 to add missing features. -6.2-SPR new model support - -Signed-off-by: Lei Wang -Message-ID: <20240424072912.43188-1-lei4.wang@intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index f4b5c95c5..baa1a8207 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -3730,6 +3730,17 @@ static const X86CPUDefinition builtin_x86_defs[] = { - { /* end of list */ } - } - }, -+ { -+ .version = 3, -+ .props = (PropValue[]) { -+ { "ss", "on" }, -+ { "tsc-adjust", "on" }, -+ { "cldemote", "on" }, -+ { "movdiri", "on" }, -+ { "movdir64b", "on" }, -+ { /* end of list */ } -+ } -+ }, - { /* end of list */ } - } - }, --- -2.25.1 diff --git a/1095-ebpf-replace-deprecated-bpf_program__set_socket_filt.patch b/1095-ebpf-replace-deprecated-bpf_program__set_socket_filt.patch deleted file mode 100644 index 574626b..0000000 --- a/1095-ebpf-replace-deprecated-bpf_program__set_socket_filt.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Haochen Tong -Date: Sat, 28 May 2022 03:06:58 +0800 -Subject: [PATCH] ebpf: replace deprecated bpf_program__set_socket_filter - -commit a495eba03c31c96d6a0817b13598ce2219326691 upstream. - -bpf_program__set_ functions have been deprecated since libbpf 0.8. -Replace with the equivalent bpf_program__set_type call to avoid a -deprecation warning. - -Intel-SIG: commit a495eba03c31 ebpf: replace deprecated bpf_program__set_socket_filter. -6.2-SPR new model support - -Signed-off-by: Haochen Tong -Reviewed-by: Zhang Chen -Signed-off-by: Jason Wang -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - ebpf/ebpf_rss.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ebpf/ebpf_rss.c b/ebpf/ebpf_rss.c -index 118c68da83..cee658c158 100644 ---- a/ebpf/ebpf_rss.c -+++ b/ebpf/ebpf_rss.c -@@ -49,7 +49,7 @@ bool ebpf_rss_load(struct EBPFRSSContext *ctx) - goto error; - } - -- bpf_program__set_socket_filter(rss_bpf_ctx->progs.tun_rss_steering_prog); -+ bpf_program__set_type(rss_bpf_ctx->progs.tun_rss_steering_prog, BPF_PROG_TYPE_SOCKET_FILTER); - - if (rss_bpf__load(rss_bpf_ctx)) { - trace_ebpf_error("eBPF RSS", "can not load RSS program"); --- -2.25.1 diff --git a/1096-target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch b/1096-target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch deleted file mode 100644 index 0387342..0000000 --- a/1096-target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Pawan Gupta -Date: Fri, 23 Jun 2023 13:26:25 -0700 -Subject: [PATCH] target/i386: Export MSR_ARCH_CAPABILITIES bits to guests - -commit 5bef742cc4f0e21c80a31611af7881ba811e507f upstream. - -On Intel CPUs there are certain bits in MSR_ARCH_CAPABILITIES that -indicates if the CPU is not affected by a vulnerability. Without these -bits guests may try to deploy the mitigation even if the CPU is not -affected. - -Export the bits to guests that indicate immunity to hardware -vulnerabilities. - -Intel-SIG: commit 5bef742cc4f0 target/i386: Export MSR_ARCH_CAPABILITIES bits to guests. -6.2-SPR new model support - -Signed-off-by: Pawan Gupta -Message-ID: <63d85cc76d4cdc51e6c732478b81d8f13be11e5a.1687551881.git.pawan.kumar.gupta@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 11f52c79b..62149367b 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1022,10 +1022,10 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - "rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry", - "ssb-no", "mds-no", "pschange-mc-no", "tsx-ctrl", - "taa-no", NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ NULL, "sbdr-ssdp-no", "fbsdp-no", "psdp-no", - NULL, "fb-clear", NULL, NULL, - NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, "rfds-no", -+ "pbrsb-no", NULL, NULL, "rfds-no", - "rfds-clear", NULL, NULL, NULL, - }, - .msr = { --- -2.25.1 diff --git a/81-kvm-anolis.rules b/81-kvm-rhel.rules similarity index 100% rename from 81-kvm-anolis.rules rename to 81-kvm-rhel.rules diff --git a/Add-lbt-support-for-kvm.patch b/Add-lbt-support-for-kvm.patch deleted file mode 100644 index 660785f..0000000 --- a/Add-lbt-support-for-kvm.patch +++ /dev/null @@ -1,154 +0,0 @@ -From b7760c4fd70de74df6014394c5d27d498fed3e31 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 08:00:52 -0400 -Subject: [PATCH 22/28] Add lbt support for kvm - -Signed-off-by: lixianglai ---- - hw/loongarch/larch_3a.c | 4 ++-- - linux-headers/asm-loongarch64/kvm.h | 10 ++++++++- - target/loongarch64/cpu.h | 10 +++++++++ - target/loongarch64/kvm.c | 35 +++++++++++++++++++++++++++++ - 4 files changed, 56 insertions(+), 3 deletions(-) - -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -index 8fc79546d..2affc5048 100644 ---- a/hw/loongarch/larch_3a.c -+++ b/hw/loongarch/larch_3a.c -@@ -348,8 +348,8 @@ struct kvm_cpucfg ls3a5k_cpucfgs = { - CPUCFG1_IOCSRBRD, - .cpucfg[LOONGARCH_CPUCFG2] = CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP | - CPUCFG2_FPVERS | CPUCFG2_LSX | CPUCFG2_LASX | CPUCFG2_COMPLEX | -- CPUCFG2_CRYPTO | CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | CPUCFG2_LSPW | -- CPUCFG2_LAM, -+ CPUCFG2_CRYPTO | CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | CPUCFG2_X86BT | -+ CPUCFG2_ARMBT | CPUCFG2_MIPSBT | CPUCFG2_LSPW | CPUCFG2_LAM, - .cpucfg[LOONGARCH_CPUCFG3] = CPUCFG3_CCDMA | CPUCFG3_SFB | CPUCFG3_UCACC | - CPUCFG3_LLEXC | CPUCFG3_SCDLY | CPUCFG3_LLDBAR | CPUCFG3_ITLBT | - CPUCFG3_ICACHET | CPUCFG3_SPW_LVL | CPUCFG3_SPW_HG_HF | CPUCFG3_RVA | -diff --git a/linux-headers/asm-loongarch64/kvm.h b/linux-headers/asm-loongarch64/kvm.h -index 799af7594..3687a358f 100644 ---- a/linux-headers/asm-loongarch64/kvm.h -+++ b/linux-headers/asm-loongarch64/kvm.h -@@ -77,6 +77,7 @@ struct kvm_fpu { - * Register set = 2: KVM specific registers (see definitions below). - * - * Register set = 3: FPU / MSA registers (see definitions below). -+ * Register set = 4: LBT registers (see definitions below). - * - * Other sets registers may be added in the future. Each set would - * have its own identifier in bits[31..16]. -@@ -86,7 +87,7 @@ struct kvm_fpu { - #define KVM_REG_LOONGARCH_CSR (KVM_REG_LOONGARCH | 0x0000000000010000ULL) - #define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x0000000000020000ULL) - #define KVM_REG_LOONGARCH_FPU (KVM_REG_LOONGARCH | 0x0000000000030000ULL) -- -+#define KVM_REG_LOONGARCH_LBT (KVM_REG_LOONGARCH | 0x0000000000040000ULL) - - /* - * KVM_REG_LOONGARCH_GP - General purpose registers from kvm_regs. -@@ -168,6 +169,13 @@ struct kvm_fpu { - - #define KVM_REG_LOONGARCH_VCPU_RESET (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 4) - -+#define KVM_REG_LBT_SCR0 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 1) -+#define KVM_REG_LBT_SCR1 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 2) -+#define KVM_REG_LBT_SCR2 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 3) -+#define KVM_REG_LBT_SCR3 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 4) -+#define KVM_REG_LBT_FLAGS (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 5) -+#define KVM_REG_LBT_FTOP (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 6) -+ - struct kvm_iocsr_entry { - __u32 addr; - __u32 pad; -diff --git a/target/loongarch64/cpu.h b/target/loongarch64/cpu.h -index 078556a22..ab88658e4 100644 ---- a/target/loongarch64/cpu.h -+++ b/target/loongarch64/cpu.h -@@ -55,6 +55,7 @@ typedef struct CPULOONGARCHFPUContext { - uint32_t fcsr0; - uint32_t fcsr0_rw_bitmask; - uint32_t vcsr16; -+ uint64_t ftop; - } CPULOONGARCHFPUContext; - - /* fp control and status register definition */ -@@ -167,6 +168,15 @@ struct CPULOONGARCHState { - struct { - uint64_t guest_addr; - } st; -+ struct { -+ /* scratch registers */ -+ unsigned long scr0; -+ unsigned long scr1; -+ unsigned long scr2; -+ unsigned long scr3; -+ /* loongarch eflag */ -+ unsigned long eflag; -+ } lbt; - }; - - -diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c -index b6711da91..0eaabe394 100644 ---- a/target/loongarch64/kvm.c -+++ b/target/loongarch64/kvm.c -@@ -1295,6 +1295,39 @@ int kvm_loongarch_get_pvtime(LOONGARCHCPU *cpu) - return 0; - } - -+ -+static int kvm_loongarch_put_lbt_registers(CPUState *cs) -+{ -+ int ret = 0; -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR0, &env->lbt.scr0); -+ ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR1, &env->lbt.scr1); -+ ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR2, &env->lbt.scr2); -+ ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR3, &env->lbt.scr3); -+ ret |= kvm_larch_putq(cs, KVM_REG_LBT_FLAGS, &env->lbt.eflag); -+ ret |= kvm_larch_putq(cs, KVM_REG_LBT_FTOP, &env->active_fpu.ftop); -+ -+ return ret; -+} -+ -+static int kvm_loongarch_get_lbt_registers(CPUState *cs) -+{ -+ int ret = 0; -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR0, &env->lbt.scr0); -+ ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR1, &env->lbt.scr1); -+ ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR2, &env->lbt.scr2); -+ ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR3, &env->lbt.scr3); -+ ret |= kvm_larch_getq(cs, KVM_REG_LBT_FLAGS, &env->lbt.eflag); -+ ret |= kvm_larch_getq(cs, KVM_REG_LBT_FTOP, &env->active_fpu.ftop); -+ -+ return ret; -+} -+ - int kvm_arch_put_registers(CPUState *cs, int level) - { - LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -@@ -1326,6 +1359,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) - return ret; - } - -+ kvm_loongarch_put_lbt_registers(cs); - return ret; - } - -@@ -1352,6 +1386,7 @@ int kvm_arch_get_registers(CPUState *cs) - - kvm_loongarch_get_csr_registers(cs); - kvm_loongarch_get_fpu_registers(cs); -+ kvm_loongarch_get_lbt_registers(cs); - - return ret; - } --- -2.43.5 - diff --git a/Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch b/Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch deleted file mode 100644 index 330b37d..0000000 --- a/Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 3e8ddd1af3c46387ed45319dd0dc3c0a673b989f Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Mon, 19 Jun 2023 09:38:16 +0800 -Subject: [PATCH 25/28] Add loongarch into QEMU_ARCH_VIRTIO_PCI to support qdev - alias - -Signed-off-by: Tianrui Zhao ---- - softmmu/qdev-monitor.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c -index 01f3834db..ece96121d 100644 ---- a/softmmu/qdev-monitor.c -+++ b/softmmu/qdev-monitor.c -@@ -60,7 +60,8 @@ typedef struct QDevAlias - QEMU_ARCH_HPPA | QEMU_ARCH_I386 | \ - QEMU_ARCH_MIPS | QEMU_ARCH_PPC | \ - QEMU_ARCH_RISCV | QEMU_ARCH_SH4 | \ -- QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA) -+ QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA | \ -+ QEMU_ARCH_LOONGARCH64) - #define QEMU_ARCH_VIRTIO_CCW (QEMU_ARCH_S390X) - #define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K) - --- -2.43.5 - diff --git a/Add-usb-storage-config-for-loongarch.patch b/Add-usb-storage-config-for-loongarch.patch deleted file mode 100644 index 0529515..0000000 --- a/Add-usb-storage-config-for-loongarch.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 1f41256389e5d8862d08b2253d752569727f1e79 Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Mon, 19 Jun 2023 09:34:02 +0800 -Subject: [PATCH 24/28] Add usb-storage config for loongarch - -Signed-off-by: Tianrui Zhao ---- - configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak -index 696ee9b72..15fc2d00f 100644 ---- a/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak -+++ b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak -@@ -147,6 +147,8 @@ CONFIG_USB_EHCI=y - CONFIG_USB_EHCI_PCI=y - CONFIG_USB_EHCI_SYSBUS=y - CONFIG_USB_STORAGE_BOT=y -+CONFIG_USB_STORAGE_CORE=y -+CONFIG_USB_STORAGE_CLASSIC=y - CONFIG_TPM_EMULATOR=y - CONFIG_TPM_TIS=y - CONFIG_PLATFORM_BUS=y --- -2.43.5 - diff --git a/Fix-LoongArch-KVM-header-macros.patch b/Fix-LoongArch-KVM-header-macros.patch deleted file mode 100644 index 57ea9d8..0000000 --- a/Fix-LoongArch-KVM-header-macros.patch +++ /dev/null @@ -1,32 +0,0 @@ -From d090e30797ef1acc5f0f5488a60040606f60ff44 Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Tue, 20 Jun 2023 16:34:43 +0800 -Subject: [PATCH 27/28] Fix LoongArch KVM header macros - -Signed-off-by: Tianrui Zhao ---- - linux-headers/linux/kvm.h | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index f5589b068..0e50d3749 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2126,10 +2126,10 @@ struct kvm_loongarch_vcpu_state { - __u64 core_ext_ioisr[4]; - }; - --#define KVM_CAP_LOONGARCH_FPU 800 --#define KVM_CAP_LOONGARCH_LSX 801 --#define KVM_CAP_LOONGARCH_VZ 802 --#define KVM_REG_LOONGARCH 0x9000000000000000ULL -+#define KVM_CAP_LOONGARCH_FPU 165 -+#define KVM_CAP_LOONGARCH_LSX 166 -+#define KVM_CAP_LOONGARCH_VZ 167 -+#define KVM_REG_LOONGARCH 0x8000000000000000ULL - #define KVM_LARCH_GET_VCPU_STATE _IOR(KVMIO, 0xc0, struct kvm_loongarch_vcpu_state) - #define KVM_LARCH_SET_VCPU_STATE _IOW(KVMIO, 0xc1, struct kvm_loongarch_vcpu_state) - #define KVM_LARCH_GET_CPUCFG _IOR(KVMIO, 0xc2, struct kvm_cpucfg) --- -2.43.5 - diff --git a/Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch b/Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch deleted file mode 100644 index 9d6896c..0000000 --- a/Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch +++ /dev/null @@ -1,27 +0,0 @@ -From ff15ca716d827e6364e51f1ee9d7bc6440d55c20 Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Mon, 19 Jun 2023 16:38:29 +0800 -Subject: [PATCH 26/28] Fix host architecture macro of LoongArch to - HOST_LOONGARCH64 - -Signed-off-by: Tianrui Zhao ---- - accel/kvm/kvm-all.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 48034d427..6d63f0ab0 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2503,7 +2503,7 @@ static int kvm_init(MachineState *ms) - soft_vcpus_limit = kvm_recommended_vcpus(s); - hard_vcpus_limit = kvm_max_vcpus(s); - --#if defined(HOST_PPC64) || defined(HOST_LOONGARCH) -+#if defined(HOST_PPC64) || defined(HOST_LOONGARCH64) - /* - * On POWER, the kernel advertises a soft limit based on the - * number of CPU threads on the host. We want to allow exceeding --- -2.43.5 - diff --git a/Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch b/Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch deleted file mode 100644 index 09a842d..0000000 --- a/Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch +++ /dev/null @@ -1,31 +0,0 @@ -From d24d2e0d530e6354d4f9a4b213983779136f4ab7 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 07:38:26 -0400 -Subject: [PATCH 16/28] Fix irq routing and fpu option to compat with kernel - v6.4 - -Fix set irq routing and enable fpu for kvm to compat -with kernel v6.4 - -Signed-off-by: lixianglai ---- - target/loongarch64/kvm.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c -index 6885ec6c9..b6711da91 100644 ---- a/target/loongarch64/kvm.c -+++ b/target/loongarch64/kvm.c -@@ -107,6 +107,9 @@ int kvm_arch_init_vcpu(CPUState *cs) - CPULOONGARCHState *env = &cpu->env; - int ret = 0; - -+ kvm_vcpu_enable_cap(cs, KVM_CAP_LOONGARCH_FPU, 0, 0); -+ kvm_vcpu_enable_cap(cs, KVM_CAP_LOONGARCH_LSX, 0, 0); -+ - cpu->cpuStateEntry = qemu_add_vm_change_state_handler(kvm_loongarch_update_state, cs); - cpu->kvm_csr_buf = g_malloc0(CSR_BUF_SIZE + CSR_BUF_SIZE); - --- -2.43.5 - diff --git a/Fix-smp.cores-value.patch b/Fix-smp.cores-value.patch deleted file mode 100644 index 9517ef9..0000000 --- a/Fix-smp.cores-value.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 902dc77676bc6ada74ddbdb57d00821435550bdb Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 07:55:12 -0400 -Subject: [PATCH 21/28] Fix smp.cores value - -The smp.cores should use the default value passed from -qemu start command, and the argument is cores_per_socket. - -Signed-off-by: lixianglai ---- - hw/loongarch/larch_3a.c | 7 ------- - 1 file changed, 7 deletions(-) - -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -index b1501e0ea..8fc79546d 100644 ---- a/hw/loongarch/larch_3a.c -+++ b/hw/loongarch/larch_3a.c -@@ -1211,14 +1211,7 @@ static void loongarch_build_smbios(LoongarchMachineState *lsms) - uint8_t *smbios_tables, *smbios_anchor; - size_t smbios_tables_len, smbios_anchor_len; - const char *product = "QEMU Virtual Machine"; -- int nb_numa_nodes, smp_cpus; - -- smp_cpus = ms->smp.cpus; -- nb_numa_nodes = ms->numa_state->num_nodes; -- if (nb_numa_nodes == 0) { -- nb_numa_nodes = 1; -- } -- ms->smp.cores = smp_cpus / nb_numa_nodes; - if (!lsms->fw_cfg) { - return; - } --- -2.43.5 - diff --git a/Fixed-the-issue-where-qemu-specifies-the-boot-order.patch b/Fixed-the-issue-where-qemu-specifies-the-boot-order.patch deleted file mode 100644 index b86a981..0000000 --- a/Fixed-the-issue-where-qemu-specifies-the-boot-order.patch +++ /dev/null @@ -1,140 +0,0 @@ -From d280c3a4a6ea0b3b9bf03bd4d4bd36b7e763287e Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Wed, 23 Aug 2023 07:10:25 -0400 -Subject: [PATCH 28/28] Fixed the issue where qemu specifies the boot order - -Fixed the issue that the device path of bootorder -in the generated fw_cfg was abnormal because the -PCIeHost device did not initialize the memory space -of sysbus, which caused the QEMU boot order to not -take effect. - -Change-Id: Ifde4c8b8432c5c8748c1b38a3c33bafef4f24083 -Signed-off-by: lixianglai ---- - hw/loongarch/larch_3a.c | 14 -------------- - hw/loongarch/ls7a_nb.c | 28 ++++++++++++++++++++++++++-- - include/hw/loongarch/larch.h | 6 ++++++ - include/hw/loongarch/ls7a.h | 2 ++ - 4 files changed, 34 insertions(+), 16 deletions(-) - -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -index 2affc5048..1a4e982b7 100644 ---- a/hw/loongarch/larch_3a.c -+++ b/hw/loongarch/larch_3a.c -@@ -86,12 +86,6 @@ - - #define TARGET_REALPAGE_MASK (TARGET_PAGE_MASK << 2) - --#ifdef CONFIG_KVM --#define LS_ISA_IO_SIZE 0x02000000 --#else --#define LS_ISA_IO_SIZE 0x00010000 --#endif -- - #ifdef CONFIG_KVM - #define align(x) (((x) + 63) & ~63) - #else -@@ -1618,8 +1612,6 @@ static void ls3a5k_init(MachineState *args) - ram_addr_t ram_size = args->ram_size; - MemoryRegion *address_space_mem = get_system_memory(); - ram_addr_t offset = 0; -- MemoryRegion *isa_io = g_new(MemoryRegion, 1); -- MemoryRegion *isa_mem = g_new(MemoryRegion, 1); - MachineState *machine = args; - MachineClass *mc = MACHINE_GET_CLASS(machine); - LoongarchMachineState *lsms = LoongarchMACHINE(machine); -@@ -1799,12 +1791,6 @@ static void ls3a5k_init(MachineState *args) - &machine->device_memory->mr); - } - -- memory_region_init_alias(isa_io, NULL, "isa-io", -- get_system_io(), 0, LS_ISA_IO_SIZE); -- memory_region_init(isa_mem, NULL, "isa-mem", PCIE_MEMORY_SIZE); -- memory_region_add_subregion(get_system_memory(), lsmc->isa_io_base, isa_io); -- memory_region_add_subregion(get_system_memory(), PCIE_MEMORY_BASE, isa_mem); -- - if (!strcmp(lsmc->bridge_name, "ls7a")) { - /*Initialize the 7A IO interrupt subsystem*/ - DeviceState *ls7a_dev; -diff --git a/hw/loongarch/ls7a_nb.c b/hw/loongarch/ls7a_nb.c -index 5a231e6f0..f11b855a7 100644 ---- a/hw/loongarch/ls7a_nb.c -+++ b/hw/loongarch/ls7a_nb.c -@@ -162,17 +162,41 @@ static PCIBus *pci_ls7a_init(MachineState *machine, DeviceState *dev, - { - LoongarchMachineState *lsms = LoongarchMACHINE(machine); - LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ LS7APCIEHost *pciehost = LS7A_PCIE_HOST_BRIDGE(dev); - PCIExpressHost *e; -+ SysBusDevice *sysbus; - PCIHostState *phb; -+ MemoryRegion *mmio_alias; - - e = PCIE_HOST_BRIDGE(dev); -+ sysbus = SYS_BUS_DEVICE(e); - phb = PCI_HOST_BRIDGE(e); -+ -+ sysbus_init_mmio(sysbus, &e->mmio); -+ -+ memory_region_init(&pciehost->io_mmio, OBJECT(pciehost), -+ "pciehost-mmio", UINT64_MAX); -+ sysbus_init_mmio(sysbus, &pciehost->io_mmio); -+ mmio_alias = g_new0(MemoryRegion, 1); -+ memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio", -+ &pciehost->io_mmio, PCIE_MEMORY_BASE, -+ PCIE_MEMORY_SIZE); -+ memory_region_add_subregion(get_system_memory(), -+ PCIE_MEMORY_BASE, mmio_alias); -+ -+ memory_region_init(&pciehost->io_ioport, OBJECT(pciehost), -+ "pciehost-ioport", LS_ISA_IO_SIZE); -+ sysbus_init_mmio(sysbus, &pciehost->io_ioport); -+ -+ sysbus_mmio_map(sysbus, 2, LS3A5K_ISA_IO_BASE); -+ -+ - phb->bus = pci_register_root_bus(dev, "pcie.0", pci_ls7a_set_irq, - pci_ls7a_map_irq, pic, -- get_system_memory(), get_system_io(), -+ &pciehost->io_mmio, &pciehost->io_ioport, - (1 << 3), 128, TYPE_PCIE_BUS); -+ /*update pcie config memory*/ - pcie_host_mmcfg_update(e, true, lsmc->pciecfg_base, LS_PCIECFG_SIZE); -- DPRINTF("------ %d\n", __LINE__); - - pci_bus_set_route_irq_fn(phb->bus, ls7a_route_intx_pin_to_irq); - -diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h -index b8f28e330..3f4fdd946 100644 ---- a/include/hw/loongarch/larch.h -+++ b/include/hw/loongarch/larch.h -@@ -40,6 +40,12 @@ - #define LOONGARCH_HOTPLUG_MEM_ALIGN (1ULL << 28) - #define LOONGARCH_MAX_RAM_SLOTS 10 - -+#ifdef CONFIG_KVM -+#define LS_ISA_IO_SIZE 0x02000000 -+#else -+#define LS_ISA_IO_SIZE 0x00010000 -+#endif -+ - /* Memory types: */ - #define SYSTEM_RAM 1 - #define SYSTEM_RAM_RESERVED 2 -diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h -index 63a070296..05edee603 100644 ---- a/include/hw/loongarch/ls7a.h -+++ b/include/hw/loongarch/ls7a.h -@@ -121,6 +121,8 @@ - typedef struct LS7APCIState LS7APCIState; - typedef struct LS7APCIEHost { - PCIExpressHost parent_obj; -+ MemoryRegion io_ioport; -+ MemoryRegion io_mmio; - LS7APCIState *pci_dev; - } LS7APCIEHost; - --- -2.43.5 - diff --git a/Modify-smbios-option-lack-and-Modify-the-maximum-num.patch b/Modify-smbios-option-lack-and-Modify-the-maximum-num.patch deleted file mode 100644 index 10eb346..0000000 --- a/Modify-smbios-option-lack-and-Modify-the-maximum-num.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 3839b5ecff1bb68ed03e0cb901acfd331668d4fd Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 05:48:46 -0400 -Subject: [PATCH 10/28] Modify smbios option lack and Modify the maximum number - of CPUs supported by the virtual machine. - -Add smbios option support for loongarch. -The number of virtual CPUs can be greater than the number of CPUs of the host machine. - -Signed-off-by: lixianglai ---- - accel/kvm/kvm-all.c | 2 +- - qemu-options.hx | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 3b7bc3982..48034d427 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2503,7 +2503,7 @@ static int kvm_init(MachineState *ms) - soft_vcpus_limit = kvm_recommended_vcpus(s); - hard_vcpus_limit = kvm_max_vcpus(s); - --#ifdef HOST_PPC64 -+#if defined(HOST_PPC64) || defined(HOST_LOONGARCH) - /* - * On POWER, the kernel advertises a soft limit based on the - * number of CPU threads on the host. We want to allow exceeding -diff --git a/qemu-options.hx b/qemu-options.hx -index 981248e28..1b3f2df49 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -2480,7 +2480,7 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios, - " 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) -+ QEMU_ARCH_I386 | QEMU_ARCH_ARM | QEMU_ARCH_LOONGARCH64) - SRST - ``-smbios file=binary`` - Load SMBIOS entry from binary file. --- -2.43.5 - diff --git a/Modify-the-ioctl-command-of-kvm.patch b/Modify-the-ioctl-command-of-kvm.patch deleted file mode 100644 index 6b41fb1..0000000 --- a/Modify-the-ioctl-command-of-kvm.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c593589f83c7655dcd8b9c144bf6061933d4ed40 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 08:44:26 -0400 -Subject: [PATCH 23/28] Modify the ioctl command of kvm. - -Signed-off-by: lixianglai ---- - linux-headers/linux/kvm.h | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 0e50d3749..f5589b068 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2126,10 +2126,10 @@ struct kvm_loongarch_vcpu_state { - __u64 core_ext_ioisr[4]; - }; - --#define KVM_CAP_LOONGARCH_FPU 165 --#define KVM_CAP_LOONGARCH_LSX 166 --#define KVM_CAP_LOONGARCH_VZ 167 --#define KVM_REG_LOONGARCH 0x8000000000000000ULL -+#define KVM_CAP_LOONGARCH_FPU 800 -+#define KVM_CAP_LOONGARCH_LSX 801 -+#define KVM_CAP_LOONGARCH_VZ 802 -+#define KVM_REG_LOONGARCH 0x9000000000000000ULL - #define KVM_LARCH_GET_VCPU_STATE _IOR(KVMIO, 0xc0, struct kvm_loongarch_vcpu_state) - #define KVM_LARCH_SET_VCPU_STATE _IOW(KVMIO, 0xc1, struct kvm_loongarch_vcpu_state) - #define KVM_LARCH_GET_CPUCFG _IOR(KVMIO, 0xc2, struct kvm_cpucfg) --- -2.43.5 - diff --git a/Support-TPM.patch b/Support-TPM.patch deleted file mode 100644 index 8bfa530..0000000 --- a/Support-TPM.patch +++ /dev/null @@ -1,518 +0,0 @@ -From 8eea4ea57942c83f0e1d9d4073004409505fda59 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 07:16:34 -0400 -Subject: [PATCH 13/28] Support TPM. - -Signed-off-by: lixianglai ---- - hw/loongarch/acpi-build.c | 44 +++++++ - hw/loongarch/larch_3a.c | 53 ++++++++- - hw/loongarch/larch_hotplug.c | 16 ++- - hw/loongarch/meson.build | 1 + - hw/loongarch/sysbus-fdt.c | 183 ++++++++++++++++++++++++++++++ - include/hw/loongarch/larch.h | 1 + - include/hw/loongarch/ls7a.h | 5 + - include/hw/loongarch/sysbus-fdt.h | 37 ++++++ - 8 files changed, 333 insertions(+), 7 deletions(-) - create mode 100644 hw/loongarch/sysbus-fdt.c - create mode 100644 include/hw/loongarch/sysbus-fdt.h - -diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c -index 6ba637be5..682e016be 100644 ---- a/hw/loongarch/acpi-build.c -+++ b/hw/loongarch/acpi-build.c -@@ -58,6 +58,7 @@ - #include "hw/acpi/aml-build.h" - #include "hw/loongarch/larch.h" - #include "hw/loongarch/ls7a.h" -+#include "hw/platform-bus.h" - - #include "hw/acpi/ipmi.h" - #include "hw/acpi/ls7a.h" -@@ -474,7 +475,40 @@ static void build_ls7a_uart_device_aml(Aml *table) - aml_append(scope, dev); - aml_append(table, scope); - } -+#ifdef CONFIG_TPM -+static void acpi_dsdt_add_tpm(Aml *scope, LoongarchMachineState *vms) -+{ -+ PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev); -+ hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS; -+ SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find()); -+ MemoryRegion *sbdev_mr; -+ hwaddr tpm_base; -+ -+ if (!sbdev) { -+ return; -+ } -+ -+ tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); -+ assert(tpm_base != -1); - -+ tpm_base += pbus_base; -+ -+ sbdev_mr = sysbus_mmio_get_region(sbdev, 0); -+ -+ Aml *dev = aml_device("TPM0"); -+ aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101"))); -+ aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device"))); -+ aml_append(dev, aml_name_decl("_UID", aml_int(0))); -+ -+ Aml *crs = aml_resource_template(); -+ aml_append(crs, -+ aml_memory32_fixed(tpm_base, -+ (uint32_t)memory_region_size(sbdev_mr), -+ AML_READ_WRITE)); -+ aml_append(dev, aml_name_decl("_CRS", crs)); -+ aml_append(scope, dev); -+} -+#endif - static void - build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) - { -@@ -500,6 +534,10 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) - aml_append(dev, aml_name_decl("_UID", aml_int(1))); - aml_append(dev, build_ls7a_osc_method()); - aml_append(sb_scope, dev); -+ -+#ifdef CONFIG_TPM -+ acpi_dsdt_add_tpm(sb_scope, lsms); -+#endif - aml_append(dsdt, sb_scope); - - build_ls7a_pci0_int(dsdt); -@@ -633,6 +671,12 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) - lsms->oem_table_id); - } - -+ if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) { -+ acpi_add_table(table_offsets, tables_blob); -+ build_tpm2(tables_blob, tables->linker, tables->tcpalog, -+ lsms->oem_id, lsms->oem_table_id); -+ } -+ - /* Build mcfg */ - acpi_add_table(table_offsets, tables_blob); - { -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -index 3194a822c..6c2602050 100644 ---- a/hw/loongarch/larch_3a.c -+++ b/hw/loongarch/larch_3a.c -@@ -52,6 +52,7 @@ - #include "hw/rtc/mc146818rtc.h" - #include "hw/irq.h" - #include "net/net.h" -+#include "hw/platform-bus.h" - #include "hw/timer/i8254.h" - #include "hw/loongarch/larch.h" - #include "hw/loongarch/ls7a.h" -@@ -65,6 +66,8 @@ - #include "sysemu/device_tree.h" - #include "qapi/visitor.h" - #include "qapi/qapi-visit-common.h" -+#include "sysemu/tpm.h" -+#include "hw/loongarch/sysbus-fdt.h" - - #include - -@@ -1235,6 +1238,19 @@ void loongarch_machine_done(Notifier *notifier, void *data) - { - LoongarchMachineState *lsms = container_of(notifier, - LoongarchMachineState, machine_done); -+ -+ platform_bus_add_all_fdt_nodes(lsms->fdt, NULL, -+ VIRT_PLATFORM_BUS_BASEADDRESS, -+ VIRT_PLATFORM_BUS_SIZE, -+ VIRT_PLATFORM_BUS_IRQ); -+ -+ qemu_fdt_dumpdtb(lsms->fdt, lsms->fdt_size); -+ /* load fdt */ -+ MemoryRegion *fdt_rom = g_new(MemoryRegion, 1); -+ memory_region_init_rom(fdt_rom, NULL, "fdt", LS_FDT_SIZE, &error_fatal); -+ memory_region_add_subregion(get_system_memory(), LS_FDT_BASE, fdt_rom); -+ rom_add_blob_fixed("fdt", lsms->fdt, lsms->fdt_size, LS_FDT_BASE); -+ - loongarch_acpi_setup(); - loongarch_build_smbios(lsms); - } -@@ -1562,7 +1578,31 @@ static void fdt_add_pcie_node(const LoongarchMachineState *lsms) - 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, - 2, base_mmio, 2, size_mmio); - g_free(nodename); -- qemu_fdt_dumpdtb(lsms->fdt, lsms->fdt_size); -+} -+ -+static void create_platform_bus(LoongarchMachineState *s, qemu_irq *pic) -+{ -+ DeviceState *dev; -+ SysBusDevice *sysbus; -+ int i; -+ MemoryRegion *sysmem = get_system_memory(); -+ -+ dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE); -+ dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE); -+ qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS); -+ qdev_prop_set_uint32(dev, "mmio_size", VIRT_PLATFORM_BUS_SIZE); -+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); -+ s->platform_bus_dev = dev; -+ -+ sysbus = SYS_BUS_DEVICE(dev); -+ for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) { -+ int irq = VIRT_PLATFORM_BUS_IRQ + i; -+ sysbus_connect_irq(sysbus, i, pic[irq - LOONGARCH_PCH_IRQ_BASE]); -+ } -+ -+ memory_region_add_subregion(sysmem, -+ VIRT_PLATFORM_BUS_BASEADDRESS, -+ sysbus_mmio_get_region(sysbus, 0)); - } - - static void ls3a5k_init(MachineState *args) -@@ -1784,6 +1824,8 @@ static void ls3a5k_init(MachineState *args) - object_property_set_link(OBJECT(machine), LOONGARCH_MACHINE_ACPI_DEVICE_PROP, - OBJECT(ls7a_dev), &error_abort); - -+ create_platform_bus(lsms, ls7a_apic); -+ - #ifdef CONFIG_KVM - if (kvm_enabled()) { - kvm_direct_msi_allowed = (kvm_check_extension(kvm_state, -@@ -1835,11 +1877,6 @@ static void ls3a5k_init(MachineState *args) - - fdt_add_pcie_node(lsms); - -- /* load fdt */ -- MemoryRegion *fdt_rom = g_new(MemoryRegion, 1); -- memory_region_init_rom(fdt_rom, NULL, "fdt", LS_FDT_SIZE, &error_fatal); -- memory_region_add_subregion(get_system_memory(), LS_FDT_BASE, fdt_rom); -- rom_add_blob_fixed("fdt", lsms->fdt, lsms->fdt_size, LS_FDT_BASE); - } - - static const CPUArchIdList *loongarch_possible_cpu_arch_ids(MachineState *ms) -@@ -1986,6 +2023,10 @@ static void loongarch_class_init(ObjectClass *oc, void *data) - mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("Loongson-3A5000"); - mc->default_ram_id = "loongarch_ls3a.ram"; - -+#ifdef CONFIG_TPM -+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); -+#endif -+ - mc->reset = ls3a_board_reset; - mc->max_cpus = LOONGARCH_MAX_VCPUS; - hc->pre_plug = loongarch_machine_device_pre_plug; -diff --git a/hw/loongarch/larch_hotplug.c b/hw/loongarch/larch_hotplug.c -index 7bce95712..bb3e9826b 100644 ---- a/hw/loongarch/larch_hotplug.c -+++ b/hw/loongarch/larch_hotplug.c -@@ -32,6 +32,7 @@ - #include "hw/loongarch/larch.h" - #include "hw/cpu/core.h" - #include "hw/nvram/fw_cfg.h" -+#include "hw/platform-bus.h" - - /* find cpu slot in machine->possible_cpus by core_id */ - static CPUArchId *loongarch_find_cpu_slot(MachineState *ms, uint32_t id, -@@ -327,7 +328,8 @@ HotplugHandler *loongarch_get_hotpug_handler(MachineState *machine, - DeviceState *dev) - { - if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || -- object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { -+ object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU) || -+ object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) { - return HOTPLUG_HANDLER(machine); - } - return NULL; -@@ -346,6 +348,18 @@ void loongarch_machine_device_pre_plug(HotplugHandler *hotplug_dev, - void loongarch_machine_device_plug(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) - { -+ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); -+ -+ if (lsms->platform_bus_dev) { -+ MachineClass *mc = MACHINE_GET_CLASS(lsms); -+ -+ if (device_is_dynamic_sysbus(mc, dev)) { -+ platform_bus_link_device( -+ PLATFORM_BUS_DEVICE(lsms->platform_bus_dev), -+ SYS_BUS_DEVICE(dev)); -+ } -+ } -+ - if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - loongarch_memory_plug(hotplug_dev, dev, errp); - } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { -diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build -index 81ee99a02..47d886ddd 100644 ---- a/hw/loongarch/meson.build -+++ b/hw/loongarch/meson.build -@@ -9,6 +9,7 @@ loongarch_ss.add(files( - 'ipi.c', - 'apic.c', - 'iocsr.c', -+ 'sysbus-fdt.c', - )) - - hw_arch += {'loongarch64': loongarch_ss} -diff --git a/hw/loongarch/sysbus-fdt.c b/hw/loongarch/sysbus-fdt.c -new file mode 100644 -index 000000000..f750ad6b6 ---- /dev/null -+++ b/hw/loongarch/sysbus-fdt.c -@@ -0,0 +1,183 @@ -+/* -+ * Loongarch Platform Bus device tree generation helpers -+ * -+ * Copyright (c) 2014 Linaro Limited -+ * -+ * Authors: -+ * Alex Graf -+ * Eric Auger -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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 . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include -+#include "qemu/error-report.h" -+#include "sysemu/device_tree.h" -+#include "hw/platform-bus.h" -+#include "hw/display/ramfb.h" -+#include "hw/loongarch/sysbus-fdt.h" -+#include "sysemu/tpm.h" -+ -+/* -+ * internal struct that contains the information to create dynamic -+ * sysbus device node -+ */ -+typedef struct PlatformBusFDTData { -+ void *fdt; /* device tree handle */ -+ int irq_start; /* index of the first IRQ usable by platform bus devices */ -+ const char *pbus_node_name; /* name of the platform bus node */ -+ PlatformBusDevice *pbus; -+} PlatformBusFDTData; -+ -+/* struct that allows to match a device and create its FDT node */ -+typedef struct BindingEntry { -+ const char *typename; -+ const char *compat; -+ int (*add_fn)(SysBusDevice *sbdev, void *opaque); -+ bool (*match_fn)(SysBusDevice *sbdev, const struct BindingEntry *combo); -+} BindingEntry; -+ -+ -+ -+static int no_fdt_node(SysBusDevice *sbdev, void *opaque) -+{ -+ return 0; -+} -+ -+/* Device type based matching */ -+static bool type_match(SysBusDevice *sbdev, const BindingEntry *entry) -+{ -+ return !strcmp(object_get_typename(OBJECT(sbdev)), entry->typename); -+} -+ -+#define TYPE_BINDING(type, add_fn) {(type), NULL, (add_fn), NULL} -+ -+#ifdef CONFIG_TPM -+/* -+ * add_tpm_tis_fdt_node: Create a DT node for TPM TIS -+ * -+ * See kernel documentation: -+ * Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt -+ * Optional interrupt for command completion is not exposed -+ */ -+static int add_tpm_tis_fdt_node(SysBusDevice *sbdev, void *opaque) -+{ -+ PlatformBusFDTData *data = opaque; -+ PlatformBusDevice *pbus = data->pbus; -+ void *fdt = data->fdt; -+ const char *parent_node = data->pbus_node_name; -+ char *nodename; -+ uint32_t reg_attr[2]; -+ uint64_t mmio_base; -+ -+ mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); -+ nodename = g_strdup_printf("%s/tpm_tis@%" PRIx64, parent_node, mmio_base); -+ qemu_fdt_add_subnode(fdt, nodename); -+ -+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "tcg,tpm-tis-mmio"); -+ -+ reg_attr[0] = cpu_to_be32(mmio_base); -+ reg_attr[1] = cpu_to_be32(0x5000); -+ qemu_fdt_setprop(fdt, nodename, "reg", reg_attr, 2 * sizeof(uint32_t)); -+ -+ g_free(nodename); -+ -+ return 0; -+} -+#endif -+ -+/* list of supported dynamic sysbus bindings */ -+static const BindingEntry bindings[] = { -+#ifdef CONFIG_TPM -+ TYPE_BINDING(TYPE_TPM_TIS_SYSBUS, add_tpm_tis_fdt_node), -+#endif -+ TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node), -+ TYPE_BINDING("", NULL), /* last element */ -+}; -+ -+/* Generic Code */ -+ -+/** -+ * add_fdt_node - add the device tree node of a dynamic sysbus device -+ * -+ * @sbdev: handle to the sysbus device -+ * @opaque: handle to the PlatformBusFDTData -+ * -+ * Checks the sysbus type belongs to the list of device types that -+ * are dynamically instantiable and if so call the node creation -+ * function. -+ */ -+static void add_fdt_node(SysBusDevice *sbdev, void *opaque) -+{ -+ int i, ret; -+ -+ for (i = 0; i < ARRAY_SIZE(bindings); i++) { -+ const BindingEntry *iter = &bindings[i]; -+ -+ if (type_match(sbdev, iter)) { -+ if (!iter->match_fn || iter->match_fn(sbdev, iter)) { -+ ret = iter->add_fn(sbdev, opaque); -+ assert(!ret); -+ return; -+ } -+ } -+ } -+ error_report("Device %s can not be dynamically instantiated", -+ qdev_fw_name(DEVICE(sbdev))); -+ exit(1); -+} -+ -+void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr, -+ hwaddr bus_size, int irq_start) -+{ -+ const char platcomp[] = "qemu,platform\0simple-bus"; -+ PlatformBusDevice *pbus; -+ DeviceState *dev; -+ gchar *node; -+ -+ assert(fdt); -+ -+ node = g_strdup_printf("/platform@%"PRIx64, addr); -+ -+ /* Create a /platform node that we can put all devices into */ -+ qemu_fdt_add_subnode(fdt, node); -+ qemu_fdt_setprop(fdt, node, "compatible", platcomp, sizeof(platcomp)); -+ -+ /* -+ * Our platform bus region is less than 32bits, so 1 cell is enough for -+ * address and size -+ */ -+ qemu_fdt_setprop_cells(fdt, node, "#size-cells", 1); -+ qemu_fdt_setprop_cells(fdt, node, "#address-cells", 1); -+ qemu_fdt_setprop_cells(fdt, node, "ranges", 0, addr >> 32, addr, bus_size); -+ if (intc != NULL) { -+ qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", intc); -+ } -+ dev = qdev_find_recursive(sysbus_get_default(), TYPE_PLATFORM_BUS_DEVICE); -+ pbus = PLATFORM_BUS_DEVICE(dev); -+ -+ PlatformBusFDTData data = { -+ .fdt = fdt, -+ .irq_start = irq_start, -+ .pbus_node_name = node, -+ .pbus = pbus, -+ }; -+ -+ /* Loop through all dynamic sysbus devices and create their node */ -+ foreach_dynamic_sysbus_device(add_fdt_node, &data); -+ -+ g_free(node); -+} -diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h -index 62e2830e2..81dcb78f4 100644 ---- a/include/hw/loongarch/larch.h -+++ b/include/hw/loongarch/larch.h -@@ -103,6 +103,7 @@ typedef struct LoongarchMachineState { - void *fdt; - int fdt_size; - unsigned int hotpluged_cpu_num; -+ DeviceState *platform_bus_dev; - OnOffAuto acpi; - char *oem_id; - char *oem_table_id; -diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h -index 686af763a..fc78083be 100644 ---- a/include/hw/loongarch/ls7a.h -+++ b/include/hw/loongarch/ls7a.h -@@ -121,6 +121,11 @@ - #define INT_ROUTER_REGS_CORE2_INTISR 0x50 - #define INT_ROUTER_REGS_CORE3_INTISR 0x58 - -+#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000 -+#define VIRT_PLATFORM_BUS_SIZE 0x2000000 -+#define VIRT_PLATFORM_BUS_NUM_IRQS 2 -+#define VIRT_PLATFORM_BUS_IRQ 69 -+ - typedef struct LS7APCIState LS7APCIState; - typedef struct LS7APCIEHost { - PCIExpressHost parent_obj; -diff --git a/include/hw/loongarch/sysbus-fdt.h b/include/hw/loongarch/sysbus-fdt.h -new file mode 100644 -index 000000000..340c382cd ---- /dev/null -+++ b/include/hw/loongarch/sysbus-fdt.h -@@ -0,0 +1,37 @@ -+/* -+ * Dynamic sysbus device tree node generation API -+ * -+ * Copyright Linaro Limited, 2014 -+ * -+ * Authors: -+ * Alex Graf -+ * Eric Auger -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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 . -+ * -+ */ -+ -+#ifndef HW_ARM_SYSBUS_FDT_H -+#define HW_ARM_SYSBUS_FDT_H -+ -+#include "exec/hwaddr.h" -+ -+/** -+ * platform_bus_add_all_fdt_nodes - create all the platform bus nodes -+ * -+ * builds the parent platform bus node and all the nodes of dynamic -+ * sysbus devices attached to it. -+ */ -+void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr, -+ hwaddr bus_size, int irq_start); -+#endif --- -2.43.5 - diff --git a/Support-vfio-config.patch b/Support-vfio-config.patch deleted file mode 100644 index 01b2bb6..0000000 --- a/Support-vfio-config.patch +++ /dev/null @@ -1,47 +0,0 @@ -From e2e67dd2c2b0c3ff2737cd477bfc79cac64d4053 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 07:41:14 -0400 -Subject: [PATCH 17/28] Support vfio config - -Signed-off-by: lixianglai ---- - configs/devices/loongarch64-softmmu/default.mak | 9 +++++++++ - .../loongarch64-softmmu/loongarch64-rh-devices.mak | 8 ++++++++ - 2 files changed, 17 insertions(+) - -diff --git a/configs/devices/loongarch64-softmmu/default.mak b/configs/devices/loongarch64-softmmu/default.mak -index fcb7e45dd..b4994d8a6 100644 ---- a/configs/devices/loongarch64-softmmu/default.mak -+++ b/configs/devices/loongarch64-softmmu/default.mak -@@ -152,3 +152,12 @@ CONFIG_PLATFORM_BUS=y - CONFIG_TPM_TIS_SYSBUS=y - CONFIG_ACPI_LOONGARCH=y - CONFIG_LS7A_RTC=y -+ -+#vfio config -+CONFIG_VFIO=y -+CONFIG_VFIO_PCI=y -+CONFIG_VFIO_PLATFORM=y -+CONFIG_VFIO_XGMAC=y -+CONFIG_VFIO_AMD_XGBE=y -+ -+ -diff --git a/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak -index e7b5bdc8e..696ee9b72 100644 ---- a/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak -+++ b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak -@@ -153,3 +153,11 @@ CONFIG_PLATFORM_BUS=y - CONFIG_TPM_TIS_SYSBUS=y - CONFIG_ACPI_LOONGARCH=y - CONFIG_LS7A_RTC=y -+ -+#vfio config -+CONFIG_VFIO=y -+CONFIG_VFIO_PCI=y -+CONFIG_VFIO_PLATFORM=y -+CONFIG_VFIO_XGMAC=y -+CONFIG_VFIO_AMD_XGBE=y -+ --- -2.43.5 - diff --git a/address-space-code-cleanup-on-7A-virt-machine.patch b/address-space-code-cleanup-on-7A-virt-machine.patch deleted file mode 100644 index 61c4d78..0000000 --- a/address-space-code-cleanup-on-7A-virt-machine.patch +++ /dev/null @@ -1,276 +0,0 @@ -From 731b161d2cfddb67e4088282a33acaf90c2bd928 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 07:33:26 -0400 -Subject: [PATCH 15/28] address space code cleanup on 7A virt-machine. - -Signed-off-by: lixianglai ---- - hw/loongarch/larch_3a.c | 16 +++----- - hw/loongarch/ls7a_nb.c | 49 ------------------------- - include/hw/loongarch/larch.h | 1 - - include/hw/loongarch/ls7a.h | 71 ++++++++++++++++-------------------- - 4 files changed, 37 insertions(+), 100 deletions(-) - -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -index 6c2602050..6eaa53d74 100644 ---- a/hw/loongarch/larch_3a.c -+++ b/hw/loongarch/larch_3a.c -@@ -88,10 +88,8 @@ - - #ifdef CONFIG_KVM - #define LS_ISA_IO_SIZE 0x02000000 --#define LS_ISA_MEM_SIZE 0x40000000 - #else - #define LS_ISA_IO_SIZE 0x00010000 --#define LS_ISA_MEM_SIZE 0x01000000 - #endif - - #ifdef CONFIG_KVM -@@ -626,8 +624,8 @@ static struct irq_source_routing_table *init_irq_source(void *g_irq_source) - irq_info->ht_enable = 0x0000d17b; - irq_info->node_id = 0; - -- irq_info->pci_mem_start_addr = LS_ISA_MEM_BASE; -- irq_info->pci_mem_end_addr = irq_info->pci_mem_start_addr + LS_ISA_MEM_SIZE - 1; -+ irq_info->pci_mem_start_addr = PCIE_MEMORY_BASE; -+ irq_info->pci_mem_end_addr = irq_info->pci_mem_start_addr + PCIE_MEMORY_SIZE - 1; - - if (strstr(lsmc->cpu_name, "5000")) { - irq_info->pci_io_start_addr = LS3A5K_ISA_IO_BASE; -@@ -1551,8 +1549,8 @@ static void fdt_add_fw_cfg_node(const LoongarchMachineState *lsms) - static void fdt_add_pcie_node(const LoongarchMachineState *lsms) - { - char *nodename; -- hwaddr base_mmio = LS_ISA_MEM_BASE; -- hwaddr size_mmio = LS_ISA_MEM_SIZE; -+ hwaddr base_mmio = PCIE_MEMORY_BASE; -+ hwaddr size_mmio = PCIE_MEMORY_SIZE; - hwaddr base_pio = LS3A5K_ISA_IO_BASE; - hwaddr size_pio = LS_ISA_IO_SIZE; - hwaddr base_pcie = LS_PCIECFG_BASE; -@@ -1650,7 +1648,6 @@ static void ls3a5k_init(MachineState *args) - create_fdt(lsms); - - DPRINTF("isa 0x%lx\n", lsmc->isa_io_base); -- DPRINTF("ht1lo 0x%lx\n", lsmc->ht1lo_pcicfg_base); - DPRINTF("cpu_name %s bridge_name %s\n", - lsmc->cpu_name, lsmc->bridge_name); - -@@ -1800,9 +1797,9 @@ static void ls3a5k_init(MachineState *args) - - memory_region_init_alias(isa_io, NULL, "isa-io", - get_system_io(), 0, LS_ISA_IO_SIZE); -- memory_region_init(isa_mem, NULL, "isa-mem", LS_ISA_MEM_SIZE); -+ memory_region_init(isa_mem, NULL, "isa-mem", PCIE_MEMORY_SIZE); - memory_region_add_subregion(get_system_memory(), lsmc->isa_io_base, isa_io); -- memory_region_add_subregion(get_system_memory(), LS_ISA_MEM_BASE, isa_mem); -+ memory_region_add_subregion(get_system_memory(), PCIE_MEMORY_BASE, isa_mem); - - if (!strcmp(lsmc->bridge_name, "ls7a")) { - /*Initialize the 7A IO interrupt subsystem*/ -@@ -1950,7 +1947,6 @@ static void ls3a5k_ls7a_machine_options(MachineClass *m) - m->alias = "loongson7a"; - m->is_default = 1; - lsmc->isa_io_base = LS3A5K_ISA_IO_BASE; -- lsmc->ht1lo_pcicfg_base = LS3A5K_HT1LO_PCICFG_BASE; - lsmc->pciecfg_base = LS_PCIECFG_BASE; - lsmc->ls7a_ioapic_reg_base = LS3A5K_LS7A_IOAPIC_REG_BASE; - lsmc->node_shift = 44; -diff --git a/hw/loongarch/ls7a_nb.c b/hw/loongarch/ls7a_nb.c -index 5a500fbd5..5a231e6f0 100644 ---- a/hw/loongarch/ls7a_nb.c -+++ b/hw/loongarch/ls7a_nb.c -@@ -108,7 +108,6 @@ static const VMStateDescription vmstate_ls7a_pcie = { - .fields = (VMStateField[]) { - VMSTATE_PCI_DEVICE(dev, LS7APCIState), - VMSTATE_STRUCT(pm, LS7APCIState, 0, vmstate_ls7a_pm, LS7APCIPMRegs), -- VMSTATE_UINT32_ARRAY(regs, LS7APCIState, LS7A_REGS), - VMSTATE_END_OF_LIST() - } - }; -@@ -153,47 +152,6 @@ static void ls7a_pcie_realize(PCIDevice *dev, Error **errp) - qemu_register_reset(ls7a_reset, s); - } - --static void pci_ls7a_config_write(void *opaque, hwaddr addr, -- uint64_t val, unsigned size) --{ -- hwaddr tmp_addr; -- tmp_addr = addr & 0xffffff; -- -- pci_data_write(opaque, tmp_addr, val, size); --} -- --static uint64_t pci_ls7a_config_read(void *opaque, -- hwaddr addr, unsigned size) --{ -- uint64_t val; -- hwaddr tmp_addr; -- -- tmp_addr = addr & 0xffffff; -- val = pci_data_read(opaque, tmp_addr, size); -- -- if (addr & 0x3c) { -- DPRINTF(TARGET_FMT_plx" val %lx\n", addr, val); -- } -- return val; --} -- --static const MemoryRegionOps pci_ls7a_config_ops = { -- .read = pci_ls7a_config_read, -- .write = pci_ls7a_config_write, -- /* Set to access 64bits data, because default to 32bits*/ -- .valid = { -- .min_access_size = 1, -- .max_access_size = 4, -- }, -- /* Set to access 64bits data, because default to 32bits*/ -- .impl = { -- .min_access_size = 1, -- .max_access_size = 4, -- }, -- .endianness = DEVICE_NATIVE_ENDIAN, -- --}; -- - static AddressSpace *ls7a_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) - { - return &address_space_memory; -@@ -205,12 +163,9 @@ static PCIBus *pci_ls7a_init(MachineState *machine, DeviceState *dev, - LoongarchMachineState *lsms = LoongarchMACHINE(machine); - LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); - PCIExpressHost *e; -- SysBusDevice *sysbus; -- MemoryRegion *iomem = g_new(MemoryRegion, 1); - PCIHostState *phb; - - e = PCIE_HOST_BRIDGE(dev); -- sysbus = SYS_BUS_DEVICE(e); - phb = PCI_HOST_BRIDGE(e); - phb->bus = pci_register_root_bus(dev, "pcie.0", pci_ls7a_set_irq, - pci_ls7a_map_irq, pic, -@@ -220,10 +175,6 @@ static PCIBus *pci_ls7a_init(MachineState *machine, DeviceState *dev, - DPRINTF("------ %d\n", __LINE__); - - pci_bus_set_route_irq_fn(phb->bus, ls7a_route_intx_pin_to_irq); -- memory_region_init_io(iomem, NULL, &pci_ls7a_config_ops, phb->bus, -- "ls7a_pci_conf", HT1LO_PCICFG_SIZE); -- sysbus_init_mmio(sysbus, iomem); -- sysbus_mmio_map(sysbus, 0, lsmc->ht1lo_pcicfg_base); - - return phb->bus; - } -diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h -index 81dcb78f4..b8f28e330 100644 ---- a/include/hw/loongarch/larch.h -+++ b/include/hw/loongarch/larch.h -@@ -64,7 +64,6 @@ typedef struct LoongarchMachineClass { - uint64_t ht_control_regs_base; - uint64_t hpet_mmio_addr; - uint64_t smbus_cfg_base; -- uint64_t ht1lo_pcicfg_base; - uint64_t pciecfg_base; - uint64_t ls7a_ioapic_reg_base; - uint32_t node_shift; -diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h -index fc78083be..63a070296 100644 ---- a/include/hw/loongarch/ls7a.h -+++ b/include/hw/loongarch/ls7a.h -@@ -39,44 +39,33 @@ - #define ACPI_IO_SIZE (LS7A_ACPI_IO_SIZE) - #define ACPI_SCI_IRQ (LS7A_SCI_IRQ) - --#define LS3A5K_ISA_IO_BASE 0x18000000UL --#define LS_ISA_MEM_BASE 0x40000000 --#define LS3A5K_HT1LO_PCICFG_BASE 0x1a000000 --#define HT1LO_PCICFG_SIZE 0x02000000 -+#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000 -+#define VIRT_PLATFORM_BUS_SIZE 0x02000000 -+#define VIRT_PLATFORM_BUS_NUM_IRQS 2 -+#define VIRT_PLATFORM_BUS_IRQ (LOONGARCH_PCH_IRQ_BASE + 5) -+ -+#define LS3A5K_ISA_IO_BASE 0x18000000UL - #define LS_BIOS_BASE 0x1c000000 - #define LS_BIOS_VAR_BASE 0x1c3a0000 --#define LS_BIOS_SIZE (4 * 1024 * 1024) -- --#define FW_CFG_ADDR 0x1e020000 --#define LS7A_REG_BASE 0x1FE00000 --#define LS7A_PCICONFIG_BASE (LS7A_REG_BASE + 0x30) --#define LS7A_PCICONFIG_SIZE (0x100) --#define LS7A_INTERNAL_REG_BASE (LS7A_REG_BASE + 0x100) --#define LS7A_INTERNAL_REG_SIZE (0xE0) --#define LS7A_REGS (0xE0 >> 2) --#define LS7A_UART_BASE 0x1fe001e0 --#define LS7A_UART_LEN 0x8 -- --#define LS_FDT_BASE 0x1c400000 --#define LS_FDT_SIZE 0x100000 -- --#define LS_PCIECFG_BASE 0x20000000 --#define LS_PCIECFG_SIZE 0x08000000 --#define MSI_ADDR_LOW 0x2FF00000 --#define MSI_ADDR_HI 0x0 -- -+#define LS_BIOS_SIZE (4 * 1024 * 1024) -+#define LS_FDT_BASE 0x1c400000 -+#define LS_FDT_SIZE 0x00100000 -+ -+#define FW_CFG_ADDR 0x1e020000 -+#define LS7A_REG_BASE 0x1FE00000 -+#define LS7A_UART_BASE 0x1fe001e0 -+#define LS7A_UART_LEN 0x8 - #define SMP_GIPI_MAILBOX 0x1f000000ULL --#define CORE0_STATUS_OFF 0x000 --#define CORE0_EN_OFF 0x004 --#define CORE0_SET_OFF 0x008 --#define CORE0_CLEAR_OFF 0x00c --#define CORE0_BUF_20 0x020 --#define CORE0_BUF_28 0x028 --#define CORE0_BUF_30 0x030 --#define CORE0_BUF_38 0x038 --#define CORE0_IPI_SEND 0x040 --#define CORE0_MAIL_SEND 0x048 -- -+#define CORE0_STATUS_OFF 0x000 -+#define CORE0_EN_OFF 0x004 -+#define CORE0_SET_OFF 0x008 -+#define CORE0_CLEAR_OFF 0x00c -+#define CORE0_BUF_20 0x020 -+#define CORE0_BUF_28 0x028 -+#define CORE0_BUF_30 0x030 -+#define CORE0_BUF_38 0x038 -+#define CORE0_IPI_SEND 0x040 -+#define CORE0_MAIL_SEND 0x048 - #define INT_ROUTER_REGS_BASE 0x1fe01400UL - #define INT_ROUTER_REGS_SIZE 0x100 - #define INT_ROUTER_REGS_SYS_INT0 0x00 -@@ -121,10 +110,13 @@ - #define INT_ROUTER_REGS_CORE2_INTISR 0x50 - #define INT_ROUTER_REGS_CORE3_INTISR 0x58 - --#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000 --#define VIRT_PLATFORM_BUS_SIZE 0x2000000 --#define VIRT_PLATFORM_BUS_NUM_IRQS 2 --#define VIRT_PLATFORM_BUS_IRQ 69 -+#define LS_PCIECFG_BASE 0x20000000 -+#define LS_PCIECFG_SIZE 0x08000000 -+#define MSI_ADDR_LOW 0x2FF00000 -+#define MSI_ADDR_HI 0x0 -+ -+#define PCIE_MEMORY_BASE 0x40000000 -+#define PCIE_MEMORY_SIZE 0x40000000 - - typedef struct LS7APCIState LS7APCIState; - typedef struct LS7APCIEHost { -@@ -136,7 +128,6 @@ struct LS7APCIState { - PCIDevice dev; - - LS7APCIEHost *pciehost; -- uint32_t regs[LS7A_REGS]; - - /* LS7A registers */ - MemoryRegion iomem; --- -2.43.5 - diff --git a/code-cleanup-for-loongarch-kvm.patch b/code-cleanup-for-loongarch-kvm.patch deleted file mode 100644 index e94f6de..0000000 --- a/code-cleanup-for-loongarch-kvm.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 4bf40ba9ed6f98e7082623927d1c0c9ec6090f12 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 07:04:10 -0400 -Subject: [PATCH 12/28] code cleanup for loongarch kvm. - -Signed-off-by: lixianglai ---- - linux-headers/asm-loongarch64/kvm.h | 10 +--------- - 1 file changed, 1 insertion(+), 9 deletions(-) - -diff --git a/linux-headers/asm-loongarch64/kvm.h b/linux-headers/asm-loongarch64/kvm.h -index a24375ee5..799af7594 100644 ---- a/linux-headers/asm-loongarch64/kvm.h -+++ b/linux-headers/asm-loongarch64/kvm.h -@@ -72,15 +72,7 @@ struct kvm_fpu { - * - * Register set = 0: GP registers from kvm_regs (see definitions below). - * -- * Register set = 1: CP0 registers. -- * bits[15..8] - COP0 register set. -- * -- * COP0 register set = 0: Main CP0 registers. -- * bits[7..3] - Register 'rd' index. -- * bits[2..0] - Register 'sel' index. -- * -- * COP0 register set = 1: MAARs. -- * bits[7..0] - MAAR index. -+ * Register set = 1: CSR registers. - * - * Register set = 2: KVM specific registers (see definitions below). - * --- -2.43.5 - diff --git a/fix-smbios-type4-info-for-numa-support.patch b/fix-smbios-type4-info-for-numa-support.patch deleted file mode 100644 index 3e5f0fb..0000000 --- a/fix-smbios-type4-info-for-numa-support.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 1565426c6bc04bffe941ad6d7ce819278da323e8 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 07:53:36 -0400 -Subject: [PATCH 20/28] fix smbios type4 info for numa support. - -Signed-off-by: lixianglai ---- - hw/loongarch/larch_3a.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -index 5e271f339..b1501e0ea 100644 ---- a/hw/loongarch/larch_3a.c -+++ b/hw/loongarch/larch_3a.c -@@ -1211,8 +1211,14 @@ static void loongarch_build_smbios(LoongarchMachineState *lsms) - uint8_t *smbios_tables, *smbios_anchor; - size_t smbios_tables_len, smbios_anchor_len; - const char *product = "QEMU Virtual Machine"; -- ms->smp.cores = 4; -+ int nb_numa_nodes, smp_cpus; - -+ smp_cpus = ms->smp.cpus; -+ nb_numa_nodes = ms->numa_state->num_nodes; -+ if (nb_numa_nodes == 0) { -+ nb_numa_nodes = 1; -+ } -+ ms->smp.cores = smp_cpus / nb_numa_nodes; - if (!lsms->fw_cfg) { - return; - } -@@ -2004,6 +2010,10 @@ static int64_t ls3a_get_default_cpu_node_id(const MachineState *ms, int idx) - { - int nb_numa_nodes = ms->numa_state->num_nodes; - int smp_cores = ms->smp.cores; -+ -+ if (nb_numa_nodes == 0) { -+ nb_numa_nodes = 1; -+ } - return idx / smp_cores % nb_numa_nodes; - } - --- -2.43.5 - diff --git a/fixup-can-t-find-cpu-type.patch b/fixup-can-t-find-cpu-type.patch deleted file mode 100644 index 3ffeaf4..0000000 --- a/fixup-can-t-find-cpu-type.patch +++ /dev/null @@ -1,34 +0,0 @@ -From a08da06ba1ca817465e894737dced362babc9f18 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 07:51:55 -0400 -Subject: [PATCH 19/28] fixup can't find cpu type. - -Signed-off-by: lixianglai ---- - hw/loongarch/larch_3a.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -index f83bd3750..5e271f339 100644 ---- a/hw/loongarch/larch_3a.c -+++ b/hw/loongarch/larch_3a.c -@@ -547,7 +547,15 @@ static char *get_host_cpu_model_name(void) - fprintf(stderr, "read err...\n"); - } - close(fd); -- buf_p = strstr(buf, "name"); -+ buf_p = strstr(buf, "Name"); -+ if (!buf_p) { -+ buf_p = strstr(buf, "name"); -+ } -+ if (!buf_p) { -+ fprintf(stderr, "Can't find cpu name\n"); -+ return 0; -+ } -+ - - while (*buf_p != ':') { - buf_p++; --- -2.43.5 - diff --git a/kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch b/kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch new file mode 100644 index 0000000..b8db080 --- /dev/null +++ b/kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch @@ -0,0 +1,36 @@ +From a707eff49800045d07afbcd8a74617c50b960151 Mon Sep 17 00:00:00 2001 +From: German Maglione +Date: Thu, 10 Oct 2024 13:23:25 +0200 +Subject: [PATCH] Fix thread-pool-size default value in the man page + +RH-Author: German Maglione +RH-MergeRequest: 417: Fix thread-pool-size default value in the man page +RH-Jira: RHEL-26197 +RH-Acked-by: Hanna Czenczek +RH-Acked-by: Jon Maloy +RH-Commit: [1/1] bdf22ed4600ac7f02a4b08c54f162b1f89c44a99 + +The current --thread-pool-size default value is 0, let's reflect it +in the man page. + +Signed-off-by: German Maglione +--- + docs/tools/virtiofsd.rst | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/docs/tools/virtiofsd.rst b/docs/tools/virtiofsd.rst +index 07ac0be551..fb3d59c449 100644 +--- a/docs/tools/virtiofsd.rst ++++ b/docs/tools/virtiofsd.rst +@@ -120,7 +120,7 @@ Options + .. option:: --thread-pool-size=NUM + + Restrict the number of worker threads per request queue to NUM. The default +- is 64. ++ is 0. + + .. option:: --cache=none|auto|always + +-- +2.45.2 + diff --git a/kvm-block-move-bdrv_qiov_is_aligned-to-file-posix.patch b/kvm-block-move-bdrv_qiov_is_aligned-to-file-posix.patch new file mode 100644 index 0000000..a8531b4 --- /dev/null +++ b/kvm-block-move-bdrv_qiov_is_aligned-to-file-posix.patch @@ -0,0 +1,104 @@ +From 636e32b4c570ddb20266b6672311174353644f0e Mon Sep 17 00:00:00 2001 +From: Keith Busch +Date: Thu, 29 Sep 2022 13:05:22 -0700 +Subject: [PATCH 1/2] block: move bdrv_qiov_is_aligned to file-posix + +RH-Author: Kevin Wolf +RH-MergeRequest: 411: block: Fix iov_len check in bdrv_qiov_is_aligned() +RH-Jira: RHEL-60553 +RH-Acked-by: Eric Blake +RH-Acked-by: Jon Maloy +RH-Commit: [1/2] 682c1b81b42959d9d91e0f68cd70e9753e53a279 + +There is only user of bdrv_qiov_is_aligned(), so move the alignment +function to there and make it static. + +Signed-off-by: Keith Busch +Message-Id: <20220929200523.3218710-2-kbusch@meta.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit a7c5f67a78569f8c275ea4ea9962e9c79b9d03cb) +Signed-off-by: Kevin Wolf +--- + block/file-posix.c | 20 ++++++++++++++++++++ + block/io.c | 20 -------------------- + include/block/block.h | 1 - + 3 files changed, 20 insertions(+), 21 deletions(-) + +diff --git a/block/file-posix.c b/block/file-posix.c +index b283093e5b..b404e1544f 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -2051,6 +2051,26 @@ static int coroutine_fn raw_thread_pool_submit(BlockDriverState *bs, + return thread_pool_submit_co(pool, func, arg); + } + ++/* ++ * Check if all memory in this vector is sector aligned. ++ */ ++static bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov) ++{ ++ int i; ++ size_t alignment = bdrv_min_mem_align(bs); ++ ++ for (i = 0; i < qiov->niov; i++) { ++ if ((uintptr_t) qiov->iov[i].iov_base % alignment) { ++ return false; ++ } ++ if (qiov->iov[i].iov_len % alignment) { ++ return false; ++ } ++ } ++ ++ return true; ++} ++ + static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset, + uint64_t bytes, QEMUIOVector *qiov, int type) + { +diff --git a/block/io.c b/block/io.c +index 8ae57728a6..639e171eff 100644 +--- a/block/io.c ++++ b/block/io.c +@@ -3375,26 +3375,6 @@ void *qemu_try_blockalign0(BlockDriverState *bs, size_t size) + return mem; + } + +-/* +- * Check if all memory in this vector is sector aligned. +- */ +-bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov) +-{ +- int i; +- size_t alignment = bdrv_min_mem_align(bs); +- +- for (i = 0; i < qiov->niov; i++) { +- if ((uintptr_t) qiov->iov[i].iov_base % alignment) { +- return false; +- } +- if (qiov->iov[i].iov_len % alignment) { +- return false; +- } +- } +- +- return true; +-} +- + void bdrv_io_plug(BlockDriverState *bs) + { + BdrvChild *child; +diff --git a/include/block/block.h b/include/block/block.h +index f885f113ef..09b374b496 100644 +--- a/include/block/block.h ++++ b/include/block/block.h +@@ -622,7 +622,6 @@ void *qemu_blockalign(BlockDriverState *bs, size_t size); + void *qemu_blockalign0(BlockDriverState *bs, size_t size); + void *qemu_try_blockalign(BlockDriverState *bs, size_t size); + void *qemu_try_blockalign0(BlockDriverState *bs, size_t size); +-bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov); + + void bdrv_enable_copy_on_read(BlockDriverState *bs); + void bdrv_disable_copy_on_read(BlockDriverState *bs); +-- +2.45.2 + diff --git a/kvm-block-use-the-request-length-for-iov-alignment.patch b/kvm-block-use-the-request-length-for-iov-alignment.patch new file mode 100644 index 0000000..13b31ca --- /dev/null +++ b/kvm-block-use-the-request-length-for-iov-alignment.patch @@ -0,0 +1,48 @@ +From 9009b674a01dc0cd92c319c87714b5aca6e639f8 Mon Sep 17 00:00:00 2001 +From: Keith Busch +Date: Thu, 29 Sep 2022 13:05:23 -0700 +Subject: [PATCH 2/2] block: use the request length for iov alignment + +RH-Author: Kevin Wolf +RH-MergeRequest: 411: block: Fix iov_len check in bdrv_qiov_is_aligned() +RH-Jira: RHEL-60553 +RH-Acked-by: Eric Blake +RH-Acked-by: Jon Maloy +RH-Commit: [2/2] 0e01d51cfb21ca43283626c2367e5c5d0d531736 + +An iov length needs to be aligned to the logical block size, which may +be larger than the memory alignment. + +Tested-by: Jens Axboe +Signed-off-by: Keith Busch +Message-Id: <20220929200523.3218710-3-kbusch@meta.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit 25474d90aa50bd32e0de395a33d8de42dd6f2aef) +Signed-off-by: Kevin Wolf +--- + block/file-posix.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/block/file-posix.c b/block/file-posix.c +index b404e1544f..b84c5725cc 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -2058,12 +2058,13 @@ static bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov) + { + int i; + size_t alignment = bdrv_min_mem_align(bs); ++ size_t len = bs->bl.request_alignment; + + for (i = 0; i < qiov->niov; i++) { + if ((uintptr_t) qiov->iov[i].iov_base % alignment) { + return false; + } +- if (qiov->iov[i].iov_len % alignment) { ++ if (qiov->iov[i].iov_len % len) { + return false; + } + } +-- +2.45.2 + diff --git a/kvm-csr-save-and-restore-optimization.patch b/kvm-csr-save-and-restore-optimization.patch deleted file mode 100644 index a5c3954..0000000 --- a/kvm-csr-save-and-restore-optimization.patch +++ /dev/null @@ -1,599 +0,0 @@ -From 2b5b79cc839c3b471724c263a1a5e35bf69c1bc9 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 07:25:52 -0400 -Subject: [PATCH 14/28] kvm csr save and restore optimization. - -Signed-off-by: lixianglai ---- - target/loongarch64/kvm.c | 547 +++++++++++---------------------------- - 1 file changed, 153 insertions(+), 394 deletions(-) - -diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c -index b5c655812..6885ec6c9 100644 ---- a/target/loongarch64/kvm.c -+++ b/target/loongarch64/kvm.c -@@ -95,19 +95,165 @@ int kvm_arch_irqchip_create(KVMState *s) - return 0; - } - -+static void kvm_csr_set_addr(uint64_t **addr, uint32_t index, uint64_t *p) -+{ -+ addr[index] = p; -+} -+ - int kvm_arch_init_vcpu(CPUState *cs) - { - LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ uint64_t **addr; -+ CPULOONGARCHState *env = &cpu->env; - int ret = 0; - - cpu->cpuStateEntry = qemu_add_vm_change_state_handler(kvm_loongarch_update_state, cs); -- cpu->kvm_csr_buf = g_malloc0(CSR_BUF_SIZE); -+ cpu->kvm_csr_buf = g_malloc0(CSR_BUF_SIZE + CSR_BUF_SIZE); -+ -+ addr = (void *)cpu->kvm_csr_buf + CSR_BUF_SIZE; -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_CRMD, &env->CSR_CRMD); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PRMD, &env->CSR_PRMD); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_EUEN, &env->CSR_EUEN); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_MISC, &env->CSR_MISC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ECFG, &env->CSR_ECFG); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ESTAT, &env->CSR_ESTAT); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERA, &env->CSR_ERA); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_BADV, &env->CSR_BADV); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_BADI, &env->CSR_BADI); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_EEPN, &env->CSR_EEPN); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBIDX, &env->CSR_TLBIDX); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBEHI, &env->CSR_TLBEHI); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBELO0, &env->CSR_TLBELO0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBELO1, &env->CSR_TLBELO1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_GTLBC, &env->CSR_GTLBC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TRGP, &env->CSR_TRGP); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ASID, &env->CSR_ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PGDL, &env->CSR_PGDL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PGDH, &env->CSR_PGDH); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PGD, &env->CSR_PGD); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PWCTL0, &env->CSR_PWCTL0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PWCTL1, &env->CSR_PWCTL1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_STLBPGSIZE, &env->CSR_STLBPGSIZE); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_RVACFG, &env->CSR_RVACFG); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_CPUID, &env->CSR_CPUID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PRCFG1, &env->CSR_PRCFG1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PRCFG2, &env->CSR_PRCFG2); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PRCFG3, &env->CSR_PRCFG3); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS0, &env->CSR_KS0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS1, &env->CSR_KS1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS2, &env->CSR_KS2); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS3, &env->CSR_KS3); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS4, &env->CSR_KS4); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS5, &env->CSR_KS5); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS6, &env->CSR_KS6); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS7, &env->CSR_KS7); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TMID, &env->CSR_TMID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_CNTC, &env->CSR_CNTC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TINTCLR, &env->CSR_TINTCLR); -+ -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_GSTAT, &env->CSR_GSTAT); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_GCFG, &env->CSR_GCFG); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_GINTC, &env->CSR_GINTC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_GCNTC, &env->CSR_GCNTC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_LLBCTL, &env->CSR_LLBCTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IMPCTL1, &env->CSR_IMPCTL1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IMPCTL2, &env->CSR_IMPCTL2); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_GNMI, &env->CSR_GNMI); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRENT, &env->CSR_TLBRENT); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRBADV, &env->CSR_TLBRBADV); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRERA, &env->CSR_TLBRERA); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRSAVE, &env->CSR_TLBRSAVE); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRELO0, &env->CSR_TLBRELO0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRELO1, &env->CSR_TLBRELO1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBREHI, &env->CSR_TLBREHI); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRPRMD, &env->CSR_TLBRPRMD); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRCTL, &env->CSR_ERRCTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRINFO, &env->CSR_ERRINFO); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRINFO1, &env->CSR_ERRINFO1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRENT, &env->CSR_ERRENT); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRERA, &env->CSR_ERRERA); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRSAVE, &env->CSR_ERRSAVE); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_CTAG, &env->CSR_CTAG); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DMWIN0, &env->CSR_DMWIN0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DMWIN1, &env->CSR_DMWIN1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DMWIN2, &env->CSR_DMWIN2); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DMWIN3, &env->CSR_DMWIN3); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCTRL0, &env->CSR_PERFCTRL0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCNTR0, &env->CSR_PERFCNTR0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCTRL1, &env->CSR_PERFCTRL1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCNTR1, &env->CSR_PERFCNTR1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCTRL2, &env->CSR_PERFCTRL2); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCNTR2, &env->CSR_PERFCNTR2); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCTRL3, &env->CSR_PERFCTRL3); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCNTR3, &env->CSR_PERFCNTR3); -+ -+ /* debug */ -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_MWPC, &env->CSR_MWPC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_MWPS, &env->CSR_MWPS); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB0ADDR, &env->CSR_DB0ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB0MASK, &env->CSR_DB0MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB0CTL, &env->CSR_DB0CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB0ASID, &env->CSR_DB0ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB1ADDR, &env->CSR_DB1ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB1MASK, &env->CSR_DB1MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB1CTL, &env->CSR_DB1CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB1ASID, &env->CSR_DB1ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB2ADDR, &env->CSR_DB2ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB2MASK, &env->CSR_DB2MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB2CTL, &env->CSR_DB2CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB2ASID, &env->CSR_DB2ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB3ADDR, &env->CSR_DB3ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB3MASK, &env->CSR_DB3MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB3CTL, &env->CSR_DB3CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB3ASID, &env->CSR_DB3ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_FWPC, &env->CSR_FWPC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_FWPS, &env->CSR_FWPS); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB0ADDR, &env->CSR_IB0ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB0MASK, &env->CSR_IB0MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB0CTL, &env->CSR_IB0CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB0ASID, &env->CSR_IB0ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB1ADDR, &env->CSR_IB1ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB1MASK, &env->CSR_IB1MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB1CTL, &env->CSR_IB1CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB1ASID, &env->CSR_IB1ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB2ADDR, &env->CSR_IB2ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB2MASK, &env->CSR_IB2MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB2CTL, &env->CSR_IB2CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB2ASID, &env->CSR_IB2ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB3ADDR, &env->CSR_IB3ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB3MASK, &env->CSR_IB3MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB3CTL, &env->CSR_IB3CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB3ASID, &env->CSR_IB3ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB4ADDR, &env->CSR_IB4ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB4MASK, &env->CSR_IB4MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB4CTL, &env->CSR_IB4CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB4ASID, &env->CSR_IB4ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB5ADDR, &env->CSR_IB5ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB5MASK, &env->CSR_IB5MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB5CTL, &env->CSR_IB5CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB5ASID, &env->CSR_IB5ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB6ADDR, &env->CSR_IB6ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB6MASK, &env->CSR_IB6MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB6CTL, &env->CSR_IB6CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB6ASID, &env->CSR_IB6ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB7ADDR, &env->CSR_IB7ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB7MASK, &env->CSR_IB7MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB7CTL, &env->CSR_IB7CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB7ASID, &env->CSR_IB7ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DEBUG, &env->CSR_DEBUG); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DERA, &env->CSR_DERA); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DESAVE, &env->CSR_DESAVE); -+ - DPRINTF("%s\n", __func__); - return ret; - } - - int kvm_arch_destroy_vcpu(CPUState *cs) - { -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ -+ g_free(cpu->kvm_csr_buf); -+ cpu->kvm_csr_buf = NULL; - return 0; - } - -@@ -936,8 +1082,10 @@ static int kvm_loongarch_get_csr_registers(CPUState *cs) - CPULOONGARCHState *env = &cpu->env; - int ret = 0, i; - struct kvm_csr_entry *csrs = cpu->kvm_csr_buf->entries; -+ uint64_t **addr; - - kvm_csr_buf_reset(cpu); -+ addr = (void *)cpu->kvm_csr_buf + CSR_BUF_SIZE; - - kvm_csr_entry_add(cpu, LOONGARCH_CSR_CRMD, 0); - kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRMD, 0); -@@ -1082,399 +1230,10 @@ static int kvm_loongarch_get_csr_registers(CPUState *cs) - - for (i = 0; i < ret; i++) { - uint32_t index = csrs[i].index; -- -- switch (index) { -- case LOONGARCH_CSR_CRMD: -- env->CSR_CRMD = csrs[i].data; -- break; -- case LOONGARCH_CSR_PRMD: -- env->CSR_PRMD = csrs[i].data; -- break; -- case LOONGARCH_CSR_EUEN: -- env->CSR_EUEN = csrs[i].data; -- break; -- case LOONGARCH_CSR_MISC: -- env->CSR_MISC = csrs[i].data; -- break; -- case LOONGARCH_CSR_ECFG: -- env->CSR_ECFG = csrs[i].data; -- break; -- case LOONGARCH_CSR_ESTAT: -- env->CSR_ESTAT = csrs[i].data; -- break; -- case LOONGARCH_CSR_ERA: -- env->CSR_ERA = csrs[i].data; -- break; -- case LOONGARCH_CSR_BADV: -- env->CSR_BADV = csrs[i].data; -- break; -- case LOONGARCH_CSR_BADI: -- env->CSR_BADI = csrs[i].data; -- break; -- case LOONGARCH_CSR_EEPN: -- env->CSR_EEPN = csrs[i].data; -- break; -- case LOONGARCH_CSR_TLBIDX: -- env->CSR_TLBIDX = csrs[i].data; -- break; -- case LOONGARCH_CSR_TLBEHI: -- env->CSR_TLBEHI = csrs[i].data; -- break; -- case LOONGARCH_CSR_TLBELO0: -- env->CSR_TLBELO0 = csrs[i].data; -- break; -- case LOONGARCH_CSR_TLBELO1: -- env->CSR_TLBELO1 = csrs[i].data; -- break; -- case LOONGARCH_CSR_GTLBC: -- env->CSR_GTLBC = csrs[i].data; -- break; -- case LOONGARCH_CSR_TRGP: -- env->CSR_TRGP = csrs[i].data; -- break; -- case LOONGARCH_CSR_ASID: -- env->CSR_ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_PGDL: -- env->CSR_PGDL = csrs[i].data; -- break; -- case LOONGARCH_CSR_PGDH: -- env->CSR_PGDH = csrs[i].data; -- break; -- case LOONGARCH_CSR_PGD: -- env->CSR_PGD = csrs[i].data; -- break; -- case LOONGARCH_CSR_PWCTL0: -- env->CSR_PWCTL0 = csrs[i].data; -- break; -- case LOONGARCH_CSR_PWCTL1: -- env->CSR_PWCTL1 = csrs[i].data; -- break; -- case LOONGARCH_CSR_STLBPGSIZE: -- env->CSR_STLBPGSIZE = csrs[i].data; -- break; -- case LOONGARCH_CSR_RVACFG: -- env->CSR_RVACFG = csrs[i].data; -- break; -- case LOONGARCH_CSR_CPUID: -- env->CSR_CPUID = csrs[i].data; -- break; -- case LOONGARCH_CSR_PRCFG1: -- env->CSR_PRCFG1 = csrs[i].data; -- break; -- case LOONGARCH_CSR_PRCFG2: -- env->CSR_PRCFG2 = csrs[i].data; -- break; -- case LOONGARCH_CSR_PRCFG3: -- env->CSR_PRCFG3 = csrs[i].data; -- break; -- case LOONGARCH_CSR_KS0: -- env->CSR_KS0 = csrs[i].data; -- break; -- case LOONGARCH_CSR_KS1: -- env->CSR_KS1 = csrs[i].data; -- break; -- case LOONGARCH_CSR_KS2: -- env->CSR_KS2 = csrs[i].data; -- break; -- case LOONGARCH_CSR_KS3: -- env->CSR_KS3 = csrs[i].data; -- break; -- case LOONGARCH_CSR_KS4: -- env->CSR_KS4 = csrs[i].data; -- break; -- case LOONGARCH_CSR_KS5: -- env->CSR_KS5 = csrs[i].data; -- break; -- case LOONGARCH_CSR_KS6: -- env->CSR_KS6 = csrs[i].data; -- break; -- case LOONGARCH_CSR_KS7: -- env->CSR_KS7 = csrs[i].data; -- break; -- -- case LOONGARCH_CSR_TMID: -- env->CSR_TMID = csrs[i].data; -- break; -- case LOONGARCH_CSR_CNTC: -- env->CSR_CNTC = csrs[i].data; -- break; -- case LOONGARCH_CSR_TINTCLR: -- env->CSR_TINTCLR = csrs[i].data; -- break; -- case LOONGARCH_CSR_GSTAT: -- env->CSR_GSTAT = csrs[i].data; -- break; -- case LOONGARCH_CSR_GCFG: -- env->CSR_GCFG = csrs[i].data; -- break; -- case LOONGARCH_CSR_GINTC: -- env->CSR_GINTC = csrs[i].data; -- break; -- case LOONGARCH_CSR_GCNTC: -- env->CSR_GCNTC = csrs[i].data; -- break; -- case LOONGARCH_CSR_LLBCTL: -- env->CSR_LLBCTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_IMPCTL1: -- env->CSR_IMPCTL1 = csrs[i].data; -- break; -- case LOONGARCH_CSR_IMPCTL2: -- env->CSR_IMPCTL2 = csrs[i].data; -- break; -- case LOONGARCH_CSR_GNMI: -- env->CSR_GNMI = csrs[i].data; -- break; -- case LOONGARCH_CSR_TLBRENT: -- env->CSR_TLBRENT = csrs[i].data; -- break; -- case LOONGARCH_CSR_TLBRBADV: -- env->CSR_TLBRBADV = csrs[i].data; -- break; -- case LOONGARCH_CSR_TLBRERA: -- env->CSR_TLBRERA = csrs[i].data; -- break; -- case LOONGARCH_CSR_TLBRSAVE: -- env->CSR_TLBRSAVE = csrs[i].data; -- break; -- case LOONGARCH_CSR_TLBRELO0: -- env->CSR_TLBRELO0 = csrs[i].data; -- break; -- case LOONGARCH_CSR_TLBRELO1: -- env->CSR_TLBRELO1 = csrs[i].data; -- break; -- case LOONGARCH_CSR_TLBREHI: -- env->CSR_TLBREHI = csrs[i].data; -- break; -- case LOONGARCH_CSR_TLBRPRMD: -- env->CSR_TLBRPRMD = csrs[i].data; -- break; -- case LOONGARCH_CSR_ERRCTL: -- env->CSR_ERRCTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_ERRINFO: -- env->CSR_ERRINFO = csrs[i].data; -- break; -- case LOONGARCH_CSR_ERRINFO1: -- env->CSR_ERRINFO1 = csrs[i].data; -- break; -- case LOONGARCH_CSR_ERRENT: -- env->CSR_ERRENT = csrs[i].data; -- break; -- case LOONGARCH_CSR_ERRERA: -- env->CSR_ERRERA = csrs[i].data; -- break; -- case LOONGARCH_CSR_ERRSAVE: -- env->CSR_ERRSAVE = csrs[i].data; -- break; -- case LOONGARCH_CSR_CTAG: -- env->CSR_CTAG = csrs[i].data; -- break; -- case LOONGARCH_CSR_DMWIN0: -- env->CSR_DMWIN0 = csrs[i].data; -- break; -- case LOONGARCH_CSR_DMWIN1: -- env->CSR_DMWIN1 = csrs[i].data; -- break; -- case LOONGARCH_CSR_DMWIN2: -- env->CSR_DMWIN2 = csrs[i].data; -- break; -- case LOONGARCH_CSR_DMWIN3: -- env->CSR_DMWIN3 = csrs[i].data; -- break; -- case LOONGARCH_CSR_PERFCTRL0: -- env->CSR_PERFCTRL0 = csrs[i].data; -- break; -- case LOONGARCH_CSR_PERFCNTR0: -- env->CSR_PERFCNTR0 = csrs[i].data; -- break; -- case LOONGARCH_CSR_PERFCTRL1: -- env->CSR_PERFCTRL1 = csrs[i].data; -- break; -- case LOONGARCH_CSR_PERFCNTR1: -- env->CSR_PERFCNTR1 = csrs[i].data; -- break; -- case LOONGARCH_CSR_PERFCTRL2: -- env->CSR_PERFCTRL2 = csrs[i].data; -- break; -- case LOONGARCH_CSR_PERFCNTR2: -- env->CSR_PERFCNTR2 = csrs[i].data; -- break; -- case LOONGARCH_CSR_PERFCTRL3: -- env->CSR_PERFCTRL3 = csrs[i].data; -- break; -- case LOONGARCH_CSR_PERFCNTR3: -- env->CSR_PERFCNTR3 = csrs[i].data; -- break; -- -- case LOONGARCH_CSR_MWPC: -- env->CSR_MWPC = csrs[i].data; -- break; -- case LOONGARCH_CSR_MWPS: -- env->CSR_MWPS = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB0ADDR: -- env->CSR_DB0ADDR = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB0MASK: -- env->CSR_DB0MASK = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB0CTL: -- env->CSR_DB0CTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB0ASID: -- env->CSR_DB0ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB1ADDR: -- env->CSR_DB1ADDR = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB1MASK: -- env->CSR_DB1MASK = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB1CTL: -- env->CSR_DB1CTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB1ASID: -- env->CSR_DB1ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB2ADDR: -- env->CSR_DB2ADDR = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB2MASK: -- env->CSR_DB2MASK = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB2CTL: -- env->CSR_DB2CTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB2ASID: -- env->CSR_DB2ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB3ADDR: -- env->CSR_DB3ADDR = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB3MASK: -- env->CSR_DB3MASK = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB3CTL: -- env->CSR_DB3CTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_DB3ASID: -- env->CSR_DB3ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_FWPC: -- env->CSR_FWPC = csrs[i].data; -- break; -- case LOONGARCH_CSR_FWPS: -- env->CSR_FWPS = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB0ADDR: -- env->CSR_IB0ADDR = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB0MASK: -- env->CSR_IB0MASK = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB0CTL: -- env->CSR_IB0CTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB0ASID: -- env->CSR_IB0ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB1ADDR: -- env->CSR_IB1ADDR = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB1MASK: -- env->CSR_IB1MASK = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB1CTL: -- env->CSR_IB1CTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB1ASID: -- env->CSR_IB1ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB2ADDR: -- env->CSR_IB2ADDR = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB2MASK: -- env->CSR_IB2MASK = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB2CTL: -- env->CSR_IB2CTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB2ASID: -- env->CSR_IB2ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB3ADDR: -- env->CSR_IB3ADDR = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB3MASK: -- env->CSR_IB3MASK = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB3CTL: -- env->CSR_IB3CTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB3ASID: -- env->CSR_IB3ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB4ADDR: -- env->CSR_IB4ADDR = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB4MASK: -- env->CSR_IB4MASK = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB4CTL: -- env->CSR_IB4CTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB4ASID: -- env->CSR_IB4ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB5ADDR: -- env->CSR_IB5ADDR = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB5MASK: -- env->CSR_IB5MASK = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB5CTL: -- env->CSR_IB5CTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB5ASID: -- env->CSR_IB5ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB6ADDR: -- env->CSR_IB6ADDR = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB6MASK: -- env->CSR_IB6MASK = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB6CTL: -- env->CSR_IB6CTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB6ASID: -- env->CSR_IB6ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB7ADDR: -- env->CSR_IB7ADDR = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB7MASK: -- env->CSR_IB7MASK = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB7CTL: -- env->CSR_IB7CTL = csrs[i].data; -- break; -- case LOONGARCH_CSR_IB7ASID: -- env->CSR_IB7ASID = csrs[i].data; -- break; -- case LOONGARCH_CSR_DEBUG: -- env->CSR_DEBUG = csrs[i].data; -- break; -- case LOONGARCH_CSR_DERA: -- env->CSR_DERA = csrs[i].data; -- break; -- case LOONGARCH_CSR_DESAVE: -- env->CSR_DESAVE = csrs[i].data; -- break; -- default: -- break; -+ if (addr[index]) { -+ *addr[index] = csrs[i].data; -+ } else { -+ printf("Failed to get addr CSR 0x%"PRIx32"\n", i); - } - } - --- -2.43.5 - diff --git a/kvm-virtiofsd-Adjust-limit-for-minor-version.patch b/kvm-virtiofsd-Adjust-limit-for-minor-version.patch deleted file mode 100644 index 30ec553..0000000 --- a/kvm-virtiofsd-Adjust-limit-for-minor-version.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 3b7200134925fcf5ae99b5c3b34465456d3bc002 Mon Sep 17 00:00:00 2001 -From: Jacob Wang -Date: Mon, 2 Aug 2021 01:16:05 +0800 -Subject: [PATCH 1/1] virtiofsd: Adjust limit for minor version - -Upstream virtiofsd only supports fuse >= 7.31 -(https://github.com/qemu/qemu/commit/72c42e2d65510e073cf78fdc924d121c77fa0080), -while Cloud Kernel has fuse version 7.27, which causes virtiofs fails to run -due to version mismatch. This limitation is unnecessary in Cloud Kernel because -we have already backported mandatory fuse patches to support virtofs -frontend in Kernel. Hence, adjust the minor version limit to 7.27 to -suppress the limitation. - -Note that current fuse implementation in Cloud Kernel might lack of some -certain capabilities in fuse 7.28 ~ 7.31, which may cause unexpected results, -this patch is merely a workaround to enable virtiofs in guest kernel side and -further action is ongoing to make sure fuse APIs in both sides are 100% -compatible. - -Signed-off-by: Jacob Wang -Acked-by: Caspar Zhang ---- - tools/virtiofsd/fuse_lowlevel.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c -index 2dd36ec..2bb4318 100644 ---- a/tools/virtiofsd/fuse_lowlevel.c -+++ b/tools/virtiofsd/fuse_lowlevel.c -@@ -1917,7 +1917,7 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, - outarg.major = FUSE_KERNEL_VERSION; - outarg.minor = FUSE_KERNEL_MINOR_VERSION; - -- if (arg->major < 7 || (arg->major == 7 && arg->minor < 31)) { -+ if (arg->major < 7 || (arg->major == 7 && arg->minor < 27)) { - fuse_log(FUSE_LOG_ERR, "fuse: unsupported protocol version: %u.%u\n", - arg->major, arg->minor); - fuse_reply_err(req, EPROTO); --- -1.8.3.1 - diff --git a/loongarch_bios.bin b/loongarch_bios.bin deleted file mode 100644 index d6330c6f0532effe458726efa18222166a444839..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4190208 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 z5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X z009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH z0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI z5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X z009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH z0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI z5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X z009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH z0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI z5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X z009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH z0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI z5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X z009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH z0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI z5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X z009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH z0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI z5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X z009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH z0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI z5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X z`2U#z_Md*7CPPBRgBY&F3kKfweaqd8Vf_D;xS?=eX>XShQ^Lr`jW7(KmjFFX@z1~h z`SqXK)^e9IE)3h4kqjxCNm7yzP##|!e!MJ2g-YYfM(r>^y_ZC-5^`z!(eaW`k!iW4 zn12}QhD{hLew_B@MJiDpnPlrBmrv0IU9=b;W`Neiqwo;?6LBBL+oAMIK3s3~?$Fr- zov+MeQ{u%W@2uAicnjU$@qBWQr|fOjy(cmZeqSx4zfPP>7rQ%{Wue2e$}?q#D<;9$6QD44%E;YI*yY&?s+%! zmekjb*q1v`|E9^J@i0b#B+eV~mA6Gt)p62CEvD9JtF2h(~wXD+Z&uT>ja(8V^FvpBD4CM#f{oeVXt(;Ig)H(melkS;mkaErLll|v}7QVGK z`Y23etgT1ST@{`s7V4VvqcW6{w0$FW(Y3tlyYMjY@R!ZIeXnmf#HEyV{y5K}i$AF0 zo9nWDQ1T9uA9OO8rPC+A%C0>fGn6@Ju;s+*RGSwzDv24o%hy@R&E=}51-Wa! zJ$(10;1ZSeu93ZjZK@@G^l?SMp$cLd{N^|Jg7=+uyyfKHu0ltT)g8I&@BQGuQ0liS z*?irrg=WAZpdqPdyK@%?r5G0_NVVV)EDFMk|#S9{h#WG$8{b%!m| zs1EC*QT#=zXi(x+9iR42#qd7GB~{~{BLX+e&yUy-pRwb=QqbeSvRjgIg!ac)=5SQ@ z8sCxclyl_5^kR+!w_B-MIaAi&RVauR$K_248|&uvERtr0=Zg_Pc|EB7X6S(^>)LfK zsTqb@SL_QJG*AV<}`zeW1 zModhe&UL-bThd0{q2oaFMb@+7g_Prh&o%|aFS0IfIPo#3(Gb>7;+N7rlq-+Hce8Nf zn$LZo+x=EzXm>PQ{gGxG{a~SL`FF)Ml8i?;iZrhuFC=)E7c9GcmNaN(^=^jM`XG7Y zlY-j*8rlv{63H_w?L@y+zL&YYtJUDs4CNi$?^`fZ*3QgX^us9l<_oi(S;3{^2*u87 zjqk>ei<5<1msNy&Zmk}^Dt9#V%gWqJ*RO1kZ%oESqZ26JI+_H9kuT;{aueo*##X>*q> z@_r9zn~zB=&m8tKoTz-?LbJI!Nbf24=uLGMk)+VTHM@zIQQ@b4#}RzBJ5B5V z)!_N$BcGFW%dZX@-T6vBmoY;U5xMd@);4*e^B}q5=C5ADvwS;my{Tz;*czA!*L6oJ z?1UTz^n`9Ssj})P6BXL-wL9@{d5!&WbGBkH?po+Dp$TMjmo0iCxc2(EN)Hh?vo}xW zdHoZjYrTWxO>Hv7JIYrQwxtad4$4aY>ivYTqqjdYUGs@bp8dm=2l}t}ePV3QTB+fe zU7pX`7iUiq*7MAiB5_yPevu${ru|1uxxQnfaO%d|FMpXpSy3snru$E?k8QO6BB%Xb zsSrj#b7D?^iRpyty}r$z!`B=)Y+CTU?eLGNJfsV$Gd?D>$~AWT{r*?Ur91kHTv=@2 z&hl!ivilG2{}z$P`N&XRq0O|~_2^r+1`54{Tn~1swGx6T56#vePH7I&x+X&<{JCkc zU@ktl`lMy%{+XOjUytiIx-F~T57gYocc?mCF%ssdMZ)Rfe*TsxsfQKUn|DRG4NM-9 zm%cg{wc%p(>1|dzS9QroMsRfLNtu}V5AVuP*9inmk@gVGv^*LpQC8(Y#4{5=;k9yUh%ELAW3%*BbAg%l zbsp;GMK`^ERqK~W#l;yoo__S)&Efo|Bi!lp@EAa1;fZRAIJP#+#K-xi5{kte~)8|tHeipg@WN4DAa z$Yoc`)%_|Gm6wK1+5+m%A7y7*Qu>^hy7KtNQGA_?FU8C1$}%En^@e{_C2uKa8MP_j zd#+L+qZTnjbWe_>n0NkueJ@;?*Cv?5~s_^hf{npP7b8`Vh5>UfA6{-pSS)k zt)4seg#GX9_3qBgKA7ywRn>g6;Ja4}if&EWrO*+w=`kLD_g0VlvgAFtz`*5XJ+VtM z7a2KnSY~=Ec@kr0-<`T@DYjbq>MV#LMEoM79v8SGOlf+%B;cTiI zU-lwR|8XO?NRhYioj<(2#=E$Vr+EL1!s*}oghc6Q#2f`ox!PR<$O4nBOEWP+A}vnu zI=%MRyopm>q(;3zq3R@wGQ4N!iDN}nJ>KU7@~%= zBmDxM_7rX?NX^(^?>kCLKy^{%WVTiE1v9n=LlK`L{?_Aj++Pw)6K92LRT|nlBvl7U zzj5-L8t`e^lz6=A50>Y9c^yBonH*o! z^^=HHy3S&eNCYqS_(emd;?9h9zGS~)l8`F1Y@rJ+GxdJby9O1fl`O0(I;%@>EOg81 zhe`x%D<3;cIJ2&f?`VH)omTzg^VN5nyMb75aem^@R@zq6v5H$aR(-YOKNIT?2lj0#g3&3^%0xtJIn=- z{he-xE=Vttu)Fb7vV@ByMwq`BcNF4PZjWR<9{up0aUR|J71ncnHGQl;*U4&MZ#3%# z%rxHaZ`S>~X70IWyrK|3u}#3!kbRgs;!w4LNQtsp7W33+k!XV8qoE!JAvqMuPo@L? z%>wTnI$?W@<1|$phk)8}pn4W%l=t=MNq*8EBTb=K_%Grk@VS#Fw^g5T#D2T+)O9m+ z)7-ndcW!q2{GmfiHCDH5=vi}aN}ZN=EqCQBIb(LUqp|gsM9e_S_c|p}@i!g#A<@bGo5=!4m6Y;x`LTvP}4M++No8Ss%(2`Wwga6W{etF!O;=)FuqaW>9h72;DzlUp88l`IPo0sz{6kF3=TJMcI$uMR&~(rUwmSF(Y{zeQATJu6=uKzw1a2t{1sfJ@YYdm|2NEX94eMVJ*-D<`c$Ig? zaqt*pMBXiy6Ai6(x{niM9rcTyfAjg{htH|xTF}@~=3N%UhDS;iE;zmW_&}iAQYgU8 z9pBu;KE}gb)%8o9lI-TSlHTJw`#Je$S%L;BJ@i8wf{P|oU%X}1*`ShG+q!v8p>nZ^ z`Ai<0@%Z`5;9Tn?l9X(})S}&;NBQ_N2CPO0s`(0L0v^3-mZ(gScut^v?_u)Y{?&bW zzm9Ufqf&XO^ex88_bY8SkKMi{`&`4!K788Sit0Bs2{aPEx>-z&J98EBk)1V;<~<)Q z$3oL@A38n0_)))prdB|GeG|_ki!PahMLCfn*kO`b|JYDIfxhzX_r5od-t)8*@-*gr zQvN*Rwa|I3#qUGG+L{-fIFz@oZt{?*5*SkR5UO>pH~&1gaaB_-!}7)1iW>qE!V*l6 z2+XbMB9bD04YwQ0Uh`!k;G{6SlEcoz>*m9G|K4fV-U5w*Td(}aH19kY@qc{3p<7tn z`|R8{|NeQ3*B`fERk(hbx|8#`&hM0Q7%|5!zKuEi3rmaQPAPE`w56o>?<2}S)DQeR zeq-&4WRB4i##BOogv(j>THRu^Z?Dh(lf5m{GN+jjJ{Ms+a5L35ojod(sjPlkpzT*o z$d!&FwE}H>!Ed#9FNt`OtJrl6n(&!>V{;s(Z{-8zhnYLCb>QDQ9m=6UywhT|T+Wnq zu`K7USST_5=+n7Y#zF>@leD+zra}&S&x!hcyLMaGTjIHU>!}Q)XX35=U&LGH`94eV z-4nc7sh9Fmok9M>VfoB{r3ORC1MG1$EosMpefi!~rDxVK9xI~c{OJ9a`+>cq%)H{!+1C%8{% z55Ja)pFGmVg#BLg{6ds!&%mS1BT`f!PR%MqdR%bZOwNm8bL2W_%>^d^~vI~{6E&Cpf zX@b8HRP1`OEm41$$-^@4Nn;#yM^Bq}SW*kY+lkLnAVs zH;y^Vd5!mPePP(XKtxpDaBMeO$sE7+8%Co1wewqitakGAYgZ)X4+tEz3sd&!OmIBd z&qCYiLHFQ|w6H>61qt&hS&v+y`_UZzRnOhB>ng9th9zHew|TvVVPu;>{LAkMu@|1d z(bo3F%SyxfPUb<=j?{q@<*w^~Rz(l3GgY4Juu60su5;Tu7iTMOBon#pYA59t>6}5O zdSL!myy?DmHP@*qaRWE{ci+ZF>)S&I>k@LmVr$QcyDUyTHs5`D)tP=!!`hztLgVd?&cp2`2v`k?Oi*MC=tv-h`M4oHrON_bI=%+${%q&U2`^9eQ4r!I~5_wd7 z*0%bW5BP<#*QAD47KoFrYU287Ic8s2C|g)GCr&PSaFL6**p#%&5BTlm-l8r$wds6o zOecIxK4eN$u0!EPaT+g!RX>3v$m(S3iATF#xisFj@x-|NB|({a*h zH}mL=oZOaZLPM8+M9zy_oCkA`Pt~!>-0#|!Jn%3|U6K8Dm$Et0&?7;Il#6*T$(r=L zEM|q$tc6iszLid${7#g5Wx-EW-hYzvCI9^9rzF)l$yIyd%voRhL!XULEbQ`79uZJ@ zc5R&^Az(Av`?P@-rJwkkm-yhQ9`m^q!^y=7jAO*D`T3LI-22bH6pdBH`>DHG61gt! z{e@reke*WCNk%3)-je;w8QVKbsa4PDSN)oNXu28zOW4^ z-2z5&8s*tbZz7h83~hK+Tb7?k+ecVg3|<%Nq58?^-c6Bk{tZ9O<> zZgWp!UQ1LTlWe#wyc+$JI#{H*G?LEY3HMOb@n&VEBMhGvFX|8pOH_p8lhV&WqA`o! zI$?jQ=9f{JPe)!vT+PvUI^7Gzp>}mx;fdGZgjXBCa`q|XYrQL(<-VIdycXLzn|DZZ zd$LO2`x&3TN)X3y*;Om0wo6AR=1&;r;xik@eoxN*j(sGdv_94D>rC&pbR2(OaN?^+_Jl5BF%FC z=EV~+E0U?{IW#r1DyMr1KlcmPy?(*JXzNUM-=pE3=7ZD|rlO3_+H*?g2^`Gr)5rLK zAG5k(c5m#ZM*3;XQhlmtx`AqYWMUL zak7zdJ*Y)~_f=@y>#{LrI0 zde;@gytyyQmr2i$hB%y64)}E=m90T@KzyYv+@V<#i{?5qAx~9gJQDz*^^s9|dWuZd9w@ZF zNpK%;K1xQQt5)oilh?cNf$FaEpDF!pG>=NeU#ZAob`ywKGEP_a^m%;w-a{ch3nI_n zPQkPrO=YL}=?lcuX=cm!va=d{CLZ%P>ixW5a-^5YxJY#1Y{J}W{5RnPPl+t_4m@Re zDe~M$(j@&O^~o5HDF4IM^}`e^6L?2m5|*CItUZbqIAm09A9G)eU6=Tq{3Z3k*1oBe zn>43oepOI%)6Ske({$$iljFAx&dAuEDRrCv^jU-^Y<4C3z)h2HYJ=lf?@!t_Ui4s) zG{hz!XE9ZVdKRD4Tzt|0O)aPSu(aEfaK&A+fjjs1d|w$VmlBdNJeyNukn)_zCp0#V zyX-_yF47u9bsZ!B^e|I^E>glkrjPNqJ}Gyv#huOHQY2QgcvNf377uO+Fo=tpX`W|_ zj1~|!`Q6H&CV}^~H(rRTvocX!qpRb)O_a@u4BMqJ^DUP|>hqyW24;5LCp^DB{igD! zs$Duz)m+ib+;W+FSfj`y4*S&htX6sEw*M=hJ0`sY8rq^#R)Sd{bJJ=M^?tW|e_|mkww872PE2H!?zwVa z!R*mXlAa%eD&qL>yy#rzuS99+W+v%6?srwkB<3qCHYR_CsYsvZ|Ez}ZV(_L&jzwly zN~k>QBD>^h13%aJeR{$1ON{w)C$CI+J`mlSOg(DstyN4YHE3jch2>$v)Q=F~vDGoI z&?0%sA@iO3iqBGv`bT4r1-|<#K_OMbOIK8=eAvn58EN$5(_&iQ!+zr`4qr!?P936O zIIiaZ`kLtFV^^kcUl)4(cyE*87uQi4RF{NV_umR7 zw&hs56d#?6vCvM5p~vfwUBPFXw~{$L`+!HWK3l5s?01{FrY~BY7TszQEwYgeL{Flbto-qw(11PZ8zVU}%T6`QpZnz==GF>n zy41F3>4|b2z+~9;ce+8jVQkvx}U9c)ACjl&ChRPH7E7I`8}Cr z_Y~QF$>}v>kSEmEcWoi<+LbnfYbAWXWbO$!9`_z_Gf#Y*+2FVJf;rk&$?x}>-E7wI zN|TjZI^Bh%@QvnBGs=VbLL^P*OTa zw6WrLQ;xgZ_C4Kbd|Y8s66fR;#cfe3CHmo&8RE~1>N5(_-ocDK2iqNPt4O}p`8?G_ za)oIqXO}4;>3wgN_4m97Ld#5+8<%*kN||o>j^#%foHY8tOWtF4gG@%dWiZ^C{_> z`?NplV~;X1L9x+S7CMT>n)F5s{gj9O1uCN+_Y%IGTL|Fke&E0O{ve&QR%D()&G`9` z`7V5QHS7CHoS)*2rwLWe{wAiVv=U7pb$m;dRLNV`ai2Fcx2f`X;|I~W^xV6I)-=91 zn?|e}Rh+Llgm)p(;4NIv}3*Q2NPCq`Y);1Ss(w7%Rz}uO6v*W}Q>H@Fic3xR# z;`zI~hv*qFzxHPX7hf1uGpq4?9eGB)m-zltm+1z1YxOg7!GTA|cl(@=5S}*icPBl_ zVz-UQOM!jeD%O*@bD`FwKnXANhYfA|Sir26yrpf=$l}%#`Mb|D6#o3%c6$jIb6dSe zZ+8DoPZNsO<=ZdD934!)=zfNB9!geZh9euO)uw{++#B;l^?jP=gk93 za+TjU*017;)lF8H%;{)6jTp?~nvJJ>`unzSgLE}^jwE3wvFLt~$jrpU{&}L@cV3U% znEXB2%avQAKV?ZdCl>{3pHV5F;Ge^YNfM1ya@gyRYe*5L)0YOR^UBfO3~oK=9`>Qe zDUE5R#m*r2rQCvW(&);r(1er3hBiliM^7))Fp>D3=R@UQI>DdB9C?vzi?Bg`o?q4&_`2*)_Qk{sePwuWP-Ap>GW$1ezOhbmWfn* zG+#PuY||E|dwRm+nkLcUrE_PZGbwBr;=Bxv>8K3!2d0K*j;U=rKd`s>;HPxuVXpE` z;VC!n9C6Zeoo_L8k1J0~JR7=bym*>xtNz19$>fjhDPs8eCUa90^x^t8zNKXg?)xUj z9-cb<<-qSweQZ`lAe?vXkyMX|wMxf9b&Id+{hZW`1jVw~<;TW)6h{xY`n0l7oOsG9 z^Dtz1E`LyibTfKo^_oaAzN|6NmgI4~iX+osiPXGmjKWRoq(mth&+?dQoou<;X3*Jt zH}M83>91ejSB`XY3DU&LG>UC~%9=Xz_WKpOMU0Hy0qi zeQA7qSX8Mde~^6X=XL+otxf8w*ukI`0vA5F^wF*%N}4lNMx(oTD;Lhxzc>7GQtS5U z^u>HFr)vv_mdSZ?Cr1{|e%J`%AFCQ8qcym=N zwZQr3)l~em&YR6-(r28C*0c7gdY)dqb@cd7>YMmhk!@Q@yAy&F~ooKiup9;Y9De^;g)LI2hH)_ zqS!+Xd6huQ>D?9KnZIz|4Q|=lTDQz8( zF4&_x_Jfor_{6fm{XEyE1!Wm`l{z8qGuEUG$E654o80Pbla>_4)||U*7-W z@{QI{v<+vKo+}+Hu3s3vme;F#;9=s$oFgSt?70NbguO2%Q$7^lPw^*VB&SP*MV;}g7&0x+&mH&vQ8?hb ztvfNH&@}M0^;|RWQf&7dxn_Rt3#**=20Lz>dljDr1rj%C(|uV!#4eDIXh)C^ri5G- zf8sLyvZD3F3WwQ*al5>;h+*oxWx6|VYMH-$=+1`-KVKs=U3|G3ue}hi$M!LZk#4SU zjOc^Mqp)@F-tS|(9QE$|Q@<@N4n1rC+|)^~QiHXylW_tL~ZCS14z#m~RZ-3Gb_S(@oqvcf?S#G2bz& zyfI+2ojU2kH4-nS`vFdA=LSq3OYU-bbUu)^O=H+kP6|p`g}{*}lHwUpvNOb7~{~q^jl# zCAzNNr(aA;if*^$azAjZWy?A9;Yyx#P*bc>&Jp#gH<#?$F238>edF_~vM!R5wl-*?YDZ+!l?X{d5KcCZb=alhQuTAF~?$}a)^+k}*OPC?O&D`^O`nW~VO*?U#y8ymhVMvSxPOg}A^arZD|!v7Cfj7Gr$3$a6LMdZ&WSJsh2v zMruZQ4&>dos5nAmd&-0>sNpp`*Vp)mM#`77Eyes&(0+xhvN%6>Zkx5h{%v zriHL&-I^r0xvY`%r1VG;!FXWmnFkwAg|CUdBUMF%e|6Yt>*vbOhx0#r-W#U1v$3UY z#otr(vSMs?j$VL_!#IuUGWSRM@?c6ba$?Ow%_z6e7QMAzb+;wgzsDH;kjrN>2odND zS4^SiQ-62uwL`69>djIwbxCEewB*I4oMG9vFqLrYuELtJfH^DY81?5_rW0f?qV7@t zOyWwh2c$=74}ELj=s%`p_mj+*%>Q=}J6}xlYbkHe#zMBaeRASWb=TSs6Xsv&2sb@% zY2fDWGe$amJCJoXY--#zW(dMz(mt#i!Lkmw*=WI~X z^qB(!!}u9BG!FA(N_3PN1d8UB3ZI^bOKgiWTPOFYl|zTslAg)Kstf!fF*=k)G7S_iY-;!j>7$9o$mryE{DNok^9!4~iK z^&_Y87IiIN6(v>LJ?0AGGQsC^jmDzIsawbDjWDV6aCxY~jbAzTTfchB zrQ^(XW=RD<4^O^P>ErM;EDw@SVmoMS@$=cf&VcrM^-!;K!C3jqz3=plY9T_JUaAjj z=OmoRl1xUSAc<1v0mS^vuW z6CA@u*~F&e6_#7EiLS9!+t$lL+sjjc4v)+2Y z*;%jD+dI9973qt$yZ$mM>RJHLm0ebeyQ&xJtey@?jY62WLNeW0{-i7 zFEF-LaLT^E8m4YNrTp}&`4Mx@-rEgocC(GoRC0Ga0)zCT2$im1y=unpbUL3!_)8I? z&Vo1VFY}EkzhtM5D=yS~i?cp=_oOh1q3URw9~bsIYM!%jGiOWcpHCCo-#1ItJEtM~UX3bV)YsWoe&CPJ%xX)83pV4<+>p;7yR4IqT^S4~{y+J%`aZBIA zIERgEX1BA{3di(V52%uoXO+-YJnptV|Lcp9nWcAaw-v{kL7U3Ur1_hBDvt!#S)AjT z;~zX#O&KiAdUpJgb!{U%Ddtwwe0)lZ7LeL9?s-)43<7M#meu%}Tqs$L)jK(xV#> z9Qi;hy<4xHKByIvHW_&1e6E)G%{oPnVa;DmgtEhhMUiJeTr`}k>cH4lZuk^s40mtG zT#89C8HDzhrim zNpt?52gg+>y2F*j&Vm)`WC9gW4fMNmt&>w!t%~U@8d=yTLt>(}SgxL5I3vUS>irj| zuFO(*nL|mxd6V$vrDNa99O8P|M0Z@lZQuz{Zu!;B0ClN+8o#HXNV~7J<^CSXoj8g2 zB;|JVzNqu&F(;ko#8NwlTyg}B?6`$p22wv9-CSTE-%eg_elsn-_~Co)Bfre}8KQpP zymgm#R{FQJnu5y1voit&m)@&oa0b-h7#bbPwld$(&?hiD{#x$@m*n8@{l3gJ-A*kD zRLoM+gp(Zj+0^xH3?Frqr9UfDxHiq$60s-q8<6V!Hl{wRj=kG#j%-~S?~|l-M5lrg(tWIbWf&Y1u9wC+K|d6F+pkKP+`a?$s?uMy)E-8KWplGcO8O{{ z2VkLZ9*;09Jss>j^}$^_r?*Kq>lelGk;+Noz5MDylc$gNE~$nD&%dPlzW^yf*1ze)?cxD_ zm$KyX3Y&C(5haVrWC;*I1x@2@7!*yP6isEEx8w{ur$9Nl31rBIK9%6`wu>7QAgMf* ztDrapiB{eOd&0xsZ{mZRzSA`|I?Qg$mA{-)<7gT#>oGnL6X^*!e+YtDK${w}wqvIM zIr3$l)a%)MI?<(xvzyKew%DWt+3*6VkhrGUyzwnYfc4HDl&a)u%a%9YF zhpBf$As?ypW9J-F`5J#ev#QZ@hRacrbmEpKoAW|q*mlz5ik!rL{evg@R_m-z`mLWdPelYaVJmO-)u}p3`>KstjeD7rw_yR2RgZly z<5I12ZeUOV^?7TyU$=^_Dh|gILAxpn>veNV(Xit zYk8t4D**I%Mm+~7Yji5d?3LA@8^+ifr z4#2&UZC3F*o_355;+h1Bu<)ZYs%1Uj6OWNPbvT57N+rN!&t~u)H35{&hDR?c3KT< z4s!vnt8^G(R)1{7URDyF>E!EEh47zy)RvA9ggHK6VE zV&+KvgPTen=Uif{Sqal1=zPpFI9~@=#=ry2%bUp!yVpGRPuIg8h0Bt<;bg6XL?wCF zb{uEphko9@Z#eOb@3Y6BH%4y^w6XV0156Sgqukv=I74x}1(Cr5UN7&eG#JD4sE(hxpI1%NUtbUJq43Y&it0X_wL)9-b42#`1GL!#%q(nX-)AwIPVADhVgDEU}p zr|b~sEw0dU1=*V4wJ$xxF7V_^Yhu4!fC4!vH?!N>^VrR$t1)!LzJB}mgo#Sie^|!Q zwJy6cX9t!8Y3RUncCchN6=6s^tK@Q?LJ<}`Zp`RrdwS=~jA=5Jg&Z;Hvgb(P7QGyg zX}oJ;BpGc=-7TiDl~D3m*axl~4SH-nEoDa4N7=%E3cKC%e$|V8>@J&VZO03)w@dw< z=Qx5&Jz0LEyY+D%YTF~rK+TKZynIN2OVaM!&xRq?tJ=Y+R&7g+6&AhmOCBv7vhMhhXo1J;iRx9>Z;V8X}# zx|HAYKLX~vNx{=!Dcb57um^O$u$=;6EeBXa?T1@f@JOdxj+I4{pL9uQ%W^>_R`hi^ zHmaT$C$kzO)Js*^CNy{(@r~t}|8D|z=(|j((&y3xKjWI`S3x3odQtS^B8XoKa~XWm z^LYK?KO($bA?rbFDtJs<2cI0ejd?O$ECxXJVf4um@HX7J0NXf%aKdLWorr7H& zriE#|zI?h?6@p&E*+>L@F5C2WD&;c&- zy3R1<#!&Y|*V8<((;yLdG#l>J!m&DyBIXHBq|n0zw&;w1;4kJR(!W|V-yqDt6TBYC zsb1qUYgh76?3lC1_?)CsBj0eg4Ho`k?Hj>ExwZwi1#uSgdrJ7hW2HO z7)D1%KNwIQq2sXAi8`Tfk6_9z$vOyRMQXSqK?(WULAg*(R;Ljzjq|~xZPkQg2WHr< zn!~M9W;3qYfYa>PSUts;^9^!5&G`s$C>NK+ULg>o_!L8*OLFMzMUoLwFnhFTwxqZX z!Wz5Ras}4iD^e5sDv(_!Khj-Uy0*Y#kw88zGD02Qq{ThGs@f}d^i$ts2ogb#+~5{) zkab&XOjnX_k@NwZc6vi$)T2^}%dB~jJM!2kS197^UF>mjikHbM*=9o zszuO4mkUCp;@^+|kI>S^st;gC!)K>0z)#1287mLV8p}ipAPOA0ns7H8l?+hV={0_z zb2FfNxF*9>BJaO#=h78oKGfwdsi7HNr3WJLmtAro_0+W%@@b%jTYSD_(jh)K1VOg4 zTEbd@v8jO4-c^_i6nw&%2Qa}RXZ`l*?tG!79d>-lk$EzB1G#xwr7EV9aYU_T&r!aj zi&yC$ZEpvs!IW1kJ4SEu2FuH}x^LW8cHKOK0BTccS>Ha4I#jSrBr4so`sWMRBzCDF z6X)>Dv&#p)g+BOrISVh^zUdwziyKjsjbbCxr@4xbuBVI5;ZcWRLvQgJ)!Jc~;x%tC(HFqK%xwdF~g^jw5%NGfm5$C+ODpGrt0ih;w*^FE)&Ek?1QcOkY-%*K`;hfxz~gv3&1 z#g?0`4zctxMI=5+Q68`x*w28E18lqm7P7K!yYv^a^{4{AL>jL`%1 z0&qPv9(GESmZ5rg<8Q>5Gfl9Hktpl9ZhB+oa?Ds0X7zCF?yCP&HYg0t zCJ!SH40a_MkUgF&UE^^+qfhk(G1WX*l=^C%a#IlXD>5169jL-4?Nh_eU4Frx)_w&_ zDTl693D_8@B7iwm5pR}m8pc`mT7BOc$~RiSfqSE3LT<02;|+0Pal^cg?4;^k%<@fm z=<&Le%f<8E5kbEk{cA^&+P_OCR(1?9;9y>i4bpF1Ctvl4r1PxvY>Iosae0=Ao zAxTH4Dg@~+luc=IAg+Ef&{vRiaA5kb9oh>bM5OFUxWn7Wiu)UOK<%Nnz0q;d7)}PZ z$5C95v3`IQlfh))Z%;}o4QkT{iQ(37%+^#a%F%60nv8`F9gl+BO9FfejjXm3&^Y^I z6gq{$CL1=9=DmptF4R!t<`ep`ysfPK9UK;-&z?@b%B~>IN9bLO=o*kX5EU$+&W*GM zs9tzM-~X;@2XViu70^8cy2Wd7s{*_g77;eWqHv&;f&~psh1UX5>uh1o->|pR&CxLx zBg=jf-zHBHg+=yuRi%x+gkpSG2o?#D8PYSVy(yw#B6=a6%4KKgDb|QJmDqSdJ=A-4 zWfs48#c0HSD^IoUXSAnQn{X#&*OQv@jH&hP7dWdRY$-Bb3CN|luSo!TdcZQu_PX*l z23Lq_k^e_#K}|1#(RX;{cihYV1rKSV;)jF663pw$n{t$KkH&EM^pBM>VgLIc?~TJs zpIfx@3*+afL-K@wp*|eJvV$ZHj~;n*LB=#JDO3mEe}g(Jx;*&g2Z; zP|&+M>(8+!+`gHSZwm_*TJQD8qD2XK!R6`$$s~8A7G%D@&1rgL)hV*n+C{PHYpl^Y zf6z7b5((7I0nRo5JlXc<4tBtd2AHkT1en%D+E}0f1@Mbc%tYW|mMknCVV{gNa7ZXO zxFmj93|^v_m~TP!kqZ}eEn;Su!xvZxe6l4qh*iI>m0;@SdxPm+2yR+EI*R&Slu8WW-p5r z`~zl^Qkdzi`j=gJD&D&Q;)T!86$Q|~4jDE~8^%`O&-zLVa=EM#$$NA-D+fQ33?2=M;P_;dy;?1776uKc0*6lG zjNM=pNkS)Ul!&*MihmjSS8u6Owr^xF(@cK{@j|3j`kb3xI!LVoEP1MUSZ`VS3Z6c9 z?l3CE93pyBGpOQ-Oy;nFXn~R-t4SW9XGSD6%6BGl0hjD&lw%_d7i`rqJ;^?G^-g$O zkdFM>r;b_)9;$n4K&#kU292zP>xQ!J2k3cEJ>qbN19XCJ#5rZ*cn6K2#hjZmrZF&! zhT#ZT-slFUS?eVYRpT)BeJyl;o+O3nSW4LfuFPngx;A_8@DTieE!~R!kyTQxCAfU8 z#yYYqm>n?ScUc`8~s|!nzRAxCamzz2tU)JuQZ(Gt@eX#aV*Li491Si)F zdA*H)v!8>8jieB1{^;X34$E&w_7*~r?1diV&9(tFOj)-#$B z3fOC=)Uju^``j#(6&By`7#d~iBbyd8q@dvxNEA9$}!wouhMl1OCOxtL(w zPH+hI{uKu6j2uPjpA|U|ar;&MmopIu^Hy$>#IxM$o34m05gy`^2Iipsmu(Udi8}9` zfQU+KKcE8{6*;OgUbD0M`xyjCnf+WDpoNKY#1+pOpmGU1u4cLX0)M^OhnwHT3lbV@ z*{SUKn^8CpJ|o;XZw=UxMU%bl&V2W9O4}Z0+odaAt8>Oi9&jtTa|NT0*ED&Zr=uR` zX)6E;ER;DxMNnxS-Uv(qk^YxZUF3ztH@ZIUGaVV4Q>2e#eOp>r>}-5R{uu(uJ`?|i zRLPg>5fzZ+JcM29MS0_BA6mOf(?*Ns>lpRq&obUVik zV6&;MN-+N%->Z28PwZ!+X#4*4AiV%01^N>Yz@DbXl)%eGXPvT4&J88mRjT~aLwZ&- zM`Le4e758!i9{JfbF*85e9lMs*)q>55UNabMDJ)fKV9&Xz_=AI_8;XtzwSK-e+37- z_fDxs=#FdAlhNwj4ChmlkwFRw9S9=KTo@qEJe0Vv0FA1em2Ik~8pfbn8Bw6BBLK>a zr-m@l$S?Sir&$c7MS0QzNiQ*?vhBH zD+MgpNRg?8yi&)8&nF$IsfINDd2Iq{%(Nd4AMUt)fBZ=M!^V@T9MLec6{ZJ8w;+V( ze?}Yr7T|iS`cWWJYf}XY${tKC)9KX?dX0~SH5oN>z==Mty#s`GILg{WQJv=&O%(tX zhwA7CMhl{|A1f-HoMfEFlQDmzJ)1xkwOEn8?3gCz;JHM1ZGh>FKuxWMwXewLP@(!58Aj>&DFq6R2! z))XUf#Z=Pn(MfXM^DeK#J%`%1fII6;H;pcQd}#@>+D!R(;I&YYaII#vI=(MlD{=sP z2+a&v+t&R#c>!mCIFo@S&!Bef+OFMxW`AF^EDi)PXEO^3D>1XUW4o!%LZ0-vZ5EV? zFcf{a!<^fDOj{Olw`LF|69j~>D=Modqlr!Kaa)|MVJ|0baTT93sLE)S6=F}l`bX)0 zEe|W1>MAolYa4U$mFQ{?8@V^X=Nix9HWU;TxiEE?6u2Nh(WOEH@2OOFM9QKg?!6Cs zszDN_a#Pc?Cs*m=I}N4O1!cmCB?g}!h2-lF?vKFrI}{1WHUS8EfqPz^lQRikt9!vS zIIOtg%o$8f+c!u0{rx$f%}@JnH1m_8>3?oJAhdZbd4NC5s_>t@yuy%~VAKw9xa1~_ zgp7nz@3Kq zW~J(`zt1!Q?f$T&2X@+bK9cG`G{1JqgdNdakxIWpe^gdkM>2{f=N3BP^jF7tHW=2v z6ZC8{!>S#pFRyhm>3+5MD?oeTahEx;HOuN#{@4XnAh9RV&8A$@qpEku*LGBojYMx& zFiqM%G#x0MiKkzhAM3~crGbNp3?-rORwu$xKyQ6?3-ihk>lXpkUpu9`&Qd}~`KPBr z^*`jig4a}kNW$B}PAOi^2w5YDZue!erbsON57VW^X}D)9_fTJRi2|kk@3`C=Mw%#s ztC+=@e>$jO_H~26U&qw|-u|oFHlsm_-R#?`1)@|RfoKf7N^oQYj;J7#-~ZfZ*myF# z@W;{ZHMHeWWBT4en51F9+qYUIibI9TV1QI`!~{UR^xL(Vz3Sdj0~}G~rADMM-!m+U z`*8B0r5wrv>F=y@n^BKUB?~|n)yQT3Ea=}d$spgG{|jq$m-(TL2n;_6CWWxV?^U&t zr@=Zx>_%$)I^wA#`zzOq$^p+RfzE>Vi4yVwj$6*uqw1h65YFtz=udC-Fn||rHkQ=T zPfQ-Fdc7t^-QF%ETU86-_DB4qkENwgOb^K*60!PQyI-@LLsD`49U^`~%vQ?f*8vny z=PTdyO&N!|?9l$n(CZm$=^XMQaJYQ_RA=5$6Fn|Jw5vly^HF0qnc6bk7Z(;{np(o9 zY(Gdx;$<)^BIf}gYJj*Ds@X7Br91CUD;dgqC8J^BD(*NW?|0VI9FM?6%b!urcgO_j z9ZDc{CVo}q1czKO$q&C%LQn6~&CX~9U8&1EznefJZ7vDRFU0+H9!~d@dit*OCt3xI zZ+8W7MxAWcV(PmWD25T6^@`%#RvxaB-M0F zi4CQ+A4n~gfIK}*-*_ih7A3t^YKs8$v_?kje{3j_<#?-+-5jmDyjfqLqz6pKiMpO& zb8ptd#`@@I{3+ojOU1}gW;y@fNM4k|zKhP+%boA+#3wdi#@(iC15YCe2AU;Cd^J`u+sg{aX<=nMTwi&UQq9_t{9mt| zN^XNx%MK5Ajs?pfJ~o?MG95LBwuJREP+e0mOj2XaATKmo|NH^CG9ws z^ssl5ZSo?B;}0bNnAa!bckjT0=Yi)n80ZrcfJzfN8iJwv8SjOrBq#nJ>0nV3esLE8e%pmyH>+rL2j zIQtwvVs0rYyQdksPL#yR@hyvus^xRqndgH3KI!2=4W&GQcMPliMTp2c{Uv7(qfi`IF6yEn2zUuSvQmk_X;5k#I-b%==xmE{v}VQ>pW`3KaY zywb)hY}!pPLE=Vkz*6q3Z^8u}E27fa6AteJ!=^(b*%52({}k<tMFg=)>R^mR;@hQea zB11B@Cg?{20Q=BpmR2zj^^BbbHL?JE6jMhOp+2KkHFaszh%0B(!&(>iWsAHYE`6#T zms=!h>A5v94pojk+jt@0tT!`L8cd46^cr_B&brjdU>78F|CTcP6R%z zwR1XsQ?eK0_9X+G>~KWb-G2obPD#V=VuBbxv%a`jy6;Ndoe3?>CyCZ^_cJYhK!=#d z1`Ze8S&)BfenoqPtpNQ11I`xvQmNe7@lia-uEBB)b$Q$M@AgWEJ?Ge+(c0wqj}`>3 zjJ`J#U)gpB-pkTVDL1{GgS=7I8{Z*kT$Pj)?6PRUA;qGga17`UG}*{k3wqW70LYXw znKmh=;A>GuMKtn?3|v2Jcj0GqIB(~N zTs$m+iF|CM6r6SNalJm;l;!JO{qvQ|Z$1uK+zJN*;cFmr8mh3TvHD1`J{E**%if#M ziecOS2)S_X($88O=X?i>l$|eb!M!jA{27Mhq)dQiX$dfIw!~!Lk==FOc?)4rq<+e- zxAu>WSth`v{`0d;xF>1L>bC04ardmu`slw7{!v`kJOVDVk}2;IGD~Z4-C%tNKTpro zXyF~)>H$Eg+Bi{ic<8DwQ1@9GsOM{-e6O$(hFB|2j!ie?=F*kvc?IE&{`u7*9v1GY zKYzTZzzS~!^HW!WU2vJq?p|k?GJxMRn_H8c7)U|;7SLo_U#L=@5S_C|NC>QjHc{-- z6~4oArD6BaUhs$ZChgA-w{PDI02F^%B(QrM5J3|4TK=YKjqw@zAzf=TN}mGsRe@+gx^c?YY1j+y!Y`{$nJ}84MpQ_;sPb;yM=_&YSwVOp#MTqm$zRSAQqsC11;i3$!S-qTIq%idP#w|!{dcCFt&HNlzI3LCWY zMyW@c#_pLLY_dAmeb@aqY24GxzhaXHfp8YP)zoyWV_7Sg9?b4HQsK@%tT?e zoEcX+ufROZM`1hdb&|L?>q$dbojhi8tgIT_6_UCy)~zIV@EySKGsLHM=qew{90sA^ zl_e>~wZ^LtN~;MaXGM|KB(*^+wsiulSn!SIKnWWJ{S=coVLIF*B$h?)#&Ca*K=Jbt!8M6AzgPNX{UDMloKR`N1b$>znGB5Wv#`=bwa zKNpHP;4P7$r74fFw1R{(Javi!C54+yt2bgWbPLgU7gIh&0Dzu-hxeSL{>VBrlPbCu z@+~X7q;Jm7@|(n{s>Z3ZMJA)VnY&9Bgw0ElqE4OYk+UM>{Za4hW;H)mli?;s<^#n>!0YHd2q`1jz?l5qR0V2X5sC1z2y1|cDV=< z#H-C5&5OiXN(H{q6{bp-yuo?24DqQ9VQojI0E$i$R*kY;Z{sOZZy~e4MgF9{T5?!2 zqb0;^sX1K<>vuEdO?`I`YHTm7M&B3>#K1A=2fSFHk~2}x-py2DrJlcT7N-68vT7Ss zp5{gX+D}w{WoK}{9E28zWy}`hFYXA>NU*jvV*o#0L+CyUTd1poA%6nyU zb|P0xPH0jFdbY`>18@qGjg*nASs5-*bXmw3qoX4{RBnTn-J|!HiZcA>rT&$p5u1*Z z#%jw8A>y5@zU^0X7q{mL>muLs(=5d}I%PJ)#;z1k46?ekEd7zYdw%`0RsK9OHf{A$ zR~x3FV{5TkWv(Ii=&t-jjsr3qP|pA~9BC1Wl$oGmU3{n8(MBJUy@Zs7BB7y!^0>-H zFXU1i$Wl7A$4gKNT8&=%%yBu^G9R5)zIbvUcJ>M8X^fl-AK5*#{#4b*_>aXygm;*G zL-XRY$(7YBigDoTQC29tV-BD{5?#kjG>zJn!yHo)P7AC+{qjv z^VOd!X;({{r}Y}=vVH>z1%D}N!X1eea!|6rOFe{Ni22C%JUS;yj~Ia(emTjg^{#0h zD_g+X#i5zWfoUAtq*=AFwnrTC2INw+z%^D@3;{@))E5koLo$sPqG@FY;LAqFjX+lZ zH!f~`cwOD)$WV_2!t2WSYYd^N5Ft&LHVFSWuUDy_7|ob`3U{)Xj(H#`h>+n}`yS4Y zw1HveBYO*u=1u>UowUUDn-%mdqX#Rw5J7UYJa`*K3`QWaTuh8~65+Gi1~b{NCQFLc z(C&*KH71dNHFCumMoA0&t_(J;=gftf2(#7yKiacei!eog8{OF40|?Ey`7YM?;Tou2 zmq+c{a|2iGu`>+HOaXxucp`HK@!oL5Z316kr!Ra3Wzb+FCshB0&^@HwTcG>pwGh`I za9JG1)GL)VnKWWnfFh9E2T!&_6AtxswfYQ+%@lDX=!f?G8X<uY)j!86dZB9TN7)qnd|#EjHG-HECl(qWRrm>73VH&G1J0I38@|FF@{>&sh* zIM2s_)&j^5QHt5IPv+y)BU!+eo&Jge%jJ>{kE6XcysaC%1LFf+gIOoF$UGV0;)!?d z_FMy}8n-qxI|r@^PJL{aF`uk2l@)q_BU)FS(i>wA<+r6lpWJsnFbV7=`@~9gjLtj< zVrsQ(6qTV+#AS&mn20I&0u+Zs;C>T?vG9fVg**Vy0MLacqtAB2Zx>?4`iitr#9OPmHE@uis8?& z<<-%~HUD|Yv_`&=q5zw-WMgRuWO7?JqYDU&j)F$89mlxSE|#!g3uwOi-J7R0>?4vB zZFZhp&e{A$-ea*=0a}8~RhK$J!#azV?3}{c=SH^gOZqXcLtQEz={yWg3qdxy%AWck zRIm>8JR9QHlrXV@S3IkMRZ;b3^DSGEO7;}Qm}UQ1;Lhqf&``w+;Hes*bXMh7f1Jtk z;h5{00v^GSOR6Bel zHta1sNg1#Dpy7snimgu~HOYvLHKxIBy#$MK;A=RqjdN@31^8h$@HYprIGCo0st!?U zpgtwNd#o$7nueZ$pTSIv6ZmB5Qk~_j4WHWjnnhp3Ic4WrqD@DVS7rp+8?s8#s!bxxo&zH z!Qp7n6P(G$Km1j}Gq8_-khc!eq|l-p1jqBtx8`J%g*%b6o=?W0HUTO27fXMv*KqBT zJ(@gvpfv0Gc0KIm=>sAvG)kkPhhD_sq+;U#twlA}$wU3qGkajXT=r0)()Fh_K_Lm+ zD8(9)?Y+Rc=zBBC?(nDcd0|Gs7pMmtV{f+ki4EHs%f~+PZ13f-_TXxBC{)YtXGYR2 zHvIOmy(U3UmBF#fm~BoYW(xIJ0JSvMi^7P?wgRuSch-ypL3b;)yr_N~;4ycn73ot6 zyU~n_em^201*45U{-x(FO}YL&=-INeGS{$iU{?`oq$mB#DxJgaZ7MUnon&#F#)zsr#Tyc!BY+2AZsj>x+~(?_Ry{kdONIA=O*>60%v8+mg# zn|$3RlO!wBmbzfN%*J#-CgC#@)h{XCVu*)uWR-F*@T4Yhc*Ts8ozJPF7EXD7+Z~eERIBHhDxe(o zksLV!2T8AeP6FEf=%Vf%Yd=gMrZXeOp_MWZ%jhWsqe5fBh$;$amhUwnhu~y#6R?~n z4g4M^=nj-{M>I$Yb6I;6M$iue+$l7|wM;(z(9?NKHw5Li!uC?!#)`%(#_=47nuROQ z`}UjHr<1Ho>h6!f9Ji?B<{eN|yZApHpD78aOJ|ob>@buj$w^HOs@3OO9)1RaK5n*OK!C<4lp~&Kq$q}gp@st5*kcl6VR46S{&;s+pry&)TP>TepqS3In&=C0#_!dp z$P1b(t3{o656is;2Zm4wEd&{NxBUZ6lyqiY1mjpYMMSx zZ-@tFa9wzigX|h3eIdPH)+3^owBhaT=ExKpe0R!(Cv&+M87W3&PFTz^7d+7F;-P+z z)ulA6b%_v5C`bjAN`?f6T(rs#D%i0=;s^Gaf`$cfWygXNX?j3Tl0kpHAo9^s3<498 z7ZRqv9{sgGSmB-DmhyHFSsq7@Z|1ZvRhb7$QuU(2#%Ng12XrFKYFB-wxlgtVXGZ~JuY#7(@UX6Fwf4Ke|8eEpGI-4?Xg0E z<}tGae=gQ0g%tz1v%>H3>b4jnWb@0}B#HZ}A&)}&l=eh$^+}moJH1O;9Kt4dc%M&* zvqfY7$?ik8PN&y885hgR@zyT@*I6Fde&!F|NF| z1l36SH4`O2OZ*AwwEioN+*%?wS#32Dk6?jMP6C&#+iV=O$K4@p99*he9cYiieR<-)OH)-S{iP`QA_;i6Q?;x!dIL!$+}n*DsX&}h%)Q<2VJ3z(Q{=>miU zMU(k2+zw`s)OVWh0ox)$zI5(}J;Xy)1T!%jaiKu2ZPf}-1(@4^92H5xuh^|(}7s)60j_h%u(4t zHZ@iSjGId`vRviBs@4fhX%rNZ!t*C0^ll(|x+_|57cO^9WoIB2q;i=ntJ!SCSOxV6 zKGdEmVOeP#yQ%Tc9uGwn&2hEx8!m=4)b@XwmslH87|=MEg#SQ%!Fq^cvqh^NX<31kjI>D*O#GezW?nI?A$+x1!(SVt&ZYQ!c7Cj83&` zi>ewhw88q!iB1kK?8UgFI4v54`t7w%Cax5Tk>#6K+*3?Vv;nnKhaq3I(GS=kNb zH@lwGcm3LzJ%L*=q)CjKf0m);r?e8{Nokt=AE zDL=w_k_>JdPm7C>u4Pt=PDBqR>!s~-(C1HX%y0{v;-n=D+aKB@ggxoG@G7VkNK-v~ za;X&3nDf)a-7gjocBXx5Kx2BNQRw{Y>oN30xvfE~=}6VmUHl@jK=Q(*qlBwk)aUfN z7QKLN*Op<0N{dWJE3t~mh0&or-XUIJKWzO9%qm2IAsO6@l(8yOr2OZnKcex6 zMoU~v)24q>-Hoz3_f?FM(q8CoJj4VypTKO^j#$-U-i(>v_$wzR7Dnm6QnaW}E&qc# zoVB+uO~=#e4D98v8Xyx3&_;GKPiW~}d6RY*8?CV^46?u377bgH0pdT|M=<&?Q3ni zB*6txu)Z40=@s9R*_=81)TTi-9ABysnZ{PFA^w0>o`L^vQlrFvIjZY%T#0?Nbs%o> z#jv0vB7=1OHw|5Ri%s;%;(b?MV1ac`pCtj3iO(?K>3z6p%L-yDBdgCHv%pQY${Fug z2U~6BzeBJPagE(PzCJ*mNgCz~fiG=#2q+xYD>GNyv1IfKXa_@kgOsCO?tena;svFb zkpSa48kDbN-uRR_0bc(QWdmlqp)boku6{^Q)G;6TtsnDCk2}zE<9887v@LJYw^kMT zDuS0mGc@i{&jjxDQF8|>)1=a^6Dj%s7UcMcA_?(ZuWN;o{)~w>D?dvAGWzW=FCnLb2^!7CBpq@0c1pr zx}#J*kZuFb35^>%=iH`tFKnyQ^BWulm#ViWkb5MFvmDVJH<7=wRPPh2I~+t z`tG3m8T_SVi7uz@(`~HCu+=mQ^J<30`U3@2Y%4!z)p*~nOl*Y$U2WD`R8fAkq-hRp zLYG%mC&IC$F5n1L~FdUdfO%@}BC!l7W3Uu}9w>_Q`UWrz!6bAgE z08ozbUn14&0oT7hHfL##{SZ4%4Nq%l_s&148K6=sa*8$IZa7pruovWNM*cXl*qR@X z7T{qtn(QJ@u+1r72jSYo9jbJ+h;@Pp=7@;&3>JF4q&VEk;CC@oEp8YJk!{6Kp&Wlm zNX%zgY}BzCaAL8GPry7*T%`jYA22LWOm*nI>x%60VCOvQ6cUvR=PIKQ&JXVn?J@^p zIuKu5grq24Hq|%Nbj0vtK?h%|=gg(xxPW*(-3i!olE_E%d2=w!)4qp%2Y+GD?gkav z5Qf2DpT>}pUja%Yo9Ij^aRs8ni>ifIpltIU3mlt)zcJ(=(C-+Cjaa<7)c_;<1xvFLRwR=8ksB{Wjq_ zU<|XHc2Wm|VS41;qBQfJuEwXmUZVCTy<4jiQlT?nsOqHv;W#+o8o{qmSZX&F6eBcn zp*!rDIXI~Y(E%yLvczo}NVa!`Ur6W~G>m_-x*Ux=nVY?Pb04I)houbWeQ2_M^Thys z8;z+w2*1{%k!fLtU`YqNMG`O~t0r`O(1nwT64y_vL%`C6Y8>abqa=O!XK*Wi9G_nx zW9DkNB+Sqq5htI4rDl&h==nl}VYKnS`GDyictTv_<3^hBTg&i${XB;feyufb+JFGq zwGmJDDc@e$)Ww*q#0wm=DQib&bw@H%3O7`&E(*meofO+g`dbl}n}rRhvjWXK&>w4% z=j|96{YMbXY62i}iPv?&44sIh-&r-%m% zC{oT@Wy#rYux+&6@c9enQYH;U;&YYuh!X8X^FMD}ETiyHnimL$HW>Mc+P;Ob3E z7j67vyr)-Ri{?-{-j??-h>&A3)L9{ZBQ5LAkS!{8(Y;6~l$m&e32$bDonl4{CZ>bH zO?0X`1HhWh3qn1kf$ zUxA%$qnP>ay*D&*liSTqa>J+NT0v8T7Jo2&WXGZu+r|$sFN%`ZfYH-f>7Z`4Q(y<$ z7X~xh)N`>zD1lVDGo|s5%1g3nmil@-N8&Is2xHo3*@9@Ew;o98MNywr@?hcQg|U4B zGES-?zn#5-}oC%P9y^HcwuL9-cLTo+9$FAeO(3A5ijt>Z1DJ?uD zsf!Pl{@{T~E&O!iK@+^jzvd6pwRI@@?2S2(kn-o!#s=NGmxHRA)&7K`?|sQ7OmCUf z|8hKXFPR@i{OVywR(=G-mV-AyjHtbAVWn%9O7Pfxe%})GQV+g1g+> ztbICPXs;^hEap0QuT3U~-7>I8ROU$)evPsO%zf9D0~N*%nyT|I6-(9eM4n+9<2LCE zDi!N1%U#>%MmK*HpTjmvo$1$? z>m_1{Rns9uZ!Jq5Mfx0JOOXUCi;S4x%zVMh_(W99Po+v^W&t@=$oq&*=QMpIe*2IW zoH`Gi*@n@fUvOYHnqSQvCfdfM`b&|HhZ1%gnJMWzBLALW{)%+XjU*U}<*9}h0OeMg zy!Cokh&4UYvOEt&UD!)>*KXS4v}#J>_QJ24h3LmkcO2aCPZq399NU?n(M+&ns))p- zcl6}uMG)m?`9-=#95nI=?5RlfNtci%uHB*iR~HBZV5Akh5wNQHSx5nSLHgmqa(LyB z+8<3@>t|#9T;3_7wmX}ldfvI>Ij7KexU8uh8Bu|)N@?;s=VJWFqW*kMHZQPW=!b#+ z+9HU}M`wl3eB9VMau<(~r72lv!;vhOlL8vR2{r}N6+D{-oA+TlJ((H5*NKK!kZv*L{pt_hbPMBw0`{>Eedqnp7N+5M<&&<}y zn%`R8ZWebXFz$@;kWSKO!}t@gL_;9Xon(Z_pejq=+!+dJewA^z|gSxpzelgb|o zwWluNbh~8?%`98lnN~irJKhK#K#)5ulX{5BA;#E>78LdxP;*&(9#;Atl|Q|-&)zc| zN}r4+BOdj=48oZNR{%0=2q0^1 zDBr;?0xHQn1^`63B|!{A+~Mo65Z}>&L!JU5=RH^^b@sL+TI!JPMTS#ca}Sk-F}Rvu zqi8+Wu#_=7Jgl3wX1tP==w5{6nNGvGXq+sx;s6tQB_(J!yZ2L{LE|)8k}SNFYI%-7 zuFtD|H6vEH7NsmUQa-b-q5an76!)zb!O8LYC$_OwI>o-J_LwhhRXMOnflnS~iU#Hw z38iHiv%e~8%eBty3wFq*4uV6@69xh^Iqyk6eWgDZ-r!7hav~oRqh(jF(nbPQ_^xA} z#C>_85mj`tpppask);&wcsEC8EaKm)e}n%lj)~V#e)n#^s>ds*`_IkF=L<#LjFFvU7%e-L+2oymymH*$+l_@mIG>Pqmj#GB>7PYd^v55r7h z>0G}yegKyOB_U{#WPGOGWFxHXrg;_3qlMv+3PJR3p!XVUAvTUHzWyS*&R(#Qf%aaC z@>{bcQ+z2-{^*O_gF@&i16P2dosU=ZJtM+eVy_-tYpbs~Clw{=9M z-0j?hX^qtYpW_R!55!O&4P##CJJ2BOEA82n4qo2mKIupT*&ZAVlyES3Fn){fW^Rs`xnX8>9=shM6gi4G zTM*pjS9-xKHFSe#zdEdRCQ(CiY~g3aCm0(g_e?edZzT4J{TQov$IeK++iydnt2$c~ zyBi4C9=&YTppWpmq1ES@2o%M9vy}Vo*#@dbCudxO$++BR%s#WpxbJ)&D>qcKnaf#+ zQpy?53>Y-I^;L>M6==FEcTm7=Afv|3DkQWK2K%8x$m0aMh^Xh$Lb7wHMDbzQ>VwmG zxEldl_&M9DCrK9C`gUTkgF}kY8O~~KGhO*t&AwP_craU?3oQG*UOilzSp`$x=)NzS zi0(5)&7$e!PQF~i=l7Ch2WQ;wNx%c$12Z$!{z3Eq1X1H-E*0O?J)Q6qE_g$g!z>p7H$ce0Pfx!_!+=Sp z+^{?A+cI3YlBnp1I-(JCHd8!P&+p9KeQF@Cg{orX)42~U%n4%sVB(tDsfxUg1lzje z0vvG`{I;(L@lAq*|DP;7XHb?Fw>Ub(i*KErld*s?X%kk-K(+kkB>R#@=_`a($vP*t zaHcjpi}f<}?`N1foRoUZyd#AcrlQJ*9Ye1rhbVcJut%!aFhYaXjKkkyW5_Hvqam1N zCq}+5pW1ipO#w8LO`qrRwMpMn8whV+Pkf1JQ(HsJU|~4Edd=A)R%@|W3F&l|K7ZDD z5w9(a9;jZQ{cy2t^Wa#=RHJa(b*Z@yeA1rM8ZUjPI&#)dD*h?UKUopcN_W^kd_XKk z@;|XGq{e5Zdl%_xmbDC4%*FMM>ShW6rLqqbX$^omqWie8=<{Xw%al0oX87PWcjh+a z2RoLoN+Gz5;ikL;zt>OJvG6Mol2>8&Dk5MrgHkm5Z3gHwwLH+pyz&E@a~hjp9dr10 znVe$z_4Qd0+%xxO{dFlbT8MUGgCEvXc!%7oEXM)onj>j7vUz)R@VMtPm*@@BnP?{j zt9sZ0m^sMk~lr{v?uZ15UV)FmyrI^H9II*7O}Rqw?MlJrecvFaOc3hI{6s>6Yv!MLf%q&eWY!CsadZlbd1yY0|&y)5!NMOb?w`TsY3d^Xql?jk1oMrAVyu zZB*hX8#y(CXRpCx4s$YU-3t_XykAh3ou3?d#(+(VfW3&IqZGrXxxG2O1k)Aa%C_j2 z;#WHKk?nF9h1OJ(V)R|p?fIa)QU7%JoNcq80$IuU67-S(chi1rudlwBRNy8#VEf)R z!4*7dSPEMO$@V)08NEC|_u$?_a1gMv6|Km&dS2x@=NwBRP-os`t~xtB+^BC7tkUqI z8!WHvGx1Gx(?4avv>3M&AFkWvX^Ka~g0{$hxVe6V2=FrHNa(!0v2;~kfan-?;uon7 z!N7~D41dapoF{rTi{Tnp8$LlN_k=qSU6_*z4x*C8a-b6U%%g=v&y%@IPRUFdzG3vP zz=Nur%urgJOc2iTu7UxueQDNTm4~)GjJjYnLg1%Gb{mm1j~GS$9-OaJlukEgk;eHQ zZ>nZ!hZ*6V&1N}LQV9gX&bp6t1E?=M>;vBH zI|HVi4A;!N7#1u2U}^^y?jy&^00`Ff#~X?y;5GkMGBkG*79v|>tsSnL5%4cvV(|uL z3pEWdlA!gS)^kXiwfd_vn@qKm5|^uQkM@dgl+LJDs77_xoF)~GgUqcU>fX7J(r9HE z4*afuzv4U7k2cmJ=*$!qBs)sQ*ia~{jzx55rb~>zK@0aO*ji+5gF}Eqnxir8X5r)V3q&4C=+|53r-(LoEoptIw%`mJU^$_+O|?~C>F0+9Ks3D7!#o0c|%r! z<^|ZzfxOhC7|J9t^>PK;%8C~7U^#289!=L0w#GeUQ=H4BdL!@ZE!nB_peJS{7nVrN z3X2l>fDQ~LzsNUtDvUIYJOT}C_h+WQoecsTrK%W4(1&5We0(2hO{oYa6V-8)SyPay zd!Sk$ptuLIx}%C_;mX6Wbx0W>L~}n@u=fgB~K$*XDqsqH496&z_Y>`(~`W9#g9{Bl?bSdbbZOJ8`LF2`s-Mmu_G*O1GriDP-1XUCLus2wxUlodkS zL(zLY?r4zv!qM0p3_B#H1__Bi8Q+$j8Tx7;l&BRGtD&=}2W4m{i)y;0I8{=bTG*3Z zfI;PngLPIrl#rwv(G>E~Xv}AWn&A>5@US;58r)@vJg*sED_5y1v}QtM)zQM!mUJ-? zj6a))L|ygh2dkTyqVOppw{b=yeROzYP*%^MF&X4T>?n7SGDb%Sl6M|{5^j}i?1XC` z{}7CvD8q2X-=Y(BQc7P)*kYDlHUXh*#oI+@M*MpZAXHE_1i^rGoPwF5td7048AU8k>3FCDd= zOGfAJhbrjS`vZt8lzn)|tr{{7Vf z?Vl9hE(~FW8g#V}y|&-v0?D<0b2XFUMl2F{M^Th*s>4DPD8 zqL4G6`zEL*K39Q;DgRro8>@>}*H~YJpn2tf{C3+p)L&DJ8R@0EwL&O2yfk#**VA!> zSzE>DP-z6QhvjD<1^W0s3B%Mu204tUI^$_fUgJ{eys>9X)^gyYJ#=Yot}82H7g>(7 z8AQzJCG%3{%V&SF0b_U7pM7JU&N-yNqNeJ6x93l*y!&tW?^iZoOg_+%b~)>t{Ymwm zS))8)_wCSmpoOhx8o6g@cd8`37A{flD6kE9R+Og4#)sJ|Ct8K{u_WmtdZ!waD7K1e zsl_Od!}lUOOHPcoq^t99(W5IHg;b?agQ4+L9fT$FLgT!bf)dTHBnMKgW*(AAWTzp@ zm9dlaYw1tE7iX}2GUbx?Uz}YDC+>PUIaE-m^mCjxeB8$W&gxOFF{?;pwq-t?`E_H3 z=N+)DhT(QXH@`bH_?P<0rHAU~CRd#I9H!0$ z(?Akc%r??4)|}(%M!!EtzQ+@p})p;)cGaLz6~d}-TU{|db$FsUw6 z^?EwebZ@^xw|b^0&L&q(;}bzHG`l#9U!fjZhwFGS zyhgex3EDpa+>EE9gpAum00$RX=;Ns;hak{N5J|hrnNL%w?^6=)^1yD9N5Q&K%ukz` zC)_5H!v&h{%u!X$f%rq>>j98#`2*oj+ZA9}TwrZd`}wbgk4e~>hG*5xOc9N(T5KVw zi4FoPe>gEs-EsEeH_MULYD5Qwi)OR6r z=YoYXc+fW8@x2VHPEE|d5gSr*QY#Z;7zj`&7yYyJfk^iVads@Cqw%(reaE4a#4Djixm0gIzjJ3}0HWPpic=B~o$ z)Az4K&l;uV4Q1f!{t+qf$7{+#cf-dWkc3}merBdS(ge-bBYoKCrYe0y*j;q{F3V`<|68x&LNOv5*3|9~V%UBF}Cw7}I4Fh!ZXR z`FLAWqCm9!T?-mpooe)KJ*fASwLN1%SejkkI2r_9YSIR>)cnXnd_-wl1l;p1gy~g> z@sC|Cbn*6(_m>@#ounhHeMJKclG#Uzh`sYjhRK&1wy;K>l9}*8EW{B z1yhy;a7TFIg`o;@k<>?gduAj@P^s>334_3ONT1cFcra=OB5|C^GxAm`G0AxidyEEU zI0e1zZD8OHfkXQCVbtnUB3vB_ZuX=%kQwchc%9zk`-LGjU-UZL8(F#Vg5FZn0gS=q0`OE|L)A{-GmK+^S8ToLq8-{6UDJLCTUo7l zn{4@?G7WDe4beOl&Nc$q*~R1!-+L96-L}ij6g3O}Y8{ppQElbA;CzltUvRpV6CMy( z5hg%jWtr-7ejVV*3Tb>UY?3~I%p)jn&Ez)>Gn&GE#N`izjPQZf<4phf6?&xU)E-}( z2Yt*sR*(eRrwp3WS=IY-3AH15^OXT9W?V_>Sjzb?Nrw%@d!b(ftKFBLn|zODr>xh0 zxUFS_=TC=xe!@6!k{t$g)!vn8JpV=w9`E3}2SnVc`cnA6`$oj!ZsMIGs{m&9(+C4$s z_`4nCxa3gIIqGw?RXgzpMLC_?hFaBCDm+XGja5!-nI&c5k=^ykXO>=Dj}-jOejV2( z=yp}JVsgF_8Zz#bs2{W*=?0M25*FSfdlxh4iHY9xY1JX^tbz%~ZS*)*fC_5y^tvR~ z9tLNkD6gcM%mld}nY^$!Y=0TXtIA^d9U_0iXsj@DzPv=B&~^VRK6$k+ug=n%4XNI7 z5}v3nc0eUzJbD!AYiwsvHu8#G4%GFmZSNrDtQ<;KWStx{9^vS(38SRr|6;WLcu8agP{>kd)>T8S)r@u%|r11<_ zB}BXV99`?Pg?e(+cQ5cZWK;MH&YCgmcNGgRprx{*7Y%LQbd%M-6}dHL$y*Gk$Lm@$ zl^jbVb;?wXim|(C9HklXeV%l~kbA%wal9O{&An`CAbF0L9{c-gC%PC6g{TBo`IKRm zzrzM$Woy`6O8muB#bEh(*FOe9KOX_`!LAQ7>c7R zzWSxd?wXc|Q*#Up*khXCyhueaZ1hQ{E5UFFVbshyvDYS=rpGHfefoKWDK!_ z=un#jJ-=>kYA2LwG&|Z+JAn7IzPJ$b`UQ&ete~_1TU{cb|E%@HbHkbfTitn)dpb zv*f5culrmK6Wb|rGPjcsEO8|IzRyS@7?wRRnj!rJGX-7s$HE_EKR7ss=^r;0#K)f1 zM9?%r+^>W>w{=&7TM)RKG7w>d4&KW_#Y2c<~2<#yB}X>pK5yhd71xPlbba8 zd*AA;*;O%pKi^)aGi^0{&VI0&X1P-Vhr**;=lhKnZO2#X1u&QYYG^+YgYkpYI;H+n zoJbdDO05j+$GDKcc$Y-rame+w&0S?0!A3E^8co|eN?OY(V+(?EDtLt5o{lVELIBL= zp^qa}+FG!TmRN0cS*{9==VZcl>K z7k?UFGU_jK-tTu~BA>Ucl)htfGnWrOajv3UD#L+7KgmNgau9(pWdC&2lOVtA)k$~E2&Q)(s=^F8?!Op<~+neo>&tjOGq$nB{JoP zI1AS;DGjkssbQ9WI$Do$wvEqS1ix;Y?l0Ie5CZ0ltNR5jJW$X&b}%2(fDvYZLOq(? zsn6K$getWYRlXG&@wXJUsKh{*ZW-wQ?vBb6nAIx*BSrV_ z>;BLr0{X=t6b^GQp&Q=A6h&sY(9AnY3@$LaIBZ99*YBVK`qS-yOK@bX_35y*?%>jPt{$yC!M}_2Fii1L%?QrgizREi3LW`;{SXF}4 z089aOOFitQkZ#4R|DeN?rFEV1xxwPV*z9N>_?5sVnf#JS>7^)I13n>bWq%*jtGc39 zkVF%rP`f`ap^rCjWhsa2$oElSF3(tNI-6=yMwUnRE?ug<9;x?f!}u3LccPA0mmYm) z2elZhP0<(Y1qxY#Pn)sH%`Y?M4Vfhw1mjbww1t|k*NQ;3;jtf{+qi`G{znuouwm-j zs4gB|LK@T5;F9uc2jMm}{ITYd(ToZ7VDAh7j3bK5PWlZZa05=D`eXXG2isx5)1f>H z(9k}G6K09ZvzT^6LW^nCh6+8ml{Ew1;u(Lk**;;Y#7@8AAeRZ!F$b%Tz53A?f7Wmo zZ+cp+t!4GF{fUrBgXE#)BkkB!EJZkS@vacn2Dr#>l_!(Ic#@put$(rX_MaUFj>4W@ zDLNGRu>ljUOj&H4P+~>SMod$Rs!JyjVxjn=kZANaL)s`prYUidMTHA(>|rQhm8`B$ zdI9c3tER8Ru*}1(gq^dE*%2eeOoCEQskCrI zC2%$evIhk<7uEHsV>e5`wPv#5v^g>*nOEfExJh%dyHvpW-4Lh^F>P+10HU_r3mJU_ z(;`f-sk;m=(hxtMipwdLW05iV!Ww}A5Q$%sx9dLlBUT;G7tC$EcbrnnkU~Aqj^ze$ zA2w!0y_z^)UN}Vi87VzUv4owvHP_~GRfck(-qi*vfxvi%uEB^F~f8tkF+rn3{j^vyB+v9l>|m? zi{+K2{nBkSLAaVRDo)=4+SlV^cb2ghZ#Aj-7EO&i`6}ZZkzeZT?YhP`9(_?whC)4t zpq2?qNI?g4Wt<)Zxn^<^sz%d)z%ey71{$a8)5^nmndez8;nHqkaF+6HzN=bqSNnj(8q}!N~5c+rzn$RUQ%^StR2ApmR;z z@E7RCu9$cr#AN9*_yazsW9p1a2zg9l`R-*k0^bA!(?%zUTjLo3P$(aTXFmz<3{9z< z-IDHq7@$x9*%L*%U(mz3Ze`qeK>EDNS)@B3aOKG{R(!gufjAvMbz@Um#&#?097hrm zE1J1)aZoq@!{nkw&o|gMFW4M;hZs7TN$%@O;q*|%W$5nk(it#qb_dQ}VlY-O9YJ#f zjLrjQdE4@_Cxk?LMukdnod3a=gEoU&$5aN|GScln!xUsJCfuOlfMC78R4J&BYWAtP z-Q-14MoJKQmxVe;3B2C5fa?#;Zar?Zd#2v?_zY#wmehrKeg}37Ah3fM%|1CS?A4QR zLf%FJ)W9>=oZ3e7UH%fhPmBw~dei*m#5!obQN0PP;(v4aV~qj0O!DX zz~o)JqhO`kVJL?+C5m7W8fD_JGXXuq^~n{$f7;?dP_&(t>HjN-c5!8je+f-- zhO?7TqgvF#;9utn@Un55C|5_f>yp+E#Ek1SLX7+MxUf=;lVuXA77yT8AFM0)vuCY7 z61*)}s%An@g84BKDwllBVRz^=3GjQ0J<19z@BoPY%g>8@V0({}y=Zlju73eZkr7al`xo>xS8hw4y?Qg(NF;af3`Vfi9j zX1M#nd=Woa=E52HE#m~Ts%C2u6j~df8^Ag!_vB0h_e&jhar|Wuf%GQU>SK|?B1mpJ zJxkd5jkI%oH7wm(YKa5%A6z9lr7wWZ=>MSicp{-O4vwLh;f^w^YLh4cz>QefT9(%`a`#g><%WJU+r_#8pcjDSqhQjhena_%K}z z>}q+u!;WM|t$)~wrho17l(+z>DcrEhP}?(9_fgRsNM;t+8IMvrJ&0jyP!<=YDzRNi zda~EeD_OS)i8Z7;S1*!{bnv_g_U{0hRq9&9_a^_7Q-#&I^Ao-B5Gg7bnFfwK!M~tB zaZ=;>-Wc?qxW!Rs3ha^NdH|*7&e1EeQcxAixx98h5^jYO4GYSqhj9K1Axyai<2Uyc z0!e}gkwMx(i2hh>vKZF6N8CZDTS0m!O5xvrGHkt{(OL?CfLHhQtU%w6eJy2~tG+?j z&P{VP4R6cWL2ae!_Kh>w+q>P&=a#X#7kNl%S0*5YZ?w^S zm|I4fN?Hc^iYDc(Qn~rfD&pOQ`!THf1j0*L?9JlM{*8X`s9+>?++64P8K7tN?8-vs zQlaN=dWdFvz%1K4G0?P5lk;Ic#7nZemX^G9;VWetl7T9dLAA8ZtGvkPW9WQSo3&|F zqR?v^2Nc)%oqzK8)MAgpaoo+vjo59v&$%7?z&c%!qG!-80anXAqKQ|>#=~ee}|;-@(b;+ zfXY=Bx`WC$A$)+_A-$$1D%;RMKyX~9vJZX@f0hF|htm`LLPVy|NC#xS=T2F%Uf6_c zMBYYb8QTmZ&=-TE)N!-sLVY_qO*5N{el#hM+KPg}h(2nm=n_8|0;)I{r$YIEcoO z)7M;t4{g_zId`qNsm?R@x=tBG@l@xPux9cB2>+WZ2K(qr(TL&GwFEaB*mNB+pzn`P zm4wTv>3em1r6>|cMtNcqNeAiB0x@UC%B(I_Lj>mhe~ejBFaj4q<&l$Uj)BRE@}aOF)#oM@K18^MV?_Vzk>XWa zlK;(O@m6{Z_K-V5ar8w8nQ)GXTH_vFZy^?GK~ac|=ZU`8OAyt`8NG^;j-`k7NjODY z7Xbw8C$JPIC+5ut7)$vbAiZUlVz#|Q4R}M$OQ08W?YIhy9V0+i@H5kPKPTn;2ucsG zV#2&|$_-yo)9(3oAu^A-j{N~>zSKG3N(pfxPl293cbH470&k$fsP!He2MwMduzRm~ zH4~0-@`m$Y$-~}mdFnNgCR2H8l{GWM6Uln!){i8~6~RYVR&-qhYs8$GgaJi!CZri} z96B8eb%qBBWPLZ6D~T0BocoDhy22lP{0YK&Mgyw3*DOl3r&Iy55g=FJ1hMh=eP-W|6Ld;AXh;#Iom0-SYyE$qCw@>K5%n!d#$5 zUk(P_Qiv(m1$eM~`?E&XZXzmoLuqE@!4%ILD)sSk??&cLCkB32!Rg)k7Zg_K+FB#@ zy$#xj!zj$Jfk8-vD8T`U$-*K+CbwO1K3MS{eBJCa=H(ojV#YTcpI2%Czr99)R zeUL3uKTOyY0-HkI!o(8&#Jz=i8k1MrDDcf&7ugr`UHDb`YuAMD7O^D`_7tl z;lxG#XW5aTS;0*V;rF-UN%vd&wyayy^bKiC-5p?uH&Fix0Rl%B%!Sck-35cUXO_TA zbZ{U>2<@&c=%E8*Q=}o3(uCz*>*gq$?!b9I^$|Po9y+H!&tpDe$K9)nlNsu< zmpI^(9bphN2|@Rh7Q^tkJA0PCz)I$NG|b_>9NOv(K_3n8+i$4}O?BK&a4wjKlrx6i z5a6%TpUv(JH(FA#av2e8JKf$%3^z?O!}GJjLvqV@=}$ z$(Fu|)J^g-KB7yCGPp9957-ByV!+pegYY4CCw?FA6>JbpRfjc~Wnp6&ljXtR4uLNu zA-W`n>Dp{sZqmarb5v%YAi8WltHb9#=3yr0dEqgt4bX`4$|W93iLl$iwz^*eiuC6i zr=86Gy^+Q3x}Kvagk%Y5a`7ZX9jps=G)ROG=CuoLdL=+^^Y|+hkxNSPWve&8FeSnK z6~M$`WHg_GUrLSa(x&~;rU)DA2%e_^P3(S`^5`%9+~7KPf%P2p6wB*pi|XMms#p53xQETF9nGH#=r7 zO$w3%2_Qh_NY_=aQ%09Fp&nmF%LG!ZSa_*p+T)d}Kc9)B(Ac?;w&<-Ff3 zKE*k`JphO)Dh+z{Mawcvkt087BbP(Ku_)g3R+)8b5=dgh+zTEH{%%e5u@u(+9B10@ zJCK;HZShl3ofLK`=2@c#GC^y@rsdheYt-@~#7T;4BQ1IwX`Ixf_(x>|`* zXk!LP*#WjBkFMG=NPCwHk@B4f0k|nkw6Z)^;K?7;ocCe9=Klnh&CvWgWt*BxF#DMb zdT6Skao6I|u(PKZC_{_lVH=cEUG*iINbi!_(_Hc55UF#UTK_`rF7uQphPQbcSQ!UM zib=Y4TZ#RB#Lp>IXgK3HUylvIAou#e!L;BZ@Ju*rDd;qviEkoHYX2?n75yY;;h9Me zAS<$qXDN-@jt2JoDJiGbWfy4 zT_#5;($aI1%t?NzT1>5q8!Jd7(wy}9)_6k!U&uhV`rgbl8(dtHo9xIH27Wee-CBg z=By&pI$hkj#oOJP_!=hJZmrEJb?V4`H%oUC&2;?wOZ7d=ds-?SZ@Hd*lD1k|JQq~- zc2CorD3I&ZU7L4(8<8egL|rkS?l~*!1Tb=4%m%BS0<{>*{T|J>+44@qAiNWWvP1i` z*Q`FlwEfb-Pzkz`+Ch8-w+`_OohEfT-uJu=WedrtYn+e0r|*@-3?^wZGy6Eb+j(|T zhA4BUL@cpvoqaHviA6dOa~7p);pj$5;ejDyP{4II&P}yIpez1x8lfZ7^hl zjgVp|x~q3@?E>ZOlHu(bTxNRtLPM*2MUwDJoKZsGzg8J8gAtRF3L^c!SF-JO{i^GZ zTg=nPKgq0P&UhEl78WJvj*nI85nX7bXRNjg(C=w`3pHEAD3fpgn>xD3 z^X8qR_wR$rUmMw6Bc_?9JYtR!r8&PT9jp)(5f2eYJ1K*;HW3XG*yt8`tx%~;2Q@mJ za@DGnh*yO2(kVGfr|HX{cZGy|^5gT)j*a=>pn?aIaRgNTomENDrUeKW9p@y zaO1yQgZiLXc`;PwHK)wDAeU-OkvlvLgUb)%-um~HTmFis zRdwcMFSTje?#-cFU+qhRkSPAVSCn!el6&8SsrbbA>7<}Ev#~-9Le!;FHnrEEPsH4>y$A7CHEm#}Mw}>e36la7e zlQjayR6nVk&VZ46z5Rq0jAk39<0y*iaLF4iJR8ozb<^uZpl%c{}VsNfK z1n}4_lmsP8ePU4S&ykw;;4{ZEW{H;4j4mt-p~TEBpAtk{6K5NnvM5B_VoY4NCBCwh zKz^=jYl#T8WK#pMi|4ui<37)bV;LRS*95~^)!sBn1~JmHQ7)arZImm?+~77*FAuI= zhHbI1h~@jlDt>Jv5ZJQr$sNQ9XiDj?WDM7Xl3(|v6-R-v+{)OZ>ux520&NRt z(&XP_LB-T(Q+UZ{OWcL$U7Ux_TadB%q}C!Hs%}`xgAZH^dzyrs%Od+%JK^T&Jck9< zS=wBR1Ha+z=X~fg@oab^kqD77SJw;sPOgIB$`Q{~h~&y{4MyJ~xbS;jgOs=%l?fgc z;TEzesFtgOyqsLXwWn0?-3Vqk>3`GtpS8S_6z(5rk9qz}84@njRbtmOpB z{SdY9ID^2WnolX=AB9{?#r0yRYXzwMU2<*nyCUp?2LRc!$qy>wmjFJ^u95^eh5byy z@yT3zGeBX{$DW;PL=3L^)4NT&$B8UqXCiV=j7+1n%6B_OB`Om#)=a5U=j=|iEX76iCwbtX)8C^0%GXLzEVuqR8>OviDm0<@J zob)^-VKMjJIP_M)2bc zV&CfMK@9Ub&U-I-ot=1WMVDuZvXS#$$ky zY6j#Ikf|%8bQ{bD3<87zViMNunD2$TY#y#292Y~Oiny1ciAn=_QKNp`a;Cm6kD7LZ zyLP|;AF$e9eJvVVU>a9(8>f@m-gn3%nrm2wOVFwUE#P$4H)cC(Lz)=_l%mvYRy!Tk zcwiM5cp(jqe<$gcwyY{loQq6hImEfw1W5~Ds8lcsyW!X-)YckOSKoWF2|xXiN|q*O zBMnNF)RMkvb`5ZEPbJ_A|Ma5{b27)yOr}8vm+CunWN<$n9ySvE03o4z&Bq>?hUz$| z##jZ)*SCC94ygF{jkezWoNiyyixqi65j?@vx4F{XomcZV3nuj`sVGbSG zkFJWkT#YLK9$-Q8|8T7sliZ|ms*RT-QM9%S_ko(k`D`nxoBo@C><1!FGtqO4OwdQ} z87r3zlsD2_KF3rO`mczz+*5jTgg~DsCj{Yh*mmn+gT~$HYq@gS5dB0)MjX5GI5hDj zv*7+R>O(au&@0_uBq>yh3y1#@%b>iPZ!YD4xdN-oK(F1scS#9Xqun{$J7w+51_X-( z>T|%hY48jzS5LnrXE|n>Go5-6`ID82rgApGEp@$Cqlb>#-R7iCn07Ctuz}MjVAaKW z)<~2vGdljmuuwPFwrmjD?h!EqCo`A1|ISiIq%QGhzACBZGdiyuefWFLZJhUYyW1m_ zdp%PtY&NR$f8Cj{p8^TSeLkJ$k5_gZ1&k38Etk#r92v7foJ0a*Ae~NlMVk_D%4Q7i zJ24=Y+>Fw&SSEGxDF>E3 zwt=^h9VXM8oShGSJyb8-hGldd4l;^Cd;#3%s9yxRq)J)zz2h@;{6|)ujYZ!D6ZxWR z^g9xF0Z$B=MfLTrvyFjf)B1*66#+jdiD!+mpd<&mGit)>D-FqB+Ire{?Clcf0NA zx71sagG?R}a0zx4(}ioe5K&6d2-17L7}3)9Pq&siw%@ku8p!_8T;Q#`Yam)-5nlTb z%45NRMr!;cie1Syn9jixq~I4Rv>;hlVgd2-qzF!1whUZ9fBm^!?uX;7JV>Hn3hzNm za`eS0LSp?5)$Z9YoZF~&rgpwllz zGbbFO&sc7+rC^wLE8a=hH~~K`g3&oK*-L+UUY(_?LOqR)t*N0}}%5WyAh?qh{ z2sK3Uw}hIh0uQFZhoF}GF%;P|b*zcyQQWEk7H6w26{TQt2(n3r85Yc&N7)mq7tl5( z1SGSNKsbEin54oXFL3z-#G;D;_AyNcKzr7cp^Yaz`>p@oNl3Dc z3St9Qom-=Sv0g1<5i(Ka;K8YQbuJRt9v2)C-xFk0RlUT1()TCt;-ZxO!IoZQ5Ml!@ zEXn`onS<>Oit6=J8lvVlj3@af&}}PoWgcY~`*~SWa}2f>IA0*|r0$+z)tI_~CW%gX z)%#s>JR?NEKrG8!TXjtz!v8Pn$w`&>s6ZFGv##jbZXNCHG$raxJl5FHx|RfxYj`xk zNBiXnY9pWB3b0t&g-dE@w%~F6VsviTB{RY2v&c>J!;uT*L{tdsW#6e#^@i0#`|FgE zmR=&yMi1yv3PMs}SxmEZy4`2WuNyNu(6(YH7>bidDv$@ahdI-l+eHS00OS;N>d)MuLlU9Xw^3-My`GriP^su;TgO~4O5(VS#eDz7|gTeco9 zb30Fw^c>I*uxwEv|Mxje0X+VWD}H}M>ji&p=cFd|GTM`<^ksC;CyJijB?zINNE~{T`gu>}<1}%~ z4kCdo((48tujK`{e#WQ-Z_HE;In&tzI%SHj!m{$gUK%<)Lng1KXp_FF+ipdY?cN2| zBI}I_^d9eR%hDwjGuKTmqF+lmWFrpy2;rd=FNG16w_ux&qb!ff?;K?_ z$*lJP}(5Z`t+yMC0{I+Slw>Oh}d)qd!P z%DM1r2A1{?qJc~J7uH@@+W-DzaL~9HDLxzvbB>sL!pitFF2k^w7|D9s8f=V~fi~iA zUp*lw7Vr8b(ARp)yYp$94uVWwSK3nwEb43Vx2a~hsp$|k%sxy>-~-tx@md|OIUYbO zycvs3k3w^QGz0MN>n#u25+7k(?pjZT2&nBJ!?b+u9x<_1G21ock*H&Mgj4Wg_pz~? zM?xKF-ZOS^epn6uR{rgdcBybfos=_k zM*8)pLwH;(Bx)vz-S4q=sf>1Mn}#x)GKqd!mn14CQ~ljE&)>A)3EtvKzqWT$fCy{! z&pdh5_e2rRCc_;8v(F!#^bvJ}q7J|Zf%TcS{u~)xepzg&O?87HH#wMwEw{q$;FlEk z|ED%2SY;Q*Ml zyn}4N{A?ef^m?e`Q#Q#}{X-N!{&HqZgH4ts3Z_brFMi?hWpWF8$fZjxEaVY#RdjyC zw^6~$zbr7+!jav%HFakFh9Q&ZV!Nll$+fI6$SJlDb^sQ8(8p1t`vYm{|6xH0~K#U__v%L_l*Nlt&Kq21}-l@Nb>Mk}#!v}xPAFnxrw zE&Kx9JpESMsX*f4japBJt2xCa=stcU0}u6no=AXGou6}=!!##N)XvDMfkw4*1HbEL z_93yeT1y_y>1(7gYKf9{`g8HOq70nAZV1y)q64>H^n=JmJN%FRnKQ(}v74eJk~Mbu z7Mr$w2cIXWcO;%?)9X*+b^2C>iRX!_FZ(NNC(CAu-I52BcXaIvD5joM^2ZHSfN~^d z%Z9y9_M}t2AW?)^HJ6wTh96XcqJ!_765=%}oSwuFt*&S4j&LP0krt_(X4DiM?8nn$ z{WFpr2vQ9a5SNuOlCVL$-$d2EE$scpho?)s3>w5HuW}(Dev9dPZ=ug#4Bg=~JzQO) zR6c9_>>g!@WANlz%v9|mFN?wzYK?~G=F4dBe|?&ud^$N`zVkss{1hoexfhE^q7}cE z^j*Kw`i6SPqk)zQ54Fq$ z$TD@BQH7XI2B6fT$MM!6z?Q&BkYTUyAV3s|M>@^1tP=NX|5O42p0c!iIO%p*RsAXe8h3o-cQ(q0@49QK$48y=tA1N8 z*T((yGuB85wdtlCS;d({x6qn&Rdv-_V0-g!>C#oAWrT<`oq`XSNs`c{5g{^bfYq#x zw+I6W{EYxPdeeV!Qcju>=#JuN5TW-dYLZ@Yb(e{#28 zF{?RaV`h!ElEbSgT~yWm>=1j{ZeDU>b4;8b!l28OTH1CQ8@=FngK#G7Aq-)#8qj5h z3u4=cql;n)4#A`cubM{x2m5icBKir5a5W=Hgr7=RC61CUF@^OMh__uNwBstMliKrs z2DtyI*M~0TtTwDe zAd#sB<=sH;*(y>p0qVKU=S)(tG2LicsA{-rbD95odI%;5nw;d!&!$0VLf=23C*`W0 zlI%J^$zgeJ+ZNSWJyxwA%Kb4U22D9FEk~|6NITKx>1&`vUHV5&5i5nUlA#)qi52Kx z{|Prml|DUu7v_X?ppWD7ShHC9-D;WUlWt5feZ-C7kaJhlKup@!aKKz`i;=6>*}Xo3 zg#TB1BH^WxDXE$ z!MS0gZT~o~bKdRgdMHz^Ac8$WC6_c4ZIiPm7u=^85ykC}MRMRmf`U zFfgMO^bPBl83xf3Y^(CK^dGZ@6+? zqK0&bW^Bi$)=Fu#=Uqn{rb+&5+I`j@d$JpoE;Mf?KRfg_^JnpBf`wiF-*w?qvlZbN zDjCLrOM^hu&*ShmrKab4t-UZOLe3Fn?tQv0F;sjH{H{DCX(4txfV zEkRhZyE7HgWxT7)Zf!>(QA{OS_E_MmA|YR&WdUtDE&tR1n8E|VDo&zD58f%`u;3zR z%g_huHTPOwsWN~kcZL=Hb8}S=0s#I%_InQN?PAT`1{iI8V`D-icqh=Oe(dxnJGbO?H%LuqTgX3R@m*3m4)r|f zC5zj{okG$&+A_ueIc3Lxot9H`PF8WmTJA&KXc>b+cccy^&AhZh^<^w5I+&qK7|r(^ zF|O?@j`nM9+YI3O(vS;%0}(5bjg=XIHr)fcgGhDaRkx zx?7U;9S`y(ONg4?-^Ev;R-}~p=H+Z5b}jtLYioV)@1@Cea^2krIBNKxT4ZXj?k?$f zb^K(|u^Ntkk*3A*R_Kp|NgF8S

QTQo+|HZ@ByG_EXr==mhtmuge;4Xri(alK&~ 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

`M8>h>T9UpW70pJ}{!e1h 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

hI^)cd=(ja+ZLc@t_so-0Z{BH9 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%0Dx>I}JdaouZ^+8ouz)5DddnTkZnR*QwPRO>E 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

    qCaZ_BO#EJE}oFo(?Z|w&f0H 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 literal 0 HcmV?d00001 diff --git a/loongarch_vars.bin b/loongarch_vars.bin new file mode 100644 index 0000000000000000000000000000000000000000..65bdb77af90b92dc268c0c5c70c054dee71599f4 GIT binary patch literal 389120 zcmeIuze+*@6bInbA98VUkd`K=h`TvRs~}|{)D)pZ4GBR@OHRsd5rT-OqN!Saf#@mf z2?AfC2k2hCx%LF|{e}bQoay(ily|GOxLK=3bfQv?`{XBo8r*dz B3V{Fs literal 0 HcmV?d00001 diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 80946fe..22f1bf3 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -55,7 +55,11 @@ %ifarch aarch64 %global kvm_target aarch64 %endif - +%ifarch loongarch64 + %global kvm_target loongarch64 + %global have_spice 1 + %global have_usbredir 1 +%endif #Versions of various parts: %global requires_all_modules \ @@ -90,7 +94,7 @@ Epoch: 15 License: GPLv2 and GPLv2+ and CC-BY Group: Development/Tools URL: http://www.qemu.org/ -ExclusiveArch: x86_64 %{power64} aarch64 s390x +ExclusiveArch: x86_64 %{power64} aarch64 s390x loongarch64 Source0: http://wiki.qemu.org/download/qemu-6.2.0.tar.xz @@ -123,6 +127,8 @@ Source37: tests_data_acpi_pc_SSDT.dimmpxm Source38: tests_data_acpi_q35_FACP.slic Source39: tests_data_acpi_q35_SSDT.dimmpxm Source40: tests_data_acpi_virt_SSDT.memhp +Source41: loongarch_bios.bin +Source42: loongarch_vars.bin Patch0001: 0001-redhat-Adding-slirp-to-the-exploded-tree.patch Patch0005: 0005-Initial-redhat-build.patch @@ -895,6 +901,16 @@ Patch366: kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch Patch1000: kvm-virtiofsd-Adjust-limit-for-minor-version.patch +Patch1001: 0001-Add-Acpi-support.patch +Patch1002: 0002-Support-rtc.patch +Patch1003: 0003-Add-loongarch-machine.patch +Patch1004: 0004-Add-target-loongarch64.patch +Patch1005: 0005-Add-linux-headers-and-linux-user.patch +Patch1006: 0006-Add-disas-gdb.patch +Patch1007: 0007-Modify-kvm-cpu-vga-qapi.patch +Patch1008: 0008-Modify-compile-script.patch +Patch1009: 0009-Add-loongarch64-rh-devices.mak.patch + BuildRequires: wget BuildRequires: rpm-build BuildRequires: ninja-build @@ -1083,7 +1099,7 @@ Requires(postun): systemd-units Requires: seabios-bin >= 1.10.2-1 Requires: sgabios-bin %endif -%ifnarch aarch64 s390x +%ifnarch aarch64 s390x loongarch64 Requires: seavgabios-bin >= 1.12.0-3 Requires: ipxe-roms-qemu >= 20170123-1 %endif @@ -1222,6 +1238,9 @@ rm -fr slirp mkdir slirp %autopatch -p1 +cp %{SOURCE41} ./pc-bios/ -f +cp %{SOURCE42} ./pc-bios/ -f + %global qemu_kvm_build qemu_kvm_build mkdir -p %{qemu_kvm_build} @@ -1691,6 +1710,8 @@ rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/opensbi-riscv64-virt-fw_jump.bin rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/opensbi-riscv64-generic-fw_dynamic.* rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/qemu-nsis.bmp rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/npcm7xx_bootrom.bin +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/loongarch_bios.bin +rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/loongarch_vars.bin rm -rf ${RPM_BUILD_ROOT}%{_libdir}/qemu-kvm/ui-spice-app.so @@ -1706,6 +1727,11 @@ rm -rf ${RPM_BUILD_ROOT}%{_mandir}/man1/virtfs-proxy-helper* rm -rf ${RPM_BUILD_ROOT}%{_libdir}/qemu-kvm/hw-s390x-virtio-gpu-ccw.so %endif +%ifarch loongarch64 + install -m 0644 pc-bios/loongarch_bios.bin $RPM_BUILD_ROOT%{_datadir}/%{name}/ + install -m 0644 pc-bios/loongarch_vars.bin $RPM_BUILD_ROOT%{_datadir}/%{name}/ +%endif + %ifnarch x86_64 rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/kvmvapic.bin rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/linuxboot.bin @@ -1807,10 +1833,12 @@ rm -rf $RPM_BUILD_ROOT%{qemudocdir}/specs popd %check +%ifnarch loongarch64 pushd %{qemu_kvm_build} echo "Testing qemu-kvm-build" export DIFF=diff; make check V=1 popd +%endif %post -n qemu-kvm-common %systemd_post ksm.service @@ -1931,6 +1959,10 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %{_datadir}/%{name}/s390-ccw.img %{_datadir}/%{name}/s390-netboot.img %endif +%ifarch loongarch64 + %{_datadir}/%{name}/loongarch_bios.bin + %{_datadir}/%{name}/loongarch_vars.bin +%endif %ifnarch aarch64 s390x %{_datadir}/%{name}/vgabios.bin %{_datadir}/%{name}/vgabios-cirrus.bin @@ -1952,7 +1984,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %ifnarch s390x %{_libdir}/%{name}/hw-display-virtio-gpu-pci-gl.so %endif -%ifarch x86_64 %{power64} +%ifarch x86_64 %{power64} loongarch64 %{_libdir}/%{name}/hw-display-virtio-vga-gl.so %endif %{_libdir}/%{name}/accel-qtest-%{kvm_target}.so @@ -2045,7 +2077,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %{_libdir}/qemu-kvm/audio-spice.so %{_libdir}/qemu-kvm/ui-spice-core.so %{_libdir}/qemu-kvm/chardev-spice.so -%ifarch x86_64 +%ifarch x86_64 loongarch64 %{_libdir}/qemu-kvm/hw-display-qxl.so %endif %endif @@ -2065,6 +2097,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %changelog * Fri Nov 08 2024 Jacob Wang - 6.2.0-53.0.1.2 - Adjust limit for virtiofsd minor version +- Add loongarch supporti (lixianglai@loongson.cn) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] -- Gitee From 03ae87533435d84defd906d70bd0b25329d49c16 Mon Sep 17 00:00:00 2001 From: Wu Hao Date: Fri, 3 Feb 2023 17:59:37 +0800 Subject: [PATCH 04/17] support qemu aarch64 user mode emulation on x86_64 Signed-off-by: Wu Hao --- qemu-kvm.spec | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 22f1bf3..2e4d7ab 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -11,6 +11,10 @@ %global have_kvm_setup 0 %global have_memlock_limits 0 +%global user_static 0 +%ifarch x86_64 +%global user_static 1 +%endif # Release candidate version tracking @@ -1019,6 +1023,10 @@ BuildRequires: pkgconfig(gbm) BuildRequires: perl-Test-Harness +%if %{user_static} +BuildRequires: glibc-static pcre-static glib2-static zlib-static +%endif + Requires: qemu-kvm-core = %{epoch}:%{version}-%{release} Requires: qemu-kvm-docs = %{epoch}:%{version}-%{release} %rhev_ma_conflicts qemu-kvm @@ -1231,6 +1239,15 @@ This package provides usbredir support. %endif +%if %{user_static} +%package -n qemu-user-static +Summary: QEMU user mode emulation of qemu targets static build +%description -n qemu-user-static +This package provides the user mode emulation of qemu targets built as +static binaries +%endif + + %prep %setup -q -n qemu-%{version}%{?rcstr} # Remove slirp content in scratchbuilds because it's being applyed as a patch @@ -1249,6 +1266,9 @@ cp -f %{SOURCE38} tests/data/acpi/q35/FACP.slic cp -f %{SOURCE39} tests/data/acpi/q35/SSDT.dimmpxm cp -f %{SOURCE40} tests/data/acpi/virt/SSDT.memhp +%global static_builddir static_builddir +mkdir -p %{static_builddir} + %build %global buildarch %{kvm_target}-softmmu @@ -1524,6 +1544,25 @@ gcc %{SOURCE35} $RPM_OPT_FLAGS $RPM_LD_FLAGS -o udev-kvm-check popd +%if %{user_static} +pushd %{static_builddir} +# add more targets here when necessary +%define static_targets aarch64-linux-user + +../configure \ + %{disable_everything} \ + --enable-docs \ + --enable-attr \ + --enable-tcg \ + --enable-linux-user \ + --target-list=%{static_targets} \ + --static + +make -j + +popd +%endif + %install pushd %{qemu_kvm_build} %define _udevdir %(pkg-config --variable=udevdir udev) @@ -1832,6 +1871,20 @@ rm -rf $RPM_BUILD_ROOT%{qemudocdir}/specs popd +%if %{user_static} +# Install qemu-user-static +mkdir -p $RPM_BUILD_ROOT%{_bindir}/ +pushd %{static_builddir} +for src in qemu-*\.*; do + rm -rf $src +done + +for src in qemu-*; do + mv $src $RPM_BUILD_ROOT%{_bindir}/$(basename $src)-static +done +popd +%endif + %check %ifnarch loongarch64 pushd %{qemu_kvm_build} @@ -2093,11 +2146,16 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %{_libdir}/qemu-kvm/hw-usb-redirect.so %endif +%if %{user_static} +%files -n qemu-user-static +%{_bindir}/qemu-aarch64-static +%endif %changelog * Fri Nov 08 2024 Jacob Wang - 6.2.0-53.0.1.2 - Adjust limit for virtiofsd minor version - Add loongarch supporti (lixianglai@loongson.cn) +- Add package qemu-user-static (fuyuan.wh@alibaba-inc.com) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] -- Gitee From cccf5c190a540efac0c5b7610f909187de86fca2 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Thu, 1 Jun 2023 05:55:20 -0400 Subject: [PATCH 05/17] Update code of loongarch. - Modify-smbios-option-lack-and-Modify-the-maximum-num.patch Loongarch supports the -smbios option and Fixed the issue that the number of QEMU VCPUs in the Loongarch architecture could not exceed the number of CPUs on the physical machine. - Support-TPM.patch Add TPM support for loonarch. - Support-vfio-config.patch Support vfio for loongarch. - pass-to-make-check.patch Fix make check fail issue. - Fix-smp.cores-value.patch Fixed CPU topology error. - Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch add fpu option. - fixup-can-t-find-cpu-type.patch Fixed the issue that the CPU type of the physical machine could not be found. - Add-lbt-support-for-kvm.patch Add lbt support for kvm. - Modify-the-ioctl-command-of-kvm.patch Modify the IOCTL command word number. - rename-kvm_msr_buf-with-kvm_csr_buf.patch - code-cleanup-for-loongarch-kvm.patch - kvm-csr-save-and-restore-optimization.patch - address-space-code-cleanup-on-7A-virt-machine.patch Code rectification optimization for loongarch. Signed-off-by: lixianglai --- Add-lbt-support-for-kvm.patch | 154 +++++ ...and-fpu-option-to-compat-with-kernel.patch | 31 + Fix-smp.cores-value.patch | 35 + ...tion-lack-and-Modify-the-maximum-num.patch | 44 ++ Modify-the-ioctl-command-of-kvm.patch | 32 + Support-TPM.patch | 518 ++++++++++++++ Support-vfio-config.patch | 47 ++ ...pace-code-cleanup-on-7A-virt-machine.patch | 276 ++++++++ code-cleanup-for-loongarch-kvm.patch | 34 + fix-smbios-type4-info-for-numa-support.patch | 44 ++ fixup-can-t-find-cpu-type.patch | 34 + kvm-csr-save-and-restore-optimization.patch | 599 ++++++++++++++++ loongarch_bios.bin | Bin 4190208 -> 4190208 bytes pass-to-make-check.patch | 164 +++++ qemu-kvm.spec | 29 + rename-kvm_msr_buf-with-kvm_csr_buf.patch | 638 ++++++++++++++++++ 16 files changed, 2679 insertions(+) create mode 100644 Add-lbt-support-for-kvm.patch create mode 100644 Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch create mode 100644 Fix-smp.cores-value.patch create mode 100644 Modify-smbios-option-lack-and-Modify-the-maximum-num.patch create mode 100644 Modify-the-ioctl-command-of-kvm.patch create mode 100644 Support-TPM.patch create mode 100644 Support-vfio-config.patch create mode 100644 address-space-code-cleanup-on-7A-virt-machine.patch create mode 100644 code-cleanup-for-loongarch-kvm.patch create mode 100644 fix-smbios-type4-info-for-numa-support.patch create mode 100644 fixup-can-t-find-cpu-type.patch create mode 100644 kvm-csr-save-and-restore-optimization.patch create mode 100644 pass-to-make-check.patch create mode 100644 rename-kvm_msr_buf-with-kvm_csr_buf.patch diff --git a/Add-lbt-support-for-kvm.patch b/Add-lbt-support-for-kvm.patch new file mode 100644 index 0000000..d2d6ef4 --- /dev/null +++ b/Add-lbt-support-for-kvm.patch @@ -0,0 +1,154 @@ +From 02aacf8cfbe627c0012bf38a007a8a8ec9f95cb5 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 08:00:52 -0400 +Subject: [PATCH 13/14] Add lbt support for kvm + +Signed-off-by: lixianglai +--- + hw/loongarch/larch_3a.c | 4 ++-- + linux-headers/asm-loongarch64/kvm.h | 10 ++++++++- + target/loongarch64/cpu.h | 10 +++++++++ + target/loongarch64/kvm.c | 35 +++++++++++++++++++++++++++++ + 4 files changed, 56 insertions(+), 3 deletions(-) + +diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c +index 8fc79546d..2affc5048 100644 +--- a/hw/loongarch/larch_3a.c ++++ b/hw/loongarch/larch_3a.c +@@ -348,8 +348,8 @@ struct kvm_cpucfg ls3a5k_cpucfgs = { + CPUCFG1_IOCSRBRD, + .cpucfg[LOONGARCH_CPUCFG2] = CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP | + CPUCFG2_FPVERS | CPUCFG2_LSX | CPUCFG2_LASX | CPUCFG2_COMPLEX | +- CPUCFG2_CRYPTO | CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | CPUCFG2_LSPW | +- CPUCFG2_LAM, ++ CPUCFG2_CRYPTO | CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | CPUCFG2_X86BT | ++ CPUCFG2_ARMBT | CPUCFG2_MIPSBT | CPUCFG2_LSPW | CPUCFG2_LAM, + .cpucfg[LOONGARCH_CPUCFG3] = CPUCFG3_CCDMA | CPUCFG3_SFB | CPUCFG3_UCACC | + CPUCFG3_LLEXC | CPUCFG3_SCDLY | CPUCFG3_LLDBAR | CPUCFG3_ITLBT | + CPUCFG3_ICACHET | CPUCFG3_SPW_LVL | CPUCFG3_SPW_HG_HF | CPUCFG3_RVA | +diff --git a/linux-headers/asm-loongarch64/kvm.h b/linux-headers/asm-loongarch64/kvm.h +index 799af7594..3687a358f 100644 +--- a/linux-headers/asm-loongarch64/kvm.h ++++ b/linux-headers/asm-loongarch64/kvm.h +@@ -77,6 +77,7 @@ struct kvm_fpu { + * Register set = 2: KVM specific registers (see definitions below). + * + * Register set = 3: FPU / MSA registers (see definitions below). ++ * Register set = 4: LBT registers (see definitions below). + * + * Other sets registers may be added in the future. Each set would + * have its own identifier in bits[31..16]. +@@ -86,7 +87,7 @@ struct kvm_fpu { + #define KVM_REG_LOONGARCH_CSR (KVM_REG_LOONGARCH | 0x0000000000010000ULL) + #define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x0000000000020000ULL) + #define KVM_REG_LOONGARCH_FPU (KVM_REG_LOONGARCH | 0x0000000000030000ULL) +- ++#define KVM_REG_LOONGARCH_LBT (KVM_REG_LOONGARCH | 0x0000000000040000ULL) + + /* + * KVM_REG_LOONGARCH_GP - General purpose registers from kvm_regs. +@@ -168,6 +169,13 @@ struct kvm_fpu { + + #define KVM_REG_LOONGARCH_VCPU_RESET (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 4) + ++#define KVM_REG_LBT_SCR0 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 1) ++#define KVM_REG_LBT_SCR1 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 2) ++#define KVM_REG_LBT_SCR2 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 3) ++#define KVM_REG_LBT_SCR3 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 4) ++#define KVM_REG_LBT_FLAGS (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 5) ++#define KVM_REG_LBT_FTOP (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 6) ++ + struct kvm_iocsr_entry { + __u32 addr; + __u32 pad; +diff --git a/target/loongarch64/cpu.h b/target/loongarch64/cpu.h +index 078556a22..ab88658e4 100644 +--- a/target/loongarch64/cpu.h ++++ b/target/loongarch64/cpu.h +@@ -55,6 +55,7 @@ typedef struct CPULOONGARCHFPUContext { + uint32_t fcsr0; + uint32_t fcsr0_rw_bitmask; + uint32_t vcsr16; ++ uint64_t ftop; + } CPULOONGARCHFPUContext; + + /* fp control and status register definition */ +@@ -167,6 +168,15 @@ struct CPULOONGARCHState { + struct { + uint64_t guest_addr; + } st; ++ struct { ++ /* scratch registers */ ++ unsigned long scr0; ++ unsigned long scr1; ++ unsigned long scr2; ++ unsigned long scr3; ++ /* loongarch eflag */ ++ unsigned long eflag; ++ } lbt; + }; + + +diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c +index b6711da91..0eaabe394 100644 +--- a/target/loongarch64/kvm.c ++++ b/target/loongarch64/kvm.c +@@ -1295,6 +1295,39 @@ int kvm_loongarch_get_pvtime(LOONGARCHCPU *cpu) + return 0; + } + ++ ++static int kvm_loongarch_put_lbt_registers(CPUState *cs) ++{ ++ int ret = 0; ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ ++ ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR0, &env->lbt.scr0); ++ ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR1, &env->lbt.scr1); ++ ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR2, &env->lbt.scr2); ++ ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR3, &env->lbt.scr3); ++ ret |= kvm_larch_putq(cs, KVM_REG_LBT_FLAGS, &env->lbt.eflag); ++ ret |= kvm_larch_putq(cs, KVM_REG_LBT_FTOP, &env->active_fpu.ftop); ++ ++ return ret; ++} ++ ++static int kvm_loongarch_get_lbt_registers(CPUState *cs) ++{ ++ int ret = 0; ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ ++ ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR0, &env->lbt.scr0); ++ ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR1, &env->lbt.scr1); ++ ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR2, &env->lbt.scr2); ++ ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR3, &env->lbt.scr3); ++ ret |= kvm_larch_getq(cs, KVM_REG_LBT_FLAGS, &env->lbt.eflag); ++ ret |= kvm_larch_getq(cs, KVM_REG_LBT_FTOP, &env->active_fpu.ftop); ++ ++ return ret; ++} ++ + int kvm_arch_put_registers(CPUState *cs, int level) + { + LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); +@@ -1326,6 +1359,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) + return ret; + } + ++ kvm_loongarch_put_lbt_registers(cs); + return ret; + } + +@@ -1352,6 +1386,7 @@ int kvm_arch_get_registers(CPUState *cs) + + kvm_loongarch_get_csr_registers(cs); + kvm_loongarch_get_fpu_registers(cs); ++ kvm_loongarch_get_lbt_registers(cs); + + return ret; + } +-- +2.27.0 + diff --git a/Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch b/Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch new file mode 100644 index 0000000..8937b8d --- /dev/null +++ b/Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch @@ -0,0 +1,31 @@ +From 889d874e72cec80244363d3c4f9594d14f05d529 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 07:38:26 -0400 +Subject: [PATCH 07/14] Fix irq routing and fpu option to compat with kernel + v6.4 + +Fix set irq routing and enable fpu for kvm to compat +with kernel v6.4 + +Signed-off-by: lixianglai +--- + target/loongarch64/kvm.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c +index 6885ec6c9..b6711da91 100644 +--- a/target/loongarch64/kvm.c ++++ b/target/loongarch64/kvm.c +@@ -107,6 +107,9 @@ int kvm_arch_init_vcpu(CPUState *cs) + CPULOONGARCHState *env = &cpu->env; + int ret = 0; + ++ kvm_vcpu_enable_cap(cs, KVM_CAP_LOONGARCH_FPU, 0, 0); ++ kvm_vcpu_enable_cap(cs, KVM_CAP_LOONGARCH_LSX, 0, 0); ++ + cpu->cpuStateEntry = qemu_add_vm_change_state_handler(kvm_loongarch_update_state, cs); + cpu->kvm_csr_buf = g_malloc0(CSR_BUF_SIZE + CSR_BUF_SIZE); + +-- +2.27.0 + diff --git a/Fix-smp.cores-value.patch b/Fix-smp.cores-value.patch new file mode 100644 index 0000000..26f4b7b --- /dev/null +++ b/Fix-smp.cores-value.patch @@ -0,0 +1,35 @@ +From 509d230669e65fd45bd3a58f3167e4a12a74877e Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 07:55:12 -0400 +Subject: [PATCH 12/14] Fix smp.cores value + +The smp.cores should use the default value passed from +qemu start command, and the argument is cores_per_socket. + +Signed-off-by: lixianglai +--- + hw/loongarch/larch_3a.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c +index b1501e0ea..8fc79546d 100644 +--- a/hw/loongarch/larch_3a.c ++++ b/hw/loongarch/larch_3a.c +@@ -1211,14 +1211,7 @@ static void loongarch_build_smbios(LoongarchMachineState *lsms) + uint8_t *smbios_tables, *smbios_anchor; + size_t smbios_tables_len, smbios_anchor_len; + const char *product = "QEMU Virtual Machine"; +- int nb_numa_nodes, smp_cpus; + +- smp_cpus = ms->smp.cpus; +- nb_numa_nodes = ms->numa_state->num_nodes; +- if (nb_numa_nodes == 0) { +- nb_numa_nodes = 1; +- } +- ms->smp.cores = smp_cpus / nb_numa_nodes; + if (!lsms->fw_cfg) { + return; + } +-- +2.27.0 + diff --git a/Modify-smbios-option-lack-and-Modify-the-maximum-num.patch b/Modify-smbios-option-lack-and-Modify-the-maximum-num.patch new file mode 100644 index 0000000..959dd7e --- /dev/null +++ b/Modify-smbios-option-lack-and-Modify-the-maximum-num.patch @@ -0,0 +1,44 @@ +From 5fb830ad315907fca8a30551c1160632001fc6fb Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 05:48:46 -0400 +Subject: [PATCH 01/14] Modify smbios option lack and Modify the maximum number + of CPUs supported by the virtual machine. + +Add smbios option support for loongarch. +The number of virtual CPUs can be greater than the number of CPUs of the host machine. + +Signed-off-by: lixianglai +--- + accel/kvm/kvm-all.c | 2 +- + qemu-options.hx | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index 8f2a53438..e7d1e9ace 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -2423,7 +2423,7 @@ static int kvm_init(MachineState *ms) + soft_vcpus_limit = kvm_recommended_vcpus(s); + hard_vcpus_limit = kvm_max_vcpus(s); + +-#ifdef HOST_PPC64 ++#if defined(HOST_PPC64) || defined(HOST_LOONGARCH) + /* + * On POWER, the kernel advertises a soft limit based on the + * number of CPU threads on the host. We want to allow exceeding +diff --git a/qemu-options.hx b/qemu-options.hx +index 4b7798088..8997969d5 100644 +--- a/qemu-options.hx ++++ b/qemu-options.hx +@@ -2480,7 +2480,7 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios, + " 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) ++ QEMU_ARCH_I386 | QEMU_ARCH_ARM | QEMU_ARCH_LOONGARCH64) + SRST + ``-smbios file=binary`` + Load SMBIOS entry from binary file. +-- +2.27.0 + diff --git a/Modify-the-ioctl-command-of-kvm.patch b/Modify-the-ioctl-command-of-kvm.patch new file mode 100644 index 0000000..9927a63 --- /dev/null +++ b/Modify-the-ioctl-command-of-kvm.patch @@ -0,0 +1,32 @@ +From 01a90be04dd6dd7edb3f49feca1ff1500ccb551b Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 08:44:26 -0400 +Subject: [PATCH 14/14] Modify the ioctl command of kvm. + +Signed-off-by: lixianglai +--- + linux-headers/linux/kvm.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index f99455294..1e6aed0fb 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -2057,10 +2057,10 @@ struct kvm_loongarch_vcpu_state { + __u64 core_ext_ioisr[4]; + }; + +-#define KVM_CAP_LOONGARCH_FPU 165 +-#define KVM_CAP_LOONGARCH_LSX 166 +-#define KVM_CAP_LOONGARCH_VZ 167 +-#define KVM_REG_LOONGARCH 0x8000000000000000ULL ++#define KVM_CAP_LOONGARCH_FPU 800 ++#define KVM_CAP_LOONGARCH_LSX 801 ++#define KVM_CAP_LOONGARCH_VZ 802 ++#define KVM_REG_LOONGARCH 0x9000000000000000ULL + #define KVM_LARCH_GET_VCPU_STATE _IOR(KVMIO, 0xc0, struct kvm_loongarch_vcpu_state) + #define KVM_LARCH_SET_VCPU_STATE _IOW(KVMIO, 0xc1, struct kvm_loongarch_vcpu_state) + #define KVM_LARCH_GET_CPUCFG _IOR(KVMIO, 0xc2, struct kvm_cpucfg) +-- +2.27.0 + diff --git a/Support-TPM.patch b/Support-TPM.patch new file mode 100644 index 0000000..6601bce --- /dev/null +++ b/Support-TPM.patch @@ -0,0 +1,518 @@ +From e7b5a4aea5499e793ef769d1c39161ab33870bb2 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 07:16:34 -0400 +Subject: [PATCH 04/14] Support TPM. + +Signed-off-by: lixianglai +--- + hw/loongarch/acpi-build.c | 44 +++++++ + hw/loongarch/larch_3a.c | 53 ++++++++- + hw/loongarch/larch_hotplug.c | 16 ++- + hw/loongarch/meson.build | 1 + + hw/loongarch/sysbus-fdt.c | 183 ++++++++++++++++++++++++++++++ + include/hw/loongarch/larch.h | 1 + + include/hw/loongarch/ls7a.h | 5 + + include/hw/loongarch/sysbus-fdt.h | 37 ++++++ + 8 files changed, 333 insertions(+), 7 deletions(-) + create mode 100644 hw/loongarch/sysbus-fdt.c + create mode 100644 include/hw/loongarch/sysbus-fdt.h + +diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c +index 6ba637be5..682e016be 100644 +--- a/hw/loongarch/acpi-build.c ++++ b/hw/loongarch/acpi-build.c +@@ -58,6 +58,7 @@ + #include "hw/acpi/aml-build.h" + #include "hw/loongarch/larch.h" + #include "hw/loongarch/ls7a.h" ++#include "hw/platform-bus.h" + + #include "hw/acpi/ipmi.h" + #include "hw/acpi/ls7a.h" +@@ -474,7 +475,40 @@ static void build_ls7a_uart_device_aml(Aml *table) + aml_append(scope, dev); + aml_append(table, scope); + } ++#ifdef CONFIG_TPM ++static void acpi_dsdt_add_tpm(Aml *scope, LoongarchMachineState *vms) ++{ ++ PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev); ++ hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS; ++ SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find()); ++ MemoryRegion *sbdev_mr; ++ hwaddr tpm_base; ++ ++ if (!sbdev) { ++ return; ++ } ++ ++ tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); ++ assert(tpm_base != -1); + ++ tpm_base += pbus_base; ++ ++ sbdev_mr = sysbus_mmio_get_region(sbdev, 0); ++ ++ Aml *dev = aml_device("TPM0"); ++ aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101"))); ++ aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device"))); ++ aml_append(dev, aml_name_decl("_UID", aml_int(0))); ++ ++ Aml *crs = aml_resource_template(); ++ aml_append(crs, ++ aml_memory32_fixed(tpm_base, ++ (uint32_t)memory_region_size(sbdev_mr), ++ AML_READ_WRITE)); ++ aml_append(dev, aml_name_decl("_CRS", crs)); ++ aml_append(scope, dev); ++} ++#endif + static void + build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) + { +@@ -500,6 +534,10 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) + aml_append(dev, aml_name_decl("_UID", aml_int(1))); + aml_append(dev, build_ls7a_osc_method()); + aml_append(sb_scope, dev); ++ ++#ifdef CONFIG_TPM ++ acpi_dsdt_add_tpm(sb_scope, lsms); ++#endif + aml_append(dsdt, sb_scope); + + build_ls7a_pci0_int(dsdt); +@@ -633,6 +671,12 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) + lsms->oem_table_id); + } + ++ if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) { ++ acpi_add_table(table_offsets, tables_blob); ++ build_tpm2(tables_blob, tables->linker, tables->tcpalog, ++ lsms->oem_id, lsms->oem_table_id); ++ } ++ + /* Build mcfg */ + acpi_add_table(table_offsets, tables_blob); + { +diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c +index 3194a822c..6c2602050 100644 +--- a/hw/loongarch/larch_3a.c ++++ b/hw/loongarch/larch_3a.c +@@ -52,6 +52,7 @@ + #include "hw/rtc/mc146818rtc.h" + #include "hw/irq.h" + #include "net/net.h" ++#include "hw/platform-bus.h" + #include "hw/timer/i8254.h" + #include "hw/loongarch/larch.h" + #include "hw/loongarch/ls7a.h" +@@ -65,6 +66,8 @@ + #include "sysemu/device_tree.h" + #include "qapi/visitor.h" + #include "qapi/qapi-visit-common.h" ++#include "sysemu/tpm.h" ++#include "hw/loongarch/sysbus-fdt.h" + + #include + +@@ -1235,6 +1238,19 @@ void loongarch_machine_done(Notifier *notifier, void *data) + { + LoongarchMachineState *lsms = container_of(notifier, + LoongarchMachineState, machine_done); ++ ++ platform_bus_add_all_fdt_nodes(lsms->fdt, NULL, ++ VIRT_PLATFORM_BUS_BASEADDRESS, ++ VIRT_PLATFORM_BUS_SIZE, ++ VIRT_PLATFORM_BUS_IRQ); ++ ++ qemu_fdt_dumpdtb(lsms->fdt, lsms->fdt_size); ++ /* load fdt */ ++ MemoryRegion *fdt_rom = g_new(MemoryRegion, 1); ++ memory_region_init_rom(fdt_rom, NULL, "fdt", LS_FDT_SIZE, &error_fatal); ++ memory_region_add_subregion(get_system_memory(), LS_FDT_BASE, fdt_rom); ++ rom_add_blob_fixed("fdt", lsms->fdt, lsms->fdt_size, LS_FDT_BASE); ++ + loongarch_acpi_setup(); + loongarch_build_smbios(lsms); + } +@@ -1562,7 +1578,31 @@ static void fdt_add_pcie_node(const LoongarchMachineState *lsms) + 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, + 2, base_mmio, 2, size_mmio); + g_free(nodename); +- qemu_fdt_dumpdtb(lsms->fdt, lsms->fdt_size); ++} ++ ++static void create_platform_bus(LoongarchMachineState *s, qemu_irq *pic) ++{ ++ DeviceState *dev; ++ SysBusDevice *sysbus; ++ int i; ++ MemoryRegion *sysmem = get_system_memory(); ++ ++ dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE); ++ dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE); ++ qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS); ++ qdev_prop_set_uint32(dev, "mmio_size", VIRT_PLATFORM_BUS_SIZE); ++ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); ++ s->platform_bus_dev = dev; ++ ++ sysbus = SYS_BUS_DEVICE(dev); ++ for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) { ++ int irq = VIRT_PLATFORM_BUS_IRQ + i; ++ sysbus_connect_irq(sysbus, i, pic[irq - LOONGARCH_PCH_IRQ_BASE]); ++ } ++ ++ memory_region_add_subregion(sysmem, ++ VIRT_PLATFORM_BUS_BASEADDRESS, ++ sysbus_mmio_get_region(sysbus, 0)); + } + + static void ls3a5k_init(MachineState *args) +@@ -1784,6 +1824,8 @@ static void ls3a5k_init(MachineState *args) + object_property_set_link(OBJECT(machine), LOONGARCH_MACHINE_ACPI_DEVICE_PROP, + OBJECT(ls7a_dev), &error_abort); + ++ create_platform_bus(lsms, ls7a_apic); ++ + #ifdef CONFIG_KVM + if (kvm_enabled()) { + kvm_direct_msi_allowed = (kvm_check_extension(kvm_state, +@@ -1835,11 +1877,6 @@ static void ls3a5k_init(MachineState *args) + + fdt_add_pcie_node(lsms); + +- /* load fdt */ +- MemoryRegion *fdt_rom = g_new(MemoryRegion, 1); +- memory_region_init_rom(fdt_rom, NULL, "fdt", LS_FDT_SIZE, &error_fatal); +- memory_region_add_subregion(get_system_memory(), LS_FDT_BASE, fdt_rom); +- rom_add_blob_fixed("fdt", lsms->fdt, lsms->fdt_size, LS_FDT_BASE); + } + + static const CPUArchIdList *loongarch_possible_cpu_arch_ids(MachineState *ms) +@@ -1986,6 +2023,10 @@ static void loongarch_class_init(ObjectClass *oc, void *data) + mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("Loongson-3A5000"); + mc->default_ram_id = "loongarch_ls3a.ram"; + ++#ifdef CONFIG_TPM ++ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); ++#endif ++ + mc->reset = ls3a_board_reset; + mc->max_cpus = LOONGARCH_MAX_VCPUS; + hc->pre_plug = loongarch_machine_device_pre_plug; +diff --git a/hw/loongarch/larch_hotplug.c b/hw/loongarch/larch_hotplug.c +index 7bce95712..bb3e9826b 100644 +--- a/hw/loongarch/larch_hotplug.c ++++ b/hw/loongarch/larch_hotplug.c +@@ -32,6 +32,7 @@ + #include "hw/loongarch/larch.h" + #include "hw/cpu/core.h" + #include "hw/nvram/fw_cfg.h" ++#include "hw/platform-bus.h" + + /* find cpu slot in machine->possible_cpus by core_id */ + static CPUArchId *loongarch_find_cpu_slot(MachineState *ms, uint32_t id, +@@ -327,7 +328,8 @@ HotplugHandler *loongarch_get_hotpug_handler(MachineState *machine, + DeviceState *dev) + { + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || +- object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { ++ object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU) || ++ object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) { + return HOTPLUG_HANDLER(machine); + } + return NULL; +@@ -346,6 +348,18 @@ void loongarch_machine_device_pre_plug(HotplugHandler *hotplug_dev, + void loongarch_machine_device_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) + { ++ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); ++ ++ if (lsms->platform_bus_dev) { ++ MachineClass *mc = MACHINE_GET_CLASS(lsms); ++ ++ if (device_is_dynamic_sysbus(mc, dev)) { ++ platform_bus_link_device( ++ PLATFORM_BUS_DEVICE(lsms->platform_bus_dev), ++ SYS_BUS_DEVICE(dev)); ++ } ++ } ++ + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + loongarch_memory_plug(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { +diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build +index 81ee99a02..47d886ddd 100644 +--- a/hw/loongarch/meson.build ++++ b/hw/loongarch/meson.build +@@ -9,6 +9,7 @@ loongarch_ss.add(files( + 'ipi.c', + 'apic.c', + 'iocsr.c', ++ 'sysbus-fdt.c', + )) + + hw_arch += {'loongarch64': loongarch_ss} +diff --git a/hw/loongarch/sysbus-fdt.c b/hw/loongarch/sysbus-fdt.c +new file mode 100644 +index 000000000..f750ad6b6 +--- /dev/null ++++ b/hw/loongarch/sysbus-fdt.c +@@ -0,0 +1,183 @@ ++/* ++ * Loongarch Platform Bus device tree generation helpers ++ * ++ * Copyright (c) 2014 Linaro Limited ++ * ++ * Authors: ++ * Alex Graf ++ * Eric Auger ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2 or later, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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 . ++ * ++ */ ++ ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include ++#include "qemu/error-report.h" ++#include "sysemu/device_tree.h" ++#include "hw/platform-bus.h" ++#include "hw/display/ramfb.h" ++#include "hw/loongarch/sysbus-fdt.h" ++#include "sysemu/tpm.h" ++ ++/* ++ * internal struct that contains the information to create dynamic ++ * sysbus device node ++ */ ++typedef struct PlatformBusFDTData { ++ void *fdt; /* device tree handle */ ++ int irq_start; /* index of the first IRQ usable by platform bus devices */ ++ const char *pbus_node_name; /* name of the platform bus node */ ++ PlatformBusDevice *pbus; ++} PlatformBusFDTData; ++ ++/* struct that allows to match a device and create its FDT node */ ++typedef struct BindingEntry { ++ const char *typename; ++ const char *compat; ++ int (*add_fn)(SysBusDevice *sbdev, void *opaque); ++ bool (*match_fn)(SysBusDevice *sbdev, const struct BindingEntry *combo); ++} BindingEntry; ++ ++ ++ ++static int no_fdt_node(SysBusDevice *sbdev, void *opaque) ++{ ++ return 0; ++} ++ ++/* Device type based matching */ ++static bool type_match(SysBusDevice *sbdev, const BindingEntry *entry) ++{ ++ return !strcmp(object_get_typename(OBJECT(sbdev)), entry->typename); ++} ++ ++#define TYPE_BINDING(type, add_fn) {(type), NULL, (add_fn), NULL} ++ ++#ifdef CONFIG_TPM ++/* ++ * add_tpm_tis_fdt_node: Create a DT node for TPM TIS ++ * ++ * See kernel documentation: ++ * Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt ++ * Optional interrupt for command completion is not exposed ++ */ ++static int add_tpm_tis_fdt_node(SysBusDevice *sbdev, void *opaque) ++{ ++ PlatformBusFDTData *data = opaque; ++ PlatformBusDevice *pbus = data->pbus; ++ void *fdt = data->fdt; ++ const char *parent_node = data->pbus_node_name; ++ char *nodename; ++ uint32_t reg_attr[2]; ++ uint64_t mmio_base; ++ ++ mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); ++ nodename = g_strdup_printf("%s/tpm_tis@%" PRIx64, parent_node, mmio_base); ++ qemu_fdt_add_subnode(fdt, nodename); ++ ++ qemu_fdt_setprop_string(fdt, nodename, "compatible", "tcg,tpm-tis-mmio"); ++ ++ reg_attr[0] = cpu_to_be32(mmio_base); ++ reg_attr[1] = cpu_to_be32(0x5000); ++ qemu_fdt_setprop(fdt, nodename, "reg", reg_attr, 2 * sizeof(uint32_t)); ++ ++ g_free(nodename); ++ ++ return 0; ++} ++#endif ++ ++/* list of supported dynamic sysbus bindings */ ++static const BindingEntry bindings[] = { ++#ifdef CONFIG_TPM ++ TYPE_BINDING(TYPE_TPM_TIS_SYSBUS, add_tpm_tis_fdt_node), ++#endif ++ TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node), ++ TYPE_BINDING("", NULL), /* last element */ ++}; ++ ++/* Generic Code */ ++ ++/** ++ * add_fdt_node - add the device tree node of a dynamic sysbus device ++ * ++ * @sbdev: handle to the sysbus device ++ * @opaque: handle to the PlatformBusFDTData ++ * ++ * Checks the sysbus type belongs to the list of device types that ++ * are dynamically instantiable and if so call the node creation ++ * function. ++ */ ++static void add_fdt_node(SysBusDevice *sbdev, void *opaque) ++{ ++ int i, ret; ++ ++ for (i = 0; i < ARRAY_SIZE(bindings); i++) { ++ const BindingEntry *iter = &bindings[i]; ++ ++ if (type_match(sbdev, iter)) { ++ if (!iter->match_fn || iter->match_fn(sbdev, iter)) { ++ ret = iter->add_fn(sbdev, opaque); ++ assert(!ret); ++ return; ++ } ++ } ++ } ++ error_report("Device %s can not be dynamically instantiated", ++ qdev_fw_name(DEVICE(sbdev))); ++ exit(1); ++} ++ ++void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr, ++ hwaddr bus_size, int irq_start) ++{ ++ const char platcomp[] = "qemu,platform\0simple-bus"; ++ PlatformBusDevice *pbus; ++ DeviceState *dev; ++ gchar *node; ++ ++ assert(fdt); ++ ++ node = g_strdup_printf("/platform@%"PRIx64, addr); ++ ++ /* Create a /platform node that we can put all devices into */ ++ qemu_fdt_add_subnode(fdt, node); ++ qemu_fdt_setprop(fdt, node, "compatible", platcomp, sizeof(platcomp)); ++ ++ /* ++ * Our platform bus region is less than 32bits, so 1 cell is enough for ++ * address and size ++ */ ++ qemu_fdt_setprop_cells(fdt, node, "#size-cells", 1); ++ qemu_fdt_setprop_cells(fdt, node, "#address-cells", 1); ++ qemu_fdt_setprop_cells(fdt, node, "ranges", 0, addr >> 32, addr, bus_size); ++ if (intc != NULL) { ++ qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", intc); ++ } ++ dev = qdev_find_recursive(sysbus_get_default(), TYPE_PLATFORM_BUS_DEVICE); ++ pbus = PLATFORM_BUS_DEVICE(dev); ++ ++ PlatformBusFDTData data = { ++ .fdt = fdt, ++ .irq_start = irq_start, ++ .pbus_node_name = node, ++ .pbus = pbus, ++ }; ++ ++ /* Loop through all dynamic sysbus devices and create their node */ ++ foreach_dynamic_sysbus_device(add_fdt_node, &data); ++ ++ g_free(node); ++} +diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h +index 62e2830e2..81dcb78f4 100644 +--- a/include/hw/loongarch/larch.h ++++ b/include/hw/loongarch/larch.h +@@ -103,6 +103,7 @@ typedef struct LoongarchMachineState { + void *fdt; + int fdt_size; + unsigned int hotpluged_cpu_num; ++ DeviceState *platform_bus_dev; + OnOffAuto acpi; + char *oem_id; + char *oem_table_id; +diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h +index 686af763a..fc78083be 100644 +--- a/include/hw/loongarch/ls7a.h ++++ b/include/hw/loongarch/ls7a.h +@@ -121,6 +121,11 @@ + #define INT_ROUTER_REGS_CORE2_INTISR 0x50 + #define INT_ROUTER_REGS_CORE3_INTISR 0x58 + ++#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000 ++#define VIRT_PLATFORM_BUS_SIZE 0x2000000 ++#define VIRT_PLATFORM_BUS_NUM_IRQS 2 ++#define VIRT_PLATFORM_BUS_IRQ 69 ++ + typedef struct LS7APCIState LS7APCIState; + typedef struct LS7APCIEHost { + PCIExpressHost parent_obj; +diff --git a/include/hw/loongarch/sysbus-fdt.h b/include/hw/loongarch/sysbus-fdt.h +new file mode 100644 +index 000000000..340c382cd +--- /dev/null ++++ b/include/hw/loongarch/sysbus-fdt.h +@@ -0,0 +1,37 @@ ++/* ++ * Dynamic sysbus device tree node generation API ++ * ++ * Copyright Linaro Limited, 2014 ++ * ++ * Authors: ++ * Alex Graf ++ * Eric Auger ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2 or later, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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 . ++ * ++ */ ++ ++#ifndef HW_ARM_SYSBUS_FDT_H ++#define HW_ARM_SYSBUS_FDT_H ++ ++#include "exec/hwaddr.h" ++ ++/** ++ * platform_bus_add_all_fdt_nodes - create all the platform bus nodes ++ * ++ * builds the parent platform bus node and all the nodes of dynamic ++ * sysbus devices attached to it. ++ */ ++void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr, ++ hwaddr bus_size, int irq_start); ++#endif +-- +2.27.0 + diff --git a/Support-vfio-config.patch b/Support-vfio-config.patch new file mode 100644 index 0000000..6ae48b9 --- /dev/null +++ b/Support-vfio-config.patch @@ -0,0 +1,47 @@ +From 16268ffb6e5abbb5369a6a6bda9c60cd5fff22c9 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 07:41:14 -0400 +Subject: [PATCH 08/14] Support vfio config + +Signed-off-by: lixianglai +--- + configs/devices/loongarch64-softmmu/default.mak | 9 +++++++++ + .../loongarch64-softmmu/loongarch64-rh-devices.mak | 8 ++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/configs/devices/loongarch64-softmmu/default.mak b/configs/devices/loongarch64-softmmu/default.mak +index fcb7e45dd..b4994d8a6 100644 +--- a/configs/devices/loongarch64-softmmu/default.mak ++++ b/configs/devices/loongarch64-softmmu/default.mak +@@ -152,3 +152,12 @@ CONFIG_PLATFORM_BUS=y + CONFIG_TPM_TIS_SYSBUS=y + CONFIG_ACPI_LOONGARCH=y + CONFIG_LS7A_RTC=y ++ ++#vfio config ++CONFIG_VFIO=y ++CONFIG_VFIO_PCI=y ++CONFIG_VFIO_PLATFORM=y ++CONFIG_VFIO_XGMAC=y ++CONFIG_VFIO_AMD_XGBE=y ++ ++ +diff --git a/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak +index e7b5bdc8e..696ee9b72 100644 +--- a/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak ++++ b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak +@@ -153,3 +153,11 @@ CONFIG_PLATFORM_BUS=y + CONFIG_TPM_TIS_SYSBUS=y + CONFIG_ACPI_LOONGARCH=y + CONFIG_LS7A_RTC=y ++ ++#vfio config ++CONFIG_VFIO=y ++CONFIG_VFIO_PCI=y ++CONFIG_VFIO_PLATFORM=y ++CONFIG_VFIO_XGMAC=y ++CONFIG_VFIO_AMD_XGBE=y ++ +-- +2.27.0 + diff --git a/address-space-code-cleanup-on-7A-virt-machine.patch b/address-space-code-cleanup-on-7A-virt-machine.patch new file mode 100644 index 0000000..1e64b4c --- /dev/null +++ b/address-space-code-cleanup-on-7A-virt-machine.patch @@ -0,0 +1,276 @@ +From fe4009a9b0ddc2058793d3dc782778c95164ef39 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 07:33:26 -0400 +Subject: [PATCH 06/14] address space code cleanup on 7A virt-machine. + +Signed-off-by: lixianglai +--- + hw/loongarch/larch_3a.c | 16 +++----- + hw/loongarch/ls7a_nb.c | 49 ------------------------- + include/hw/loongarch/larch.h | 1 - + include/hw/loongarch/ls7a.h | 71 ++++++++++++++++-------------------- + 4 files changed, 37 insertions(+), 100 deletions(-) + +diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c +index 6c2602050..6eaa53d74 100644 +--- a/hw/loongarch/larch_3a.c ++++ b/hw/loongarch/larch_3a.c +@@ -88,10 +88,8 @@ + + #ifdef CONFIG_KVM + #define LS_ISA_IO_SIZE 0x02000000 +-#define LS_ISA_MEM_SIZE 0x40000000 + #else + #define LS_ISA_IO_SIZE 0x00010000 +-#define LS_ISA_MEM_SIZE 0x01000000 + #endif + + #ifdef CONFIG_KVM +@@ -626,8 +624,8 @@ static struct irq_source_routing_table *init_irq_source(void *g_irq_source) + irq_info->ht_enable = 0x0000d17b; + irq_info->node_id = 0; + +- irq_info->pci_mem_start_addr = LS_ISA_MEM_BASE; +- irq_info->pci_mem_end_addr = irq_info->pci_mem_start_addr + LS_ISA_MEM_SIZE - 1; ++ irq_info->pci_mem_start_addr = PCIE_MEMORY_BASE; ++ irq_info->pci_mem_end_addr = irq_info->pci_mem_start_addr + PCIE_MEMORY_SIZE - 1; + + if (strstr(lsmc->cpu_name, "5000")) { + irq_info->pci_io_start_addr = LS3A5K_ISA_IO_BASE; +@@ -1551,8 +1549,8 @@ static void fdt_add_fw_cfg_node(const LoongarchMachineState *lsms) + static void fdt_add_pcie_node(const LoongarchMachineState *lsms) + { + char *nodename; +- hwaddr base_mmio = LS_ISA_MEM_BASE; +- hwaddr size_mmio = LS_ISA_MEM_SIZE; ++ hwaddr base_mmio = PCIE_MEMORY_BASE; ++ hwaddr size_mmio = PCIE_MEMORY_SIZE; + hwaddr base_pio = LS3A5K_ISA_IO_BASE; + hwaddr size_pio = LS_ISA_IO_SIZE; + hwaddr base_pcie = LS_PCIECFG_BASE; +@@ -1650,7 +1648,6 @@ static void ls3a5k_init(MachineState *args) + create_fdt(lsms); + + DPRINTF("isa 0x%lx\n", lsmc->isa_io_base); +- DPRINTF("ht1lo 0x%lx\n", lsmc->ht1lo_pcicfg_base); + DPRINTF("cpu_name %s bridge_name %s\n", + lsmc->cpu_name, lsmc->bridge_name); + +@@ -1800,9 +1797,9 @@ static void ls3a5k_init(MachineState *args) + + memory_region_init_alias(isa_io, NULL, "isa-io", + get_system_io(), 0, LS_ISA_IO_SIZE); +- memory_region_init(isa_mem, NULL, "isa-mem", LS_ISA_MEM_SIZE); ++ memory_region_init(isa_mem, NULL, "isa-mem", PCIE_MEMORY_SIZE); + memory_region_add_subregion(get_system_memory(), lsmc->isa_io_base, isa_io); +- memory_region_add_subregion(get_system_memory(), LS_ISA_MEM_BASE, isa_mem); ++ memory_region_add_subregion(get_system_memory(), PCIE_MEMORY_BASE, isa_mem); + + if (!strcmp(lsmc->bridge_name, "ls7a")) { + /*Initialize the 7A IO interrupt subsystem*/ +@@ -1950,7 +1947,6 @@ static void ls3a5k_ls7a_machine_options(MachineClass *m) + m->alias = "loongson7a"; + m->is_default = 1; + lsmc->isa_io_base = LS3A5K_ISA_IO_BASE; +- lsmc->ht1lo_pcicfg_base = LS3A5K_HT1LO_PCICFG_BASE; + lsmc->pciecfg_base = LS_PCIECFG_BASE; + lsmc->ls7a_ioapic_reg_base = LS3A5K_LS7A_IOAPIC_REG_BASE; + lsmc->node_shift = 44; +diff --git a/hw/loongarch/ls7a_nb.c b/hw/loongarch/ls7a_nb.c +index 5a500fbd5..5a231e6f0 100644 +--- a/hw/loongarch/ls7a_nb.c ++++ b/hw/loongarch/ls7a_nb.c +@@ -108,7 +108,6 @@ static const VMStateDescription vmstate_ls7a_pcie = { + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(dev, LS7APCIState), + VMSTATE_STRUCT(pm, LS7APCIState, 0, vmstate_ls7a_pm, LS7APCIPMRegs), +- VMSTATE_UINT32_ARRAY(regs, LS7APCIState, LS7A_REGS), + VMSTATE_END_OF_LIST() + } + }; +@@ -153,47 +152,6 @@ static void ls7a_pcie_realize(PCIDevice *dev, Error **errp) + qemu_register_reset(ls7a_reset, s); + } + +-static void pci_ls7a_config_write(void *opaque, hwaddr addr, +- uint64_t val, unsigned size) +-{ +- hwaddr tmp_addr; +- tmp_addr = addr & 0xffffff; +- +- pci_data_write(opaque, tmp_addr, val, size); +-} +- +-static uint64_t pci_ls7a_config_read(void *opaque, +- hwaddr addr, unsigned size) +-{ +- uint64_t val; +- hwaddr tmp_addr; +- +- tmp_addr = addr & 0xffffff; +- val = pci_data_read(opaque, tmp_addr, size); +- +- if (addr & 0x3c) { +- DPRINTF(TARGET_FMT_plx" val %lx\n", addr, val); +- } +- return val; +-} +- +-static const MemoryRegionOps pci_ls7a_config_ops = { +- .read = pci_ls7a_config_read, +- .write = pci_ls7a_config_write, +- /* Set to access 64bits data, because default to 32bits*/ +- .valid = { +- .min_access_size = 1, +- .max_access_size = 4, +- }, +- /* Set to access 64bits data, because default to 32bits*/ +- .impl = { +- .min_access_size = 1, +- .max_access_size = 4, +- }, +- .endianness = DEVICE_NATIVE_ENDIAN, +- +-}; +- + static AddressSpace *ls7a_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) + { + return &address_space_memory; +@@ -205,12 +163,9 @@ static PCIBus *pci_ls7a_init(MachineState *machine, DeviceState *dev, + LoongarchMachineState *lsms = LoongarchMACHINE(machine); + LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); + PCIExpressHost *e; +- SysBusDevice *sysbus; +- MemoryRegion *iomem = g_new(MemoryRegion, 1); + PCIHostState *phb; + + e = PCIE_HOST_BRIDGE(dev); +- sysbus = SYS_BUS_DEVICE(e); + phb = PCI_HOST_BRIDGE(e); + phb->bus = pci_register_root_bus(dev, "pcie.0", pci_ls7a_set_irq, + pci_ls7a_map_irq, pic, +@@ -220,10 +175,6 @@ static PCIBus *pci_ls7a_init(MachineState *machine, DeviceState *dev, + DPRINTF("------ %d\n", __LINE__); + + pci_bus_set_route_irq_fn(phb->bus, ls7a_route_intx_pin_to_irq); +- memory_region_init_io(iomem, NULL, &pci_ls7a_config_ops, phb->bus, +- "ls7a_pci_conf", HT1LO_PCICFG_SIZE); +- sysbus_init_mmio(sysbus, iomem); +- sysbus_mmio_map(sysbus, 0, lsmc->ht1lo_pcicfg_base); + + return phb->bus; + } +diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h +index 81dcb78f4..b8f28e330 100644 +--- a/include/hw/loongarch/larch.h ++++ b/include/hw/loongarch/larch.h +@@ -64,7 +64,6 @@ typedef struct LoongarchMachineClass { + uint64_t ht_control_regs_base; + uint64_t hpet_mmio_addr; + uint64_t smbus_cfg_base; +- uint64_t ht1lo_pcicfg_base; + uint64_t pciecfg_base; + uint64_t ls7a_ioapic_reg_base; + uint32_t node_shift; +diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h +index fc78083be..63a070296 100644 +--- a/include/hw/loongarch/ls7a.h ++++ b/include/hw/loongarch/ls7a.h +@@ -39,44 +39,33 @@ + #define ACPI_IO_SIZE (LS7A_ACPI_IO_SIZE) + #define ACPI_SCI_IRQ (LS7A_SCI_IRQ) + +-#define LS3A5K_ISA_IO_BASE 0x18000000UL +-#define LS_ISA_MEM_BASE 0x40000000 +-#define LS3A5K_HT1LO_PCICFG_BASE 0x1a000000 +-#define HT1LO_PCICFG_SIZE 0x02000000 ++#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000 ++#define VIRT_PLATFORM_BUS_SIZE 0x02000000 ++#define VIRT_PLATFORM_BUS_NUM_IRQS 2 ++#define VIRT_PLATFORM_BUS_IRQ (LOONGARCH_PCH_IRQ_BASE + 5) ++ ++#define LS3A5K_ISA_IO_BASE 0x18000000UL + #define LS_BIOS_BASE 0x1c000000 + #define LS_BIOS_VAR_BASE 0x1c3a0000 +-#define LS_BIOS_SIZE (4 * 1024 * 1024) +- +-#define FW_CFG_ADDR 0x1e020000 +-#define LS7A_REG_BASE 0x1FE00000 +-#define LS7A_PCICONFIG_BASE (LS7A_REG_BASE + 0x30) +-#define LS7A_PCICONFIG_SIZE (0x100) +-#define LS7A_INTERNAL_REG_BASE (LS7A_REG_BASE + 0x100) +-#define LS7A_INTERNAL_REG_SIZE (0xE0) +-#define LS7A_REGS (0xE0 >> 2) +-#define LS7A_UART_BASE 0x1fe001e0 +-#define LS7A_UART_LEN 0x8 +- +-#define LS_FDT_BASE 0x1c400000 +-#define LS_FDT_SIZE 0x100000 +- +-#define LS_PCIECFG_BASE 0x20000000 +-#define LS_PCIECFG_SIZE 0x08000000 +-#define MSI_ADDR_LOW 0x2FF00000 +-#define MSI_ADDR_HI 0x0 +- ++#define LS_BIOS_SIZE (4 * 1024 * 1024) ++#define LS_FDT_BASE 0x1c400000 ++#define LS_FDT_SIZE 0x00100000 ++ ++#define FW_CFG_ADDR 0x1e020000 ++#define LS7A_REG_BASE 0x1FE00000 ++#define LS7A_UART_BASE 0x1fe001e0 ++#define LS7A_UART_LEN 0x8 + #define SMP_GIPI_MAILBOX 0x1f000000ULL +-#define CORE0_STATUS_OFF 0x000 +-#define CORE0_EN_OFF 0x004 +-#define CORE0_SET_OFF 0x008 +-#define CORE0_CLEAR_OFF 0x00c +-#define CORE0_BUF_20 0x020 +-#define CORE0_BUF_28 0x028 +-#define CORE0_BUF_30 0x030 +-#define CORE0_BUF_38 0x038 +-#define CORE0_IPI_SEND 0x040 +-#define CORE0_MAIL_SEND 0x048 +- ++#define CORE0_STATUS_OFF 0x000 ++#define CORE0_EN_OFF 0x004 ++#define CORE0_SET_OFF 0x008 ++#define CORE0_CLEAR_OFF 0x00c ++#define CORE0_BUF_20 0x020 ++#define CORE0_BUF_28 0x028 ++#define CORE0_BUF_30 0x030 ++#define CORE0_BUF_38 0x038 ++#define CORE0_IPI_SEND 0x040 ++#define CORE0_MAIL_SEND 0x048 + #define INT_ROUTER_REGS_BASE 0x1fe01400UL + #define INT_ROUTER_REGS_SIZE 0x100 + #define INT_ROUTER_REGS_SYS_INT0 0x00 +@@ -121,10 +110,13 @@ + #define INT_ROUTER_REGS_CORE2_INTISR 0x50 + #define INT_ROUTER_REGS_CORE3_INTISR 0x58 + +-#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000 +-#define VIRT_PLATFORM_BUS_SIZE 0x2000000 +-#define VIRT_PLATFORM_BUS_NUM_IRQS 2 +-#define VIRT_PLATFORM_BUS_IRQ 69 ++#define LS_PCIECFG_BASE 0x20000000 ++#define LS_PCIECFG_SIZE 0x08000000 ++#define MSI_ADDR_LOW 0x2FF00000 ++#define MSI_ADDR_HI 0x0 ++ ++#define PCIE_MEMORY_BASE 0x40000000 ++#define PCIE_MEMORY_SIZE 0x40000000 + + typedef struct LS7APCIState LS7APCIState; + typedef struct LS7APCIEHost { +@@ -136,7 +128,6 @@ struct LS7APCIState { + PCIDevice dev; + + LS7APCIEHost *pciehost; +- uint32_t regs[LS7A_REGS]; + + /* LS7A registers */ + MemoryRegion iomem; +-- +2.27.0 + diff --git a/code-cleanup-for-loongarch-kvm.patch b/code-cleanup-for-loongarch-kvm.patch new file mode 100644 index 0000000..a4bbf4b --- /dev/null +++ b/code-cleanup-for-loongarch-kvm.patch @@ -0,0 +1,34 @@ +From 1ab7b25cd4b5d827e8b04c981293b135059681ad Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 07:04:10 -0400 +Subject: [PATCH 03/14] code cleanup for loongarch kvm. + +Signed-off-by: lixianglai +--- + linux-headers/asm-loongarch64/kvm.h | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +diff --git a/linux-headers/asm-loongarch64/kvm.h b/linux-headers/asm-loongarch64/kvm.h +index a24375ee5..799af7594 100644 +--- a/linux-headers/asm-loongarch64/kvm.h ++++ b/linux-headers/asm-loongarch64/kvm.h +@@ -72,15 +72,7 @@ struct kvm_fpu { + * + * Register set = 0: GP registers from kvm_regs (see definitions below). + * +- * Register set = 1: CP0 registers. +- * bits[15..8] - COP0 register set. +- * +- * COP0 register set = 0: Main CP0 registers. +- * bits[7..3] - Register 'rd' index. +- * bits[2..0] - Register 'sel' index. +- * +- * COP0 register set = 1: MAARs. +- * bits[7..0] - MAAR index. ++ * Register set = 1: CSR registers. + * + * Register set = 2: KVM specific registers (see definitions below). + * +-- +2.27.0 + diff --git a/fix-smbios-type4-info-for-numa-support.patch b/fix-smbios-type4-info-for-numa-support.patch new file mode 100644 index 0000000..948aab7 --- /dev/null +++ b/fix-smbios-type4-info-for-numa-support.patch @@ -0,0 +1,44 @@ +From d68ddb24ed08459b9641615e00cec50e6d025a5e Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 07:53:36 -0400 +Subject: [PATCH 11/14] fix smbios type4 info for numa support. + +Signed-off-by: lixianglai +--- + hw/loongarch/larch_3a.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c +index 5e271f339..b1501e0ea 100644 +--- a/hw/loongarch/larch_3a.c ++++ b/hw/loongarch/larch_3a.c +@@ -1211,8 +1211,14 @@ static void loongarch_build_smbios(LoongarchMachineState *lsms) + uint8_t *smbios_tables, *smbios_anchor; + size_t smbios_tables_len, smbios_anchor_len; + const char *product = "QEMU Virtual Machine"; +- ms->smp.cores = 4; ++ int nb_numa_nodes, smp_cpus; + ++ smp_cpus = ms->smp.cpus; ++ nb_numa_nodes = ms->numa_state->num_nodes; ++ if (nb_numa_nodes == 0) { ++ nb_numa_nodes = 1; ++ } ++ ms->smp.cores = smp_cpus / nb_numa_nodes; + if (!lsms->fw_cfg) { + return; + } +@@ -2004,6 +2010,10 @@ static int64_t ls3a_get_default_cpu_node_id(const MachineState *ms, int idx) + { + int nb_numa_nodes = ms->numa_state->num_nodes; + int smp_cores = ms->smp.cores; ++ ++ if (nb_numa_nodes == 0) { ++ nb_numa_nodes = 1; ++ } + return idx / smp_cores % nb_numa_nodes; + } + +-- +2.27.0 + diff --git a/fixup-can-t-find-cpu-type.patch b/fixup-can-t-find-cpu-type.patch new file mode 100644 index 0000000..b9dbf89 --- /dev/null +++ b/fixup-can-t-find-cpu-type.patch @@ -0,0 +1,34 @@ +From e2d6998cad687af9d0efcc54139b28b0ff990b57 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 07:51:55 -0400 +Subject: [PATCH 10/14] fixup can't find cpu type. + +Signed-off-by: lixianglai +--- + hw/loongarch/larch_3a.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c +index f83bd3750..5e271f339 100644 +--- a/hw/loongarch/larch_3a.c ++++ b/hw/loongarch/larch_3a.c +@@ -547,7 +547,15 @@ static char *get_host_cpu_model_name(void) + fprintf(stderr, "read err...\n"); + } + close(fd); +- buf_p = strstr(buf, "name"); ++ buf_p = strstr(buf, "Name"); ++ if (!buf_p) { ++ buf_p = strstr(buf, "name"); ++ } ++ if (!buf_p) { ++ fprintf(stderr, "Can't find cpu name\n"); ++ return 0; ++ } ++ + + while (*buf_p != ':') { + buf_p++; +-- +2.27.0 + diff --git a/kvm-csr-save-and-restore-optimization.patch b/kvm-csr-save-and-restore-optimization.patch new file mode 100644 index 0000000..8a60998 --- /dev/null +++ b/kvm-csr-save-and-restore-optimization.patch @@ -0,0 +1,599 @@ +From d28802932e2379a474e86010581390dbacfab8f2 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 07:25:52 -0400 +Subject: [PATCH 05/14] kvm csr save and restore optimization. + +Signed-off-by: lixianglai +--- + target/loongarch64/kvm.c | 547 +++++++++++---------------------------- + 1 file changed, 153 insertions(+), 394 deletions(-) + +diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c +index b5c655812..6885ec6c9 100644 +--- a/target/loongarch64/kvm.c ++++ b/target/loongarch64/kvm.c +@@ -95,19 +95,165 @@ int kvm_arch_irqchip_create(KVMState *s) + return 0; + } + ++static void kvm_csr_set_addr(uint64_t **addr, uint32_t index, uint64_t *p) ++{ ++ addr[index] = p; ++} ++ + int kvm_arch_init_vcpu(CPUState *cs) + { + LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ uint64_t **addr; ++ CPULOONGARCHState *env = &cpu->env; + int ret = 0; + + cpu->cpuStateEntry = qemu_add_vm_change_state_handler(kvm_loongarch_update_state, cs); +- cpu->kvm_csr_buf = g_malloc0(CSR_BUF_SIZE); ++ cpu->kvm_csr_buf = g_malloc0(CSR_BUF_SIZE + CSR_BUF_SIZE); ++ ++ addr = (void *)cpu->kvm_csr_buf + CSR_BUF_SIZE; ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_CRMD, &env->CSR_CRMD); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PRMD, &env->CSR_PRMD); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_EUEN, &env->CSR_EUEN); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_MISC, &env->CSR_MISC); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_ECFG, &env->CSR_ECFG); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_ESTAT, &env->CSR_ESTAT); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERA, &env->CSR_ERA); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_BADV, &env->CSR_BADV); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_BADI, &env->CSR_BADI); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_EEPN, &env->CSR_EEPN); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBIDX, &env->CSR_TLBIDX); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBEHI, &env->CSR_TLBEHI); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBELO0, &env->CSR_TLBELO0); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBELO1, &env->CSR_TLBELO1); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_GTLBC, &env->CSR_GTLBC); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TRGP, &env->CSR_TRGP); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_ASID, &env->CSR_ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PGDL, &env->CSR_PGDL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PGDH, &env->CSR_PGDH); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PGD, &env->CSR_PGD); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PWCTL0, &env->CSR_PWCTL0); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PWCTL1, &env->CSR_PWCTL1); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_STLBPGSIZE, &env->CSR_STLBPGSIZE); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_RVACFG, &env->CSR_RVACFG); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_CPUID, &env->CSR_CPUID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PRCFG1, &env->CSR_PRCFG1); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PRCFG2, &env->CSR_PRCFG2); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PRCFG3, &env->CSR_PRCFG3); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS0, &env->CSR_KS0); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS1, &env->CSR_KS1); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS2, &env->CSR_KS2); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS3, &env->CSR_KS3); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS4, &env->CSR_KS4); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS5, &env->CSR_KS5); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS6, &env->CSR_KS6); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS7, &env->CSR_KS7); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TMID, &env->CSR_TMID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_CNTC, &env->CSR_CNTC); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TINTCLR, &env->CSR_TINTCLR); ++ ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_GSTAT, &env->CSR_GSTAT); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_GCFG, &env->CSR_GCFG); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_GINTC, &env->CSR_GINTC); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_GCNTC, &env->CSR_GCNTC); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_LLBCTL, &env->CSR_LLBCTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IMPCTL1, &env->CSR_IMPCTL1); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IMPCTL2, &env->CSR_IMPCTL2); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_GNMI, &env->CSR_GNMI); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRENT, &env->CSR_TLBRENT); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRBADV, &env->CSR_TLBRBADV); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRERA, &env->CSR_TLBRERA); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRSAVE, &env->CSR_TLBRSAVE); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRELO0, &env->CSR_TLBRELO0); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRELO1, &env->CSR_TLBRELO1); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBREHI, &env->CSR_TLBREHI); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRPRMD, &env->CSR_TLBRPRMD); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRCTL, &env->CSR_ERRCTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRINFO, &env->CSR_ERRINFO); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRINFO1, &env->CSR_ERRINFO1); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRENT, &env->CSR_ERRENT); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRERA, &env->CSR_ERRERA); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRSAVE, &env->CSR_ERRSAVE); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_CTAG, &env->CSR_CTAG); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DMWIN0, &env->CSR_DMWIN0); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DMWIN1, &env->CSR_DMWIN1); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DMWIN2, &env->CSR_DMWIN2); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DMWIN3, &env->CSR_DMWIN3); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCTRL0, &env->CSR_PERFCTRL0); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCNTR0, &env->CSR_PERFCNTR0); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCTRL1, &env->CSR_PERFCTRL1); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCNTR1, &env->CSR_PERFCNTR1); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCTRL2, &env->CSR_PERFCTRL2); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCNTR2, &env->CSR_PERFCNTR2); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCTRL3, &env->CSR_PERFCTRL3); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCNTR3, &env->CSR_PERFCNTR3); ++ ++ /* debug */ ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_MWPC, &env->CSR_MWPC); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_MWPS, &env->CSR_MWPS); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB0ADDR, &env->CSR_DB0ADDR); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB0MASK, &env->CSR_DB0MASK); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB0CTL, &env->CSR_DB0CTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB0ASID, &env->CSR_DB0ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB1ADDR, &env->CSR_DB1ADDR); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB1MASK, &env->CSR_DB1MASK); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB1CTL, &env->CSR_DB1CTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB1ASID, &env->CSR_DB1ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB2ADDR, &env->CSR_DB2ADDR); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB2MASK, &env->CSR_DB2MASK); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB2CTL, &env->CSR_DB2CTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB2ASID, &env->CSR_DB2ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB3ADDR, &env->CSR_DB3ADDR); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB3MASK, &env->CSR_DB3MASK); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB3CTL, &env->CSR_DB3CTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB3ASID, &env->CSR_DB3ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_FWPC, &env->CSR_FWPC); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_FWPS, &env->CSR_FWPS); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB0ADDR, &env->CSR_IB0ADDR); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB0MASK, &env->CSR_IB0MASK); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB0CTL, &env->CSR_IB0CTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB0ASID, &env->CSR_IB0ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB1ADDR, &env->CSR_IB1ADDR); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB1MASK, &env->CSR_IB1MASK); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB1CTL, &env->CSR_IB1CTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB1ASID, &env->CSR_IB1ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB2ADDR, &env->CSR_IB2ADDR); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB2MASK, &env->CSR_IB2MASK); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB2CTL, &env->CSR_IB2CTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB2ASID, &env->CSR_IB2ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB3ADDR, &env->CSR_IB3ADDR); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB3MASK, &env->CSR_IB3MASK); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB3CTL, &env->CSR_IB3CTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB3ASID, &env->CSR_IB3ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB4ADDR, &env->CSR_IB4ADDR); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB4MASK, &env->CSR_IB4MASK); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB4CTL, &env->CSR_IB4CTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB4ASID, &env->CSR_IB4ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB5ADDR, &env->CSR_IB5ADDR); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB5MASK, &env->CSR_IB5MASK); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB5CTL, &env->CSR_IB5CTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB5ASID, &env->CSR_IB5ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB6ADDR, &env->CSR_IB6ADDR); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB6MASK, &env->CSR_IB6MASK); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB6CTL, &env->CSR_IB6CTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB6ASID, &env->CSR_IB6ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB7ADDR, &env->CSR_IB7ADDR); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB7MASK, &env->CSR_IB7MASK); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB7CTL, &env->CSR_IB7CTL); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB7ASID, &env->CSR_IB7ASID); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DEBUG, &env->CSR_DEBUG); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DERA, &env->CSR_DERA); ++ kvm_csr_set_addr(addr, LOONGARCH_CSR_DESAVE, &env->CSR_DESAVE); ++ + DPRINTF("%s\n", __func__); + return ret; + } + + int kvm_arch_destroy_vcpu(CPUState *cs) + { ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ ++ g_free(cpu->kvm_csr_buf); ++ cpu->kvm_csr_buf = NULL; + return 0; + } + +@@ -936,8 +1082,10 @@ static int kvm_loongarch_get_csr_registers(CPUState *cs) + CPULOONGARCHState *env = &cpu->env; + int ret = 0, i; + struct kvm_csr_entry *csrs = cpu->kvm_csr_buf->entries; ++ uint64_t **addr; + + kvm_csr_buf_reset(cpu); ++ addr = (void *)cpu->kvm_csr_buf + CSR_BUF_SIZE; + + kvm_csr_entry_add(cpu, LOONGARCH_CSR_CRMD, 0); + kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRMD, 0); +@@ -1082,399 +1230,10 @@ static int kvm_loongarch_get_csr_registers(CPUState *cs) + + for (i = 0; i < ret; i++) { + uint32_t index = csrs[i].index; +- +- switch (index) { +- case LOONGARCH_CSR_CRMD: +- env->CSR_CRMD = csrs[i].data; +- break; +- case LOONGARCH_CSR_PRMD: +- env->CSR_PRMD = csrs[i].data; +- break; +- case LOONGARCH_CSR_EUEN: +- env->CSR_EUEN = csrs[i].data; +- break; +- case LOONGARCH_CSR_MISC: +- env->CSR_MISC = csrs[i].data; +- break; +- case LOONGARCH_CSR_ECFG: +- env->CSR_ECFG = csrs[i].data; +- break; +- case LOONGARCH_CSR_ESTAT: +- env->CSR_ESTAT = csrs[i].data; +- break; +- case LOONGARCH_CSR_ERA: +- env->CSR_ERA = csrs[i].data; +- break; +- case LOONGARCH_CSR_BADV: +- env->CSR_BADV = csrs[i].data; +- break; +- case LOONGARCH_CSR_BADI: +- env->CSR_BADI = csrs[i].data; +- break; +- case LOONGARCH_CSR_EEPN: +- env->CSR_EEPN = csrs[i].data; +- break; +- case LOONGARCH_CSR_TLBIDX: +- env->CSR_TLBIDX = csrs[i].data; +- break; +- case LOONGARCH_CSR_TLBEHI: +- env->CSR_TLBEHI = csrs[i].data; +- break; +- case LOONGARCH_CSR_TLBELO0: +- env->CSR_TLBELO0 = csrs[i].data; +- break; +- case LOONGARCH_CSR_TLBELO1: +- env->CSR_TLBELO1 = csrs[i].data; +- break; +- case LOONGARCH_CSR_GTLBC: +- env->CSR_GTLBC = csrs[i].data; +- break; +- case LOONGARCH_CSR_TRGP: +- env->CSR_TRGP = csrs[i].data; +- break; +- case LOONGARCH_CSR_ASID: +- env->CSR_ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_PGDL: +- env->CSR_PGDL = csrs[i].data; +- break; +- case LOONGARCH_CSR_PGDH: +- env->CSR_PGDH = csrs[i].data; +- break; +- case LOONGARCH_CSR_PGD: +- env->CSR_PGD = csrs[i].data; +- break; +- case LOONGARCH_CSR_PWCTL0: +- env->CSR_PWCTL0 = csrs[i].data; +- break; +- case LOONGARCH_CSR_PWCTL1: +- env->CSR_PWCTL1 = csrs[i].data; +- break; +- case LOONGARCH_CSR_STLBPGSIZE: +- env->CSR_STLBPGSIZE = csrs[i].data; +- break; +- case LOONGARCH_CSR_RVACFG: +- env->CSR_RVACFG = csrs[i].data; +- break; +- case LOONGARCH_CSR_CPUID: +- env->CSR_CPUID = csrs[i].data; +- break; +- case LOONGARCH_CSR_PRCFG1: +- env->CSR_PRCFG1 = csrs[i].data; +- break; +- case LOONGARCH_CSR_PRCFG2: +- env->CSR_PRCFG2 = csrs[i].data; +- break; +- case LOONGARCH_CSR_PRCFG3: +- env->CSR_PRCFG3 = csrs[i].data; +- break; +- case LOONGARCH_CSR_KS0: +- env->CSR_KS0 = csrs[i].data; +- break; +- case LOONGARCH_CSR_KS1: +- env->CSR_KS1 = csrs[i].data; +- break; +- case LOONGARCH_CSR_KS2: +- env->CSR_KS2 = csrs[i].data; +- break; +- case LOONGARCH_CSR_KS3: +- env->CSR_KS3 = csrs[i].data; +- break; +- case LOONGARCH_CSR_KS4: +- env->CSR_KS4 = csrs[i].data; +- break; +- case LOONGARCH_CSR_KS5: +- env->CSR_KS5 = csrs[i].data; +- break; +- case LOONGARCH_CSR_KS6: +- env->CSR_KS6 = csrs[i].data; +- break; +- case LOONGARCH_CSR_KS7: +- env->CSR_KS7 = csrs[i].data; +- break; +- +- case LOONGARCH_CSR_TMID: +- env->CSR_TMID = csrs[i].data; +- break; +- case LOONGARCH_CSR_CNTC: +- env->CSR_CNTC = csrs[i].data; +- break; +- case LOONGARCH_CSR_TINTCLR: +- env->CSR_TINTCLR = csrs[i].data; +- break; +- case LOONGARCH_CSR_GSTAT: +- env->CSR_GSTAT = csrs[i].data; +- break; +- case LOONGARCH_CSR_GCFG: +- env->CSR_GCFG = csrs[i].data; +- break; +- case LOONGARCH_CSR_GINTC: +- env->CSR_GINTC = csrs[i].data; +- break; +- case LOONGARCH_CSR_GCNTC: +- env->CSR_GCNTC = csrs[i].data; +- break; +- case LOONGARCH_CSR_LLBCTL: +- env->CSR_LLBCTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_IMPCTL1: +- env->CSR_IMPCTL1 = csrs[i].data; +- break; +- case LOONGARCH_CSR_IMPCTL2: +- env->CSR_IMPCTL2 = csrs[i].data; +- break; +- case LOONGARCH_CSR_GNMI: +- env->CSR_GNMI = csrs[i].data; +- break; +- case LOONGARCH_CSR_TLBRENT: +- env->CSR_TLBRENT = csrs[i].data; +- break; +- case LOONGARCH_CSR_TLBRBADV: +- env->CSR_TLBRBADV = csrs[i].data; +- break; +- case LOONGARCH_CSR_TLBRERA: +- env->CSR_TLBRERA = csrs[i].data; +- break; +- case LOONGARCH_CSR_TLBRSAVE: +- env->CSR_TLBRSAVE = csrs[i].data; +- break; +- case LOONGARCH_CSR_TLBRELO0: +- env->CSR_TLBRELO0 = csrs[i].data; +- break; +- case LOONGARCH_CSR_TLBRELO1: +- env->CSR_TLBRELO1 = csrs[i].data; +- break; +- case LOONGARCH_CSR_TLBREHI: +- env->CSR_TLBREHI = csrs[i].data; +- break; +- case LOONGARCH_CSR_TLBRPRMD: +- env->CSR_TLBRPRMD = csrs[i].data; +- break; +- case LOONGARCH_CSR_ERRCTL: +- env->CSR_ERRCTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_ERRINFO: +- env->CSR_ERRINFO = csrs[i].data; +- break; +- case LOONGARCH_CSR_ERRINFO1: +- env->CSR_ERRINFO1 = csrs[i].data; +- break; +- case LOONGARCH_CSR_ERRENT: +- env->CSR_ERRENT = csrs[i].data; +- break; +- case LOONGARCH_CSR_ERRERA: +- env->CSR_ERRERA = csrs[i].data; +- break; +- case LOONGARCH_CSR_ERRSAVE: +- env->CSR_ERRSAVE = csrs[i].data; +- break; +- case LOONGARCH_CSR_CTAG: +- env->CSR_CTAG = csrs[i].data; +- break; +- case LOONGARCH_CSR_DMWIN0: +- env->CSR_DMWIN0 = csrs[i].data; +- break; +- case LOONGARCH_CSR_DMWIN1: +- env->CSR_DMWIN1 = csrs[i].data; +- break; +- case LOONGARCH_CSR_DMWIN2: +- env->CSR_DMWIN2 = csrs[i].data; +- break; +- case LOONGARCH_CSR_DMWIN3: +- env->CSR_DMWIN3 = csrs[i].data; +- break; +- case LOONGARCH_CSR_PERFCTRL0: +- env->CSR_PERFCTRL0 = csrs[i].data; +- break; +- case LOONGARCH_CSR_PERFCNTR0: +- env->CSR_PERFCNTR0 = csrs[i].data; +- break; +- case LOONGARCH_CSR_PERFCTRL1: +- env->CSR_PERFCTRL1 = csrs[i].data; +- break; +- case LOONGARCH_CSR_PERFCNTR1: +- env->CSR_PERFCNTR1 = csrs[i].data; +- break; +- case LOONGARCH_CSR_PERFCTRL2: +- env->CSR_PERFCTRL2 = csrs[i].data; +- break; +- case LOONGARCH_CSR_PERFCNTR2: +- env->CSR_PERFCNTR2 = csrs[i].data; +- break; +- case LOONGARCH_CSR_PERFCTRL3: +- env->CSR_PERFCTRL3 = csrs[i].data; +- break; +- case LOONGARCH_CSR_PERFCNTR3: +- env->CSR_PERFCNTR3 = csrs[i].data; +- break; +- +- case LOONGARCH_CSR_MWPC: +- env->CSR_MWPC = csrs[i].data; +- break; +- case LOONGARCH_CSR_MWPS: +- env->CSR_MWPS = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB0ADDR: +- env->CSR_DB0ADDR = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB0MASK: +- env->CSR_DB0MASK = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB0CTL: +- env->CSR_DB0CTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB0ASID: +- env->CSR_DB0ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB1ADDR: +- env->CSR_DB1ADDR = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB1MASK: +- env->CSR_DB1MASK = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB1CTL: +- env->CSR_DB1CTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB1ASID: +- env->CSR_DB1ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB2ADDR: +- env->CSR_DB2ADDR = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB2MASK: +- env->CSR_DB2MASK = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB2CTL: +- env->CSR_DB2CTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB2ASID: +- env->CSR_DB2ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB3ADDR: +- env->CSR_DB3ADDR = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB3MASK: +- env->CSR_DB3MASK = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB3CTL: +- env->CSR_DB3CTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_DB3ASID: +- env->CSR_DB3ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_FWPC: +- env->CSR_FWPC = csrs[i].data; +- break; +- case LOONGARCH_CSR_FWPS: +- env->CSR_FWPS = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB0ADDR: +- env->CSR_IB0ADDR = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB0MASK: +- env->CSR_IB0MASK = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB0CTL: +- env->CSR_IB0CTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB0ASID: +- env->CSR_IB0ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB1ADDR: +- env->CSR_IB1ADDR = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB1MASK: +- env->CSR_IB1MASK = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB1CTL: +- env->CSR_IB1CTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB1ASID: +- env->CSR_IB1ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB2ADDR: +- env->CSR_IB2ADDR = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB2MASK: +- env->CSR_IB2MASK = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB2CTL: +- env->CSR_IB2CTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB2ASID: +- env->CSR_IB2ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB3ADDR: +- env->CSR_IB3ADDR = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB3MASK: +- env->CSR_IB3MASK = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB3CTL: +- env->CSR_IB3CTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB3ASID: +- env->CSR_IB3ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB4ADDR: +- env->CSR_IB4ADDR = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB4MASK: +- env->CSR_IB4MASK = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB4CTL: +- env->CSR_IB4CTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB4ASID: +- env->CSR_IB4ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB5ADDR: +- env->CSR_IB5ADDR = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB5MASK: +- env->CSR_IB5MASK = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB5CTL: +- env->CSR_IB5CTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB5ASID: +- env->CSR_IB5ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB6ADDR: +- env->CSR_IB6ADDR = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB6MASK: +- env->CSR_IB6MASK = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB6CTL: +- env->CSR_IB6CTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB6ASID: +- env->CSR_IB6ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB7ADDR: +- env->CSR_IB7ADDR = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB7MASK: +- env->CSR_IB7MASK = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB7CTL: +- env->CSR_IB7CTL = csrs[i].data; +- break; +- case LOONGARCH_CSR_IB7ASID: +- env->CSR_IB7ASID = csrs[i].data; +- break; +- case LOONGARCH_CSR_DEBUG: +- env->CSR_DEBUG = csrs[i].data; +- break; +- case LOONGARCH_CSR_DERA: +- env->CSR_DERA = csrs[i].data; +- break; +- case LOONGARCH_CSR_DESAVE: +- env->CSR_DESAVE = csrs[i].data; +- break; +- default: +- break; ++ if (addr[index]) { ++ *addr[index] = csrs[i].data; ++ } else { ++ printf("Failed to get addr CSR 0x%"PRIx32"\n", i); + } + } + +-- +2.27.0 + diff --git a/loongarch_bios.bin b/loongarch_bios.bin index 3aa4f36a853b0d605d6a6dd61d933fa43084c580..d6330c6f0532effe458726efa18222166a444839 100644 GIT binary patch delta 819939 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

    L}HjnqMHg6*86OaESZUm}r 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 z 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 z z?${(*b2{^N?_6w3Lk0Glv*n&Laz|OVjpZSV8%O;NQyLBs@(LryK(_q6K)k+ zF0AR26SoptVSj$Dn$D4oC;y!^mr14r6L0pQ?0)l)59TJN*-(bK{yoy-7ekJJplQR4 zQDhN_ozuGiW~js=tY*1|9=kW9YvIN1W&(0C9PX|LXwRJ zawd-Pjdpa;jfAQ(C?ZgEwyw6%h+M(DI=StXJ#2p3`z+7W2L!XfM;9}F4xw?ZK+%08 zNlzLxjJCUxa@;JifekX1ruc+kFCb4bjO?a~8e29B7T1hfhVEtsedU@bVAxtnCFdq- zs@asFoqr4;h>bsynilj0vU$dP)sY~OBrY5fWxlz4e5Sy(i1lXi^?l#kr#L7T-nmnN zygpuMsfdNL>1TjDvVlNu+2nZ?+VHcW%NOaea)X2xoD?`F$~xlyz94H)HW1%W~uvv?SR z`}uq|o)%D13=m`QjR<=qL18ey2GxPig&asv_t?@J%PqMW4rh$yR2xCHb&a{PJei^P z3Ot3uywy`APG%*wlCZmU*CI_3p$9B3@08Hq_geN2rik8(Sy=9EnT*b&N^96RMGjt% z+<$FJ)qI>}-JXuP(P_`H+-aCnSV>C|o$XAI<|2wY<){}Eg?N-?59H{xxVw_xaH(y! zPP8{)d#d3Pr;#n}^`|M7v)P@fL`YjsL^Xe}$TH} z9#;yjUIez|ogSyn3ZkvG^HspNjVPA8tO>)sv`T2J^(%yf$>WY8WknWi@4{VOPzE`I-P39LlGiQqDUD0l7>PbmH>4@hQRVgb8J$^Kn|^4GJRDVt=~& z8Vl*@&M^Up{j5G-?&Zn`$FC07q#+4YxIL*5C-hz6O;hs2SY-g@p9#*#8l@HaBk;&S zqD7#GZ-rq|n?FfIJX3kOHupDH9GrV(MojOLMIwDFDSJ~x!SkVPM{nViRFs?3QVS;f54OEO>3BnD0nL})XP1j71ZdOt!ReX7gx!afIukeobsIMQr_+sMeaT+BK^E*Jjo&;2r9d_Z0$?Yu%hr)|G=jOO6d{c&rvsUe1R5jht*(U`P5ZPc;y!# zL24qLu;RM!n-febvrj||)xjm89u~8B?PcgWA=n*2;)qg%8eBio-xywY< zcB1Y#G~1>VP7=U}i+RP>SbmDUM#q}<%g4-e8w$@QPn)ERE@ab+nFZZVD4!B1u0n22 z_^1S0dcHU6e?aB4g-X5O7NK$XNVJ7>aC-T}uipkBSdOaP*vIOOlNA(CTr)E>fs39D z(nMw1oBNl;ScA-Z{+e z4=dcyX>ysiCuPL>N({}~O7l{R1|&;G-0@3ilT$}$QTbtsl!P{?vM2pqQcc`f)dV-J zD^B$y0k%8=UIS2R&~AndIZs!voV=DL%dqze8p5Z~w?Gu>%!oJv9IRpv!r-Eo98HRk z8hZU7%-z3M0)Jg%s~Ulqmi{s_;-gYXgk=h5dz&p|t#zbKwpNZg;-mdCi@Jy(YM+g| zUL8!G{^xHs$Uu(>nuF$XesF4|qMPESXmzqYuP5QB2-qpr;`c(6>*Q6eA^E?ni~5d& z_mPfaysdvG>7nYpDWIOzh-_Kw1U|;de36bPkMR0EZ-2b+m4E>OVHT)H|NUgD?-gda zWll?K5OcW>m?nNR@82t;Al)}W($THg^_}k-ub)E(xEb~3VblzW%+@I6nc(!7hfc?( z2>I5k?>Zw)G!un8MS`n5Ykohgh_<$FL3ZX0-caU>?z?s;sf1il*od+Ey_9e60zYW` zMC2xMO@H8AsX=2u!)i2o1nbZ0WQa_HHmUyib9s--PA;V4flVw|?&(O@; z*=ZKbd`U@AkIvW3RRi1z$CZdt_v+s}x#&EK;ci25Irdx?l9{rXF1; z&^duZj~{Mi>xy+Pt)oeXiC|pYZwl)|2WE*#e7w)80bUV zez*DT(rollw|B1e+ue6y7Z@ahvfhw{E6k+^>rp?4uchb{C#`Ybe*hcx!vprMAd zg~%zCp_N>Hg0015w$es;%Ky2DuB{?DXQE>@bf2bTdq4BEuO1&hvX8HFfECuX8Go3v zKxUPC9D_K)q=2IeGJF&!2>i5>ht8lkdGb2CUHldxxFJ^*KQs9V)4`DcUFO7HPcl@q zpIm>$8I~4321@Do0pxtwVFSJxWr7C$2yS1yr?1bz+M@>q88KRYl{bn)U0aN|h>y&>wKvJV^GIjv_+jBJ0R2r*xraP&;UBzX# zy$in{#diMag19>)(Xch#b^gN^&X&>@bYPd~W8cKwpkR)|j{L^eg2io)c}RoT{${Ld z?`?yURR&Odl;v8_N0cqx-clGBxH?2*U)*d&-C74nhS~5tML38EgsyIgR|=Jq-@0dq8o$mac4@siH)_u7OBO+TIVufO)V@t zJiw8P^b@NHlbh=}D1K`QD*#aD_mh8o2M_vmB<=dRN?HQA-Qy$!!+w**cXw`DY}9df zCaAZqeXRqE)@<~TBT?3}a5A*}FBQ%2#iZO4j#AU@YZe;K!qVaazWOdnuB49WVvi%@ zVphxaJER)dLPUz>8+i5QwVffvOns@(cqx^zS^GVnoIDShkUdkkc!-cO1)6{9Z45ID zq(^roz&la0c6yH|rpXWWS*`VB%On~m@f%O|kGHg~vePS}eLqo9&;BnNj#0Q2WWz+H z3z0jyQqOj{{W=LF?QtMIw+gRoE!fpt;Y#mbj<)2G$yI$A!Q*wj80i!OE2J~;`>QFS z_DqENpZsp4Mxxn)ZA|$c>12P(r52P|VsbMuLVM(+#F2g^EtWX#x4?F$VT}<|n?;G> z3ca&}(^}+o#D2wz2D37haj=r?Fz`fV8T2J49z^`v;ql$|Vc2u1<$k4&Ok4_tu>FQ8 zJYFL<#EiO9=nm#M8L7Sre%V0j>+_};vjXe$JDh`+=gEBa)T%xxcsSEu z8UpRhv=PGEK`61Fv-sPn@e;}^9UTLq2Kgile2UKS2&@SnzKzUEM8(Y|9XAl4obKUe z$s~gmA6%}A!k298ehm!zb9RpKGtva?*l@5u^luwysYRRuMN)@fjm@NZ4Z0m$R#=|9 z^M!<`bt|UO5Q!NGx_E!}Y>UdZ`>x;?s?U$j;xWJC{@goxVbp5WBNTF|5G)9M@A9co zbSo%dld~%j@pk9nj<=wY!@#jhhG~A3=S-v}YB0FZe2+EPhDEw*VR0zKV(2^`O##1_sU~^(23nFfy>dDvd*43E!ye(xfJ=Le2*D-%FsACq7y5!(k(RLNL zH2(JeLlgWrJ1BAn8>M>6l^6E;-o5^7O6ql{FkJ+~?^}jvrf&zapY)tP6gd)YCbxi^ zt*!3fX&wtwyy~(WdJeme0nht^>p~y`n$RvxcLFL4)RAf-k{~z!{~DpLiZI20*JYcN z(#Yxot3w6QFN%L<5I^8e4FPe}oEI&X%Af`u{-4CHd9yGSXe zp0K-$j6E`l=9#~lfm*)WLTmprT%@N)kgwam+KI`0KKzL$+AOY_!+tA;H2kV} z6Jq4toe3xx5~-~Sw=4S+@tpM)N`!}*;Rjhgkk?;A%wD*xI10$Y<|`mVw! zs`6Kmc|0*qkgF1(Ov1ZichiTBrt5bro!-lU_KAr8UNrz*D<~oLq>E?%SK@PvA~hGD z9W#IFPFj+QudwuI#a-4OW_#!mH$_3F>ATdtd3*gJ7vwRxIw>UuPOL+}5)n?5@|(W# zb5`dbl@Y>V9_$K_3=+)cUrlySW=nSQuzBz<7aAtM=Q|w?;iLnE07rwzmtP5PqNSIU z_P_p3pQ3htf#677|iGN7s9wpD)t!hb>xQd>)SsX^R0=D5iFbi8>&Dg1g= zG+IxzK4T;9RSG{S?wu%#Q(M0jp)SvP*;lxo@+b zTGD!+tauAg_1ImnCHKD0ulKsLZ8tLL#N$koE5i{i-@tNbw6V-UWV<@OmSHP5= zqE+DoGlW?FgNsus6?3lZvI+CQr>0P3krK&B7Q|&B}m()=#JqTUZ8K`2!eK-0!ZkL50Fd8)1ey>Gf3cwY9om6@(B=B$0iS zPJV^@joK_t$yoDZQ@SZqBY;ZTWo*wi3#K_ocE)-O(Ze%igwxW$(_+upr(NhLG^V^!*egR7|HgTrfMfikbSfNeg85Y`pt2}q<# zH{vb=HDkG%wf;B7CLWqBqx=_#fT`nriFqo{MFB!SE9wxdlcI?2PRePHyPwV4D>nw| zIJaI9OT#0k$F*ZC1|xr_(s6ZHYzTujv;^rBb4Yt3U;i_Cff&Wrk0zvH!Zb&2-y{u+ z4CRuuH1g(bVbBc^BixToR>cp;se|`6W(Ha2+~Ylv(a=CwbOMc8%e8(OMEMlslp(*xV3fho=*&eep)8^c)HuI9;#{q1WNn+ ziTYoOh)OzYDoUQS@kpAkD8PaW4HTcOAdJXN*~z&{FLqlcvfEl5$93mI;aVgbg5Ao% z;Lkfu3cTtJ$J61#efJ{~p@4u(#Al9i!sk#qEzLSO^z>KCFNHzRfZPcCmQhxJ*lO?`~LqBWN}N7)Bwliu_+IunARobnB8u>M>oN4%q4MWT5ROX?QUH@}-tQA;pOvP=AF{hF8VgnE2T7r1swfQ~SC z#z`voelDpnSlsu;T}#zkd8ntM`Ki@Eva%^USp*Tmd;P2*#!Wj7Di-Q5r3TTgt~VCzF!0uek| z9O{tft*(Do=w&<9WD5*Gm!Z16qbDkQ5a^TC;hTaK2FRm3i<4S^v>j+UWRCWY@Jm@O z{K40J3wa7Zwp_0Pq5%@|e7^jR4wLc$QEsaCWBjE-Wf^{IX&l$@ld++ZasH2SbMt@W zW7ItWPm_TW7e;oh6*2Z$Z_l?R*L_}k0r9C1Wha3$hHqw_$GBX(k$&D?{%0! z)WtADQwf7y}=bv?f@g_Z}O z=-AbcQ(2#i56Bw8F@@rRme<h9==R-YNC$>gr=}l%P=G1(`D+i=PHL!m*6+BAJyp&Q4kS z8h8@u5KTINIv7%5Z69fzOo$|Qw_capbB6BuGwE{%d5)R%+Gf_Zw1f@;QP9o>P)>2e z?GR;GNzQ4%iXJTVR#Txs6<2?cql}R{vz;iR9lQTl>l8M5j0uck!u(O6{F2MlB}Yj; z+^wJe_-*3AO@8j6_F@3)f&iy8nrJIwo!w9x>npy#d9{qT+VJO0K7`{|lm9`W3&c3z zEzLRLSbWHaPKs!sA9sTe^`TAy96)VuQ@M%@LJT!S4h3HRDVpzpf60H0O&)8+ysWk5 zo+Wef5dj0fZ2_rYO`pJ)8MZBW>U*wuW_iehI11F3g9NscYkkb(nAkOX@~qPrrIm`%P`#ZN%X*A~N)g_P5cV4FVGwgiCw%gA;y=B8UEv_`Nu8k?oNmgP5!eNRQW;&J}H0M?rsA-&HP;?-buGj>GSN z9Pbodo&^=}JkNhiec6gCfZu!tz;~UHsm$;XCd^h&#rRcL+&8Xgo%u+%@C-2$=N6l~ zqJr+)`Q=A(F`^qbh)OzP8qyh?1-?m|phFUsz}Af4^BJJ_vFwO8nJch;yU{c?d}-uA zo7fzFpnCQI4Pbv`C4|$&1XQ2yFtoq$@*|DTRr)OcCpg!X_EU>an0YMW;!d3b&}_=+ zU5a%6%t!@PZQPq`zp$rUPiSq!tPq7iQ%Ae1F$!zh4G8dwuM8UKK`PdlNtiYA$W6Vx zP~4X6c^hxD_qEQ1xc1$|{eY&GJh;88|I<)QcGmkuD#w4DlA{huBgRzg*z4N;mwA;50<_!~V~ z308tI#y_)%=3R{7x%+Xwbd_Ut-NP)$6_UQrTg>TKUa6<+sjJb>KOmVJ;njIo_*O2i z_sSl!_K$xd3x=n6PiC13F6;_osiPbb^A!Kbqd@~Kn&$?@yR%)+R)J@93u(I8nFtW!B->jU~WnxK;T~9*ZX)W5I}Ks zmFl|0sTIRb3@#?Mq@x;4L2Z}UBhpa*rhp5=kC=a(HU?U1R^xV_`dA#W|EBNIfN&J! zb1jJpr?2>|9wzzi7RGL*x*A6?S-EHJ+dnIvFZnU{Zb6y`!XX@Hm+VofS{$*E_t2W- zzUKl~U08_`>teM$_j2bo1?`a&5AV4%`IUZL24uv|ORO1^j%Vf(QG333SKa|g7VC@l z(p`T_X*4;f5u1sKLZ!%*@cc~|_Bcv)*?e2n1`h%z-O-@#X-OXu8jJTm-zqF(UhUeM z3-Iz%&CnD@f*6?Sd>l+zYi&klnvz#I2&)jPu1G*o2TD#ulZvvWWh`GTpbbEdRay?V zubnU~xd6GH_l>u7x(F8oy$t)$dJ9d}B1LyG z*SzR>qYxvTBlzvNqNoHYWw#h+WLv#F*GY)u(!9I~&IxDe%H6?$} zVunSp;ZNXV{lBMr=D-zAR_L2ZMasJKY7|g$@YOhT61BALwK1^M0V68nk)$6a0$su0i3wK&bakwzvOd zgw`|bFA@+#6kb_Fu}XJrsgqO5?++vxbxv}{=37V7*vmRED6IgD7SUOMP>Fwwcpux? zD#ppVl&G+L8jEBMqu{Oz9iOi>O|R70bCug4b~@|cLArbK%t@7#LE;?NdPUMZaG4o3 z1|Ht-1;TjLjW_NWx|`*tod8Oe*9-7kM{R5vTBc01Ba_e7!O3-K#D=VYJNmyx?15>@ zR{+1Gy`B{oZ36?}SC-QwOzwZ~CJJEE6M}_CGhVf4&3yv@w@I8Px%5z-%y#Y6s%4xG zw1^0mP+8DQYcgd=dl*yiIq@J|-gpnomuoAEyNfjT=UCo`0vUt)U|?pyi94gx?aaiB zvpU!vjz3Eyvm(iMUAc8IDb~+(>_PK_y2d(o#&ogsi)L|6<0l~+A|ih;aayzIJ9vZy z!KXS{C;VeBp18L{G zb})0{NkR;T8PvGUP|%m!V;-{uD0i$3HrF*w*(H009Gq15hf#&#;6`nZD)q<(w->)C zj=Y;>RDeU6GO@6N!jLV5 zYDL;`{n^6E+GA~%UL8FFll|%9R@d>khwEP%di&PoF9Yw+&XGrTi9OQmh_1!0M-`Z< zl`3*;Df52N1rdpwiC~pOnBaZ%Hx}cLnIP1`D%U{&(SPOqwlIEiAb3;Dpoau?o z6KP@^`<_$;lu_6q#5>c%jev<+F<2a%vJ4?-AvUr^A`y-IpIuevw$48q;|+v1^pugB zB6SNhj0tv?BkA_35Vo65=EUz=n?{{@>_Pe$5WU*QXlMM+*I)TE<45^9Oli)+s1(s; z!k9X>9X$E@B|Lw|?oo=WyKMUf&-MbyGbrY>O8J^Xct~XyR^y z+&0Dy(Zlh5kTCYsbOmWO|60%P`1GwE!TMA#CxEviHaArY&AAM56f0uhzQTyp(s9v4 zaam)qz+dJ+yr$(?2O3o06wr(hGu%``dlvs`o=+b`k>jcH(2C|AUnu*2 zCv$%bp2aGP5~>?FJUqmEuy)d5qgj6uE8#tp%984sNFGNmz!IlOFRTD}laqU= zQ6XKO7`d8<2PVX#>rJfyERad`KY5ZSf~BGxx<0H8b?=I>Dy%4#uTBMcmag3ny>k6_ z9kE$qKEqz)!Isse7jaL9r*qTc)S=yS0m;K87BW$v)$`p2;TcLu)XJR$n~OhfSFL}I z&Zq|X3GmIG!$Y&Uuy|Q|?)+0j3#pRMiK3JM{Rd|@w}4FL@=YxHrC?6jCAbH%jwBqM z?Jm^iVAgZB1}$I(Rv?eIQ0gOhR{+32;`&{*YdTAj_B>VA(^NiRLg+ed+IM!%uxLa% z?XS_q;o;SxAao-Brp^z%S7)WI3GaVjWO(qK63T?I4h35ZY$#kQXSh|Um(UQdN4$pPRr}-t8?iBmpD>HxWG&c1^ z+L0HKgR)6cyuS7M5zDP(W8H0?*FO_g0dMwq!l^HN0Y}vJe+Ag}l{+J7(U3W{sD9-P zIu4fuZ4dr(n75#ttR)DYsz;@^BP{f!P`)qk8G~xsa5lQWhF|(1|Yb}bY8X;gHUpOMQP~zN}S3R4=F(A z@ZJzkDn}-s%_(mGc-HlcL?n9W8nM6_fo;b@-PC`b1eITy_BGat zn^q{$Rf~$3Jq{ndd+U!&K-Swmnyy2=*wJBuv{oI>LPh%_HFJsT5c>7K%PM=&V&PZ%4=$Sds=srwCMjPWpg}ndy?!rsY7(=`z8kkN7lnv%pGhs zhAak1KQ+!@K;wU%?Ps75n1FAn-&;FTzu7AX2t16Mt=F3VDk(^;w;#S){)VJKXIZ45 z^AWiMzyT?^>Ks=3p$xNAF>h!|6Pt`wb#@Ph$3|NE}t-TNl2FkW%?OCvc#W9 zy3{bI2aqfNnX-_9JQ8F-dpkJJy0UD#9jLJg=KMIW^gw^-2f*|w*c7ffkxE;MLNA-% z0+LwRT9;IN%~oQ@Fjg)NT0^8MmnFWUB==}eB@|yj!f60J+=M&&V^T?}3hX+JMbxEZbmrvY86?FE1ISy+ zq}s`*K}g-%5D%BuqJFfkbcGG~>znwpbS%ZB@|k}T?B7q;F^Rvb@Txbo3OC;d8CDYZ z1ifS_3Ao|t&k}E?&PFN#>G$+Hgl+ooWYO(rdZOy=nzkh7s_8_RS*Es>$TOH5(L~Nt z0zQc?fEgTcaIS+menv?a0Rah)gXwmoLW!(o38aXYq7k!|NofR#k3Y|O$=H$JZQ4D`(r?}~u$*aWpWGCK05c9od7L&eWTxn)M zV|;;OLafgcbqHPA`K2d^7;;OL6MQ()X6n6MJPn%V**p}hNUcl6$HvfZxx3mhL;dP~ zse~Y|#r$MRplGw$N43fY323Vr5{Z5Cj**A$ylP`FHikdJlm@~Ko6U)%#uqHpC0j)u7&(X>2-$m)5r(UkO<(u2EL8cnHrr2=8@)78P6mUz-Ni zgs2UWGtzP#;1rg>eHR!;!J12vh;@MJk3-}^-{s>{=#q8Wu3^wkwm zfcY!~G^|a8`al^5koa0UDeEbuzClzj3P=katX#vW zHEsW>`*2oJ(w3;|AsI{F+l8j1&eMTgD;KaONkpvIehSt_E2+i9{) zdi>O&d`6iHsMxARlX^%yjAda=HJRXeB(d8c;LsHin7b&WvCs-6sZq6Ya4EuouJk^x zr{NOS0uZJ41Y&VYnb&_oUqw2nMNmSdAOK`3dUc2dz07n(1Gsb&&w^SMe;WX^v6nF+A%F|5goJ0oF2fm@$T+NV}~|+ z8cBPbzX7;2{H}iok?p2j>3jTR!pFxGZXU@!PzVEDqc#)nwwvWOAC-R^FoUnoJlX2` zq+r*934B#Nr^(;**X&qX&z!Ful8GwgGIbKh59IQqqCVWJYzS|@oqmTYs~(f7ktnrQ z@!%_I4zH58w0nMVktlVRc(lQkmiOvDfz?jo@FxRXj>LZ$36wu@>$`xZxQp{>(}7P; zH*UHtV^n&@#VWapZTYve4W`(+wM%COk8h=6zhg7Uy|0&ja^xh_WKjHr!Xy?L_1r2y zHAqTnb5xCZR1DT%mbJ;~Yf`PQGOV(mN7~aY>qDD;1okamjmacrlU-4eu?!D${#!0s zrW@CfUiE)mLV5FM=L)(>#Q@>jh%qfaZP^EEh%L2{9HWGVcS!2Y9zArmxcI|mXG}wH3Hs%o9FvF^AIsR1t`Bm| zpLgPyiT48<6pnU`oNXldcf;x&*Ax&3yo_oLgJK6`P~x+N=#Pvh#{?GHZ|b-!mIR(>Yc_yh-f+d=ib7Ib zks^O8Ck*gUWPhG&tKk0(_;5B_3A?2f!0rKU@XRUHA6W;THTR?Hh;;(z5p&gaUt5(Y zn3{jWE8aL1E)1smzEJ_Vpf2(x4cqOm;M(ry?*e}OHsXDW1JX4$18G5@VQsb<0!Obb zDdYeW%NAX{f>7@nI$mvcVP631t_FiI8i!rj*^_D{{dK2hId_{wh>)NA+O*9@?2^jvyni7@s4A$kYZ=4>jZ4;hq!lwNYpQ3*h z%=G^jjkJdeuq~_ z@tpK-fnfd+Aaoz~$KbDF40o1j3VVMQA^@2kSv7Qly)OT|m*uC!n1YPh9Yf{Rv6qkr zO9RasAsB;|RBe86Ozdq`+(kZ@0^h`w3Mb9~Jq-AI5;-m(7vMht?5LFx7<*{13JN)6 zbn`$=j?_JxW6CdDVHyWXwx=O;Q$_a~XBL7$Fi)NXVO^+g`}1xlg(!f@?yrBlEdc|N zFqorazD`+YBz1WW+=wJ&Ccr`mNGCGIFbX6vljAdgK6STlF5T%G%`^GgaxQx|g||^5 zACqH=xf%TV@Jej)bvbZmCI+hWJfz;(MjuH~jM%<}ER(_1*ohtgYnRGpYN%VBiWk4d;<@YG?r7z2`W!)$b5H!$^DEC149 zthnM@-Ujw=Sh~$481m?pJ;K#FvTO|&t4iT^c~&-mRY(qsOfDf@Dp0c=l9YB@k6LVq z8mBQj`n$0?6v^3jFF1duC%tWZ7anc^ktfL|?Ab|+%TtQu3VT8i$_f7O9X6=*MmZdP z&5K|vJg7P3^6{mjtMq2z06X3Bg{pH*c+qN6A92{1nXbYN?{wAWH70-aAA-)UGdW;0 z-uNw{{?SyGuoCsE-jAko>z!gV?%PwU4b5+Pd$#cyWMGDu@;b8P z*~3^-zHp7}^_Jg~)4y1)SpFA|jI9X%@k@$HP2p}A^7ZSc19Lyjy@*&T6%<=RnNbtD zJP*2+6qhP^bf|y-!;bp7gMXR5=#5@TL>bfJ?P<#H_l3Rtp5w)}!N?OREl(h!xB_+U ztd#wa!atu!^=5w2%$BSjJVi*F2jZH10e;Xf-&1Mu|Ju&^X#4O#%Cu6q z$hLa`yNnx&dClc1kl53Oifus0)b937D=@2OxaLQseu$Lu zwZtt?YI8;H*qt=NNe-VU>QN_6;|(JcYv?eiS$DTh_v%?v7YIW-(3etV%7QuEB*}5B zukdZS`xFIA9rktZCW*fF2#1Yg#o=~6)QB{rIIJ3X-r2Q5llW2McV@_stW`1PFn=hd zVw^HN1Z97@(y)8oDHZ;iww*X)hl#zpLmj-fe4hw3)MZ7bH_xmHt^3=HW$)6qL%S_}`ql?_lJ&`X>w zT?u*^8o3fKm2yrZ$dPEssP&$^8q|hfa@$vT;ZT3z2+hC)I-_RxE77K#(js7qe%kKL zY}|Gnk$a#RctkK{V^KfEG9w0TJx(2;XgUc!ZmiGAuJRKB$l4tq>4Dff50>hgp#7V~ z^!FTdK<=cvbZ>G~RiK>Xzl^yYiK+K2*cTKJ+7{2Y*(;;jpBlleNrLR{p)@@ksjbxY zL!W;+$&Y7<@~$zBNU16u+fT2hUs%)Q)9F`kSv&v+CNIoyztu<+h&IMg zR7txFF*RSoz#{J<9j@o9IcKplzDvms?Tn)d=8$vD!AXT9v?~(99aKWw>fXin?fJf} z(2KIZ>b8)YkiugdzeHQNv^lzFUU>yR1(AOOCW2kP5_G?XJ8qp`Kf!C2AITUh_v;={ zbf1+t!;N=$GwX4m$v3%ly34Fmqs)8X+-oTQ@$7CNfJzqok{>QeRR^LlBKeOD@i{22 z0fLP)_lgFNYFx^n{23fgpxnZ>*E`ij`!P!CIH}k)TN}9x1D7=qzlv&%`7A9G>Ck_h zq$W1#C(v064qBYdPvohg`M-+joA%PFE43FtjY~!+MnO!Z&Qei@XLjmp76Gl7j&D`t z?PXJ^1+{;kf!~dehvj<_Sn8>dcq_>qm_aH{*`BwPwvla8$J`*haihlX{5$Bn{TCvO zmeI!ZOmqT!Lkx*m4|O*g1ZnHX2-=m)x@(Fs0AvzHDi7R;2^|$3ro!TG72Xa)u zGNS0op2%nMbvOMP2Ewc};!H!|J}YP)^na_wQLxQkCqfn7G!vOHO~I+s?`J z^waiBgUFHmCj5BO7dzt0@ETXT8L#sB4G(aqFyFo$v0!F5WfhXgJ$1x8IiVr z41C)wx@^M5-XdczDBjT9hh5hj%Ub3XrtzM{1KSFIl9%o};3v~aLD@ylA;&qkS&bvX z+^3wb92p36udk@GihR-ylpWq+F3?w53Q?+@j9-x2t4fS5aj}$ebr5q|P z6$Uyp;UE%NsXe330Oh|mIlm%f)TH*dN|Nz?4iLEv3lU%-%gP zElh`W+D|r$NcQdXkKZjvEG`)`fGV{|2s`H9`=q}#J_Sd(b$24OwMBn8OCNAAFKJ}q zzdj3sUCeVN#Au~F59k+fJBy*aM^|DpX2GJ0)ZMkAx7!WSs=5-Ap z4))>4xJs_Q{DBVx5L5Fev+`cAjo0WD3-KeCCBJKGOZ5@`UOQPZyl~?IW!-!tLLU$P z5WuQ~^@ur!f^<*vBGG@2Qy;t)W{774(GtcWb?Za2T=`rGl77^YroR=BdN7il16r5yBPwwVKts^g%04u(}WZ#RYx6G!~BRi{{8sw|fcC z&d3<+LjNRVNHJP)!J*XZW=>Dct%ItixVoA^?&o`}GnOf@_Zoj=^eIc4W%(HZ8}C$8 zAtfE>=LsB1R>2t`n70v!a(@bOhFPUyK*6Ivx{-J=({YY1H)Q!`}9?Yl*Qdm1=WK z$*50U=Don>ta^VHg?YVJ4+sDRcrGiPhb}mdYJtyZWM^+d#26d#q2tD4*+xdw(nDUKpknJDXh8M!}YKrRlaG5=75KPl0^o@W<3eKJH0#*I?Kj8gTGsgBPA zJ`;tr-u{gvJ}6KCjuu_|Ixm1>QxnG)pz7;Jy!v^`gU5d&T#;n%^;(A2B@Ecnnx-Qz zf~n2L$h&3GlcM(-WV9DBwx9J>nE&__Q8pPgN2m+-2wQFk<(lNcd(6=MPudh=_`Ng! z`_1@$70cd5PaK%!d(h8ux!cGIX8LgNeUFET<${IfC>fa5FLKO>uKQWZDVJFPvQYSJ zu)|?)LnVLMUbowdLIz>fc9oiI;Kly1O#%`@zz@R7CE8{>L$$g{+0kyM0T?lBSw+FQ zYPW`;fN?Lv&{wu^StIv0FVJ4=l`<-`h0LvviF!fR6{?Xmk24mwf<3CY=(QTLjl9A` zz+!(}5cGNTa16B_OBOMtuAup-rM()4J@eBVbLW5mA2GLTJv(;c@u8Zdr#HW++=E#| za|gGr8k8gDYFr{-LS$*HYSzB*Q-;+702)?!*P%y1`yPZwb&m*cZOEd;PCaXgn3$SK)N%0ba_{}YVE4SAY5bq%hlB1zjKZuDsyNIyzr zB6ojf{1S}UJ~uccleqm&`dhyTk~Ypn!Wc~=t;!3nHY;T&J1ehwkHdLe(FwPx-{Zw= z9~X4c-|D7kKK!kII8nU^Mq)Ke)Ms?bm1`cqba?J9{rcUX__ z19jzSlEoVAb~1t#b|N%F2)t0SnQQ<@#I=7c1LgR@I9f93xPSDx&wW^X+npQ~0tThL z_3TmIu5~&RwI!TeqMtS1y9A?kg*J`lO*E73(l;LCI(fd#`ybwgEDm@iooP34EJl+< zfHp{=)OYyK6ejAeM4Dck6bEHcuelU-d|aVdts=5-7xW=|D0|EWt={I%n9NT44_JRu z0i>$(_*{t25=I`}rnApj%m3>Io&{zc5D+T5%B)5Z-Ix z03V~mQAP#YC&Oup#3I$I+K||5$I14N07Cni$-N|%34P;l5oq7;Z5*I^@l7E9P)d7p z!vM>?Eos7IvD+Bt9MA~F!+lOO_aA?L7MM=IGXQ48r(rNQXzmsun=_Wh!;YLXVE|Lg zQfdI@bu83DKR;uB!Y!mKf|KFWTdLHlUH!2qnNAq=;Yz?e^?f#566nVYgDoF%$w>5! zhq<3Eg08O%DwyZ4?H#oz$$w^bFar{Nd0Vz$5c3^HRDqrExjj=kYmNbK8c{=O5r0t|RJ?JC=hnD&-f4~dyH>V0 zZ`7X|Zn5!{A}?>y?}n%G+5=0@wp`F5YuZ9R5* z#)=4{pf)$2?s`Oqc(rJKmg8F6qr80k<1Sr!D4>TAh5TSnbSW#32tm-*F89U>r0C8p*9R#f7ugCs& zo=DlEtOj<&N1Gzt!5+kqVvvsu?9%=_>Zj<*wQO0C) zP+#x}X%~8g?GZ!ZT|FPcAGo$!X5@$b9#om}1mWA|kchXV*N1->ClG9LL;d{y*RU#w zEruW_!wsIi{U@$^+49g&q&UYXCIwPH$gM{U8fDyYMK-6Wk(s-49^#8{cQ9VQtjfz0 z{{XXg3zM*-JWvZA@GH3%r{CKrNQR~!BcD7?J;yQlbgia;sD%y_!iRGM(XjhbpRpgf z2g-~J=D8sUHOzlsd+$S0Yd_Xg0w1~XZoO)vYv(nMtG=H3$H;86rd%V=DZsFE=MdS~ z#in+XH&YEu5MFXC94+>Y&ufaByjE=eA=BjhUAVky-eMDI^JcG{10V1J=hUymLIC#k zo*B!0Y_CBo+?k2Bs=Ks%-TI1FYUOsk!Dw=-@hf09-OId}FB~9c{sU^Jv zen}!7q*-SlFyS6OxHAA%F!JwpsmCWObCJ#6hbVP3eB*}o#oHO!YUneuWP6OHCg zN(EbIu{JCmk2Vpvx6C^jB0I5mhk;rKb>iFfRXY`Br(G1hYBt(kj8l22R?aOf4lV8VrnOV0sKrlM&De?p(J6C9+ov4ielu6=!G%+HP~EfM zbU`=#O`Hd;ZWV?Ce*V3mcEa6HrNZ4H{%r5Q;EaFBFg?bpc6X!k8YBKo5t+5sE62)3 zG%qK9j*p4PMj>|;pjNuGf%HXSobS|o6NJM~yS0B`hW=C^MD@c@#$Yv`298>dmdO6M z&oV*rrGK<*5R>wjOL)7X7lW~_K+SSw+BgD&rVFdw$~eiA@+)SAJG>moWe zW`eaL>|h{MD7(KBm`7TGNu(Oh6u~K&NaR9!Cl?BD2Jp0z8!hSJKVL`shnWU~k;T?R zphka`(@jk4;|1gi4DC7$rJ@pRw+sQwPx)mFjEOd4nT+Ba1GQQ^e*SEWG3|hWc~aTN z%|`s^+|-=yr9rBY9~Qjoo}zE5xu2#9fNIUcy50#AtYD{^wkK6Dk0&m)H!NS+6T5(n zHFUL4FI@vC3T6!xnzE!%aIeA@5gHR-tmuEvWl`zF7srf;|AWe4&LkA~wg_dVvf>vw zoDRQ#;lQ1|7^6MM-;ML@=DRMdG{GctN-&%=Su&FK=3R!zdcod91`lNv!KBja^48|) zZ+b$6#}Gh|E}I{knYda;C%AT4YelsWa%vkSH$GW|8{CymwQ+IV`0G=^`t8QQl^cJm zRRk(HxZ*8)Tr?J2`=9odU}6qK{?S|n)>EY}uUd*+kib&(1N4}+FhoF(%(Vd2ZC2?1 zuLJkb2kdmYa(|dQk~f87{UTc$u?duVKZUT59{b&9X*7zVWbFGB&stt4bq?+#RFyoK zx`$gN3=bXGDO>S6D&rnQebp5Q`&mN9d~^Ey>X?-3Z` z;gDaKR^xM`yuD_&XXcPfD7>A8bOHV3DQK1RV6YeuU;Rme?3cfc&1rZS#z#jLD#?$1 ztAat%qyjS-q$!b!Uu3nSpB{VYckgy~y3UhcXk+vY`VVKdGk_6kXrO<&R`p>#U;XJj zo;O}@zJ$EQW9d(xe=`2Dl$TJdVI0}m4}w`)o(PhdLI7>}Oh_P^B?b1;pCz0xh)Q$S z`h)SIbEPmvX-0`0fO$pA?~qdb9e}TkSK2@$bdDg}BiR;#iEm=w`hmIYd{z~&AXKAo zWS$UzUxYdVrz~O+jplzLBuh-~%|&7V57Dq@27dHEC|iGiQ)l%-5~)LxbJarh*x=Gw z^`j(DhGgo^>_#adCBsURRpHa5P?fO7b9WHs1v07A6 zUw+MIfYLE^(!3b8{??9_TPdor2L)cVnU8*o{JbtKb*$XrzlfmUWMrGlB5M+Sf2>Cr zSdaPcLhV-+@@aPF3@C!#n<96`ed{c~yl$Jmy{e8upLV+rDg5w%JAK?+gqHRR?}hnq zU4v6#2^xP%NaWzhqb(AzIFME@{(Vb>C7*ep$v`#r6-3z{Aa+iPJbODbj&u)ykB-0g z0B`j_b*ww!ZhcBq92-i@R-Cal~*`#2n=Z1l0E2|7a} zT9bmmh%9D{E&o4%ns;djb-nvKq?mTJN7WSZs)3Jt(K%dPL(wQdERWZLoxNotv)yZZ1F@J?V~9kw1NWjp2*1H6n%Z%c}-OhFTOLI zty5A;R{{5bYsH)^r6MQLLmSO$F8=2B0Y?dB^i|q3Vafue?Mp-YLIn&FMwl5r0u7!9 z8PR&Pu8|DgYBs}Z>$9y7E&rQR%px~Q!UjeTC2}5#!GgP#2J3b3pVfNotPo)#o6DGM z`}H+FE&f82HX!vqL1z`%FOO>R2lE5cFRtgX`)(0`m9- zb+BC*bdSgHY6(;&ZSgRnk$~VU@p3$~$IyH7;VP=UN>Ab$q}}S$B+suq#W`HPx@0nU zxl1TDCwe|4X6}}28k&Nbdk<7o2FXnmHu`ttrW26qw!LbT}X z^kT9367^L^m9|a2`kVF>2tw|Fow1Lp5!$MJ_;mZ=VJvm9oV!1=1#JviN<`^$wxvUV zm)u;ng91mQnlLZ!++;OPU@amKZZ+zLkamDr7PyrghorGSLUQ+Dx?N-Q+B z%U*Y$di?7FnwyhP)yK)WQ)YuV25#QPEezp^FP%bz*!3hLYC>-T8@6DhuFIAlnv=KuwlO5M zS)Y)m6Jt>X8|L~#Vw;!!dGde(iK3N#C{8nf!{WWs zj{;18YXox9Vw6rw)Sgf`p6<80eAuBm5}!J1V*2O}`Vw4Xv|&+71BufAJ|IodU`+XW zGQUJD`uaWgSd4c2co1BEbvNF?@0Xwa?Gf(Vr_%yX@a4FdydhgZroYr1w3*AoLP~( z;|L<#mdN6$5U?B&0IU7bAuIZjaUC^8r*x{SauvMDVYJ6W7zm#L-*!#$+^3?Kls-{< z`piB*v?aVl*yW{B-7KZqxh{Z51bJ zk;~+-N+G;`oun%!fF0s9y8>_M(Z%kaUP5dbWbdc&F+WS0AUJ@@8Bn;O)p!ngEfbxGMMP`92T~@3$x^#DEp> z%(Z!it@@@kp%a5`t3g_iQNYDa`l zjeRXjna%2S_5HOlXTT{-w&cA%n(|c%e1s_;h_=IY%oKJx^qGj>0{j%x-Ea1ow1iQx5W#A>@7` z^MhW6dA;GBj%->bIFH-`fI!cd+U2`n_!Gx+Kh^UAjNOTWFbZC_fGK{u%syh7Y546DfeCY7a3cQOpW3IA&gkY2zeA3s@~ z_kXa`Eg0AH@F`>08}93h{)X7=2-olv+vjqu_RWK=m;?gJWaWH70YznQHIn>TsVt-z z$-N;*r>^lc?hEIIqa3N?7lNH}Gczr^jJX?v6IAs7D1MZG-Mz9){<=PGoWF{m1g|kW zLAAd|no^@T006U!199@74&6I^mqo0{9q(Y#9O3}2HH_FxNJH&{IXl#`^(0Cj5#kI)6n?Nqy|4XJpu zw_b%OITts7+WFZ_K5ES_V6nD%r;U9VJ`CzIVs9VWSql_6`e;?fBdJFCw zfC98`xqlw)rZh|cqk>P(14n1?N|^{XQdO9@=z4-Q%xUV5x7H27`J_s)jnQqIg9PgJ zbzCxK^`13xdBFuAcK^ZjS>9iv{&S$;f-3WoF&Y_v`Zh_uriDr|v+bcOmEVNSfC5VF z4Qtr^mkz~ebiEeeI<6qNp$+9C8AU`@b<}d>cn^po30S|=w5U|Fe3~ye%f&$?>px&T zmHm%*7j5;yQsVop{u+}JFa-d$nSs@s(O#8A!puC1i_`jy#gzd; z^w@2GRvKW)4rvY32LuFnyTk_bi)^UITAyRSaE>kHYphEeE$FWJkt$JH^ygr5L#%k`N_!5YH2MHw*b z4_lbn)ZOx*FGNB{T}tNe;aZtQxO0$AE_IZ%Ass@`na?3u1aw{Q=PNma(;$e#Fbr`6 zoUR!iAI3RKT{B)UU(KYa1G6sCK{>JZk1nA62>^~wA=Pf@Bg;7vR?E_@MA3#H2L~2^ zC%l6JbWqlE_q@}&aEJ%EmbNB=AmPLV{VWFuTEYgo5MEc1d!zJDZ0|1mNILlqr`Y(^ zq08!`PevG{rfoZ`5%qMQp0pevR1;2FpCyc(ID4#+I;+Re{ldz8A`A9XZ{R^%96L^M z&y*KcBh}o;FJrwRtMxgCX}x}5A@}@$1aA|083P^SsGXSJxk;XkGRYMte|GqiPCq~_ zSI-TYk7rs!;}`%Ig*>6By!}d}Lcfr8)m*Mmtw^Cliy}RDbplDl5=;CnYG@eREW@Q8 z3b$HbSTiyvsPSxB-k^p~N)+^ic4V7fQi4WrTjGph5mZJt|IkZ+sBWFOr1JEC7)7en z@iajLUsDf|m!H_IKf!54=g(M!TC{TEj^gOYBleVqL=khs?=L>+g7$qu**=Qp6}W^> z@*=@x!d{tm{n`XVmf*9vN8%7GpORMbi-TPzol2mdKgpyCc`fpqj)J=uJ=<~~!d{Kw z&nkQloR5Ew*%CM%Sh2pBxvRXX=yYf8Pzwf|( zn~lxow?tKUzgk1Jfs=>Oun3UaYScpyG9CxeK7DGgknyG6D6&@igRxTMQE|6J=wh2h zzW;^GO=+94@vFo$n#2@X2)y$&d4IdYNZp%}C)$_X9egzQ+B8+UW|cR8IPRO=!!u(v zC6#v5Kd24koD|BX zBl~Kz8*rE1h124)teG5C1Ly7V*;3K<8}^1LrAVdxh?~Q2n^6O16#8~s$qjna=T_>R z4HC3V2<&^X#PPF_Gsmx&C1!omkeQd)}ng4$`qBxxHEO`TY{+9aWPquP4eu8Xq%w|8h5>{&b9TjE| zrcN|u-T6 z?q_K~Z?~^coj&tR+;=Mz-NE4U(~MKSVSuJW9L6IUG6OU*5Hq9)-%Iu02xy`zaI6|6Jz%u>+cqwq0^HORT`XS-=o zH=8d_$HMc`oQXWd6Rv@`LzJ3GI{yYo8w3}4wA@O`I`~1dT%v-1VGMc_Wvfdz+Dwr> zCiKCNlsu#>P4wTi4d^|IA}>_9Xe|3E8%E|JKC^j)*W*5aPV9_fYir)Ez|}lhC&mWq zOediq9-DI>QEsB4^}eU%9@DvfaSnfiHyAYwO6k$`&F;AYZN0K$S?ng#o=Xrj7Mz^m zmWxMy429^Y-YDJBb*e9z2&z`glcSR9kUmXb@Pi6}HCpb2SSuITuo)<=_ zb0GV8%>9qz>vSY$vgqxX$TpmJ|75-1fVK33iQ6ig0bBL^eSi>VugI^}@d~jX_?L zZ@rZ@AXj26-eg20>*&0`?bonj)vG88gS}PX{-86~2keBwlhvz*$IedemC86<(;_Cf zahzs7hYBddith$x}mPRStnc8^7TzSFD6Pk6Xg)+ zLp1P<8>W9iulxO-tdUHlS*=+RLg}?TZC7}I01cah*Cf;6d2Nv3TT84o|dBsiw%=11s!0MaFHfcu$gku2*Z5NS1GRSyNvwRx|+CLq&) zDRl4`c)l>fnT>*&1cnwcW8O`k9Daj)%tEJ`VeYhxiEU&vb`KH%D{z{aHm!m7S)D6L-=(kbiMaxy84lU%&>y?|5lYc2 z!Gj?XUQcDP7ut;$wINd7FrBa%mSvKE-{uVKbw2sF#mdQkQoD5#+1cywxJ-r6Fgi`V z%oa|R)H8=j6{1%TzYp(n`rba=M{je@58zk9%hm|B^~YHvI_R_gul?D^A%&m$zh5In z@xow7M)^Z!euX;XDpiwXo)>*9zxvJ-{YvD6)oODJkQmxj2iWJdg6l4R3|s(zpBmpd zrw-*z)G7Sf3(FBrOc7-KpqaI~$GW)>VyIg7B{HJUOKwNbF=tcN061-5_EW}nv0$Fn zZUkKD2e^M6n;Wg0lXoL3AWrCJ3d0&`@rf#fl^f@)0mqS_0Y&qlN)9?pbHf_rM#hHk z-iVY2_U0#F1vEXwo3xbD1hkodUI2wp-M-fMzS3uP@Lr~~x^1B4%iIKG&xSC0CLXlg zg>3iRmy_!3NDOA3*`aT?F3gEDN$i3BD%)xUQ}L={d~Ou+WAlxgXLl4wr|jc>m%CQH zfm4;U@1L?(8qQx^;_Q}HtAX;=dZAxJK)9kN0%c~^4Mwsk;*h@{@JcX$I~R`7ha3$G z*n*9IvGaVyVQrtP32QvMzOHJF<>FDP3?XZyB%#{Q4@_A3vVgZ@gFR@Wvi}#K_JD0jWYL zugCAp&0#z+TIhx303B#c#z0hSa6RG`wLRtCFle0WQ6{M$Inb6Q~^D0R%$VT%HGvOyZb8Uox>Wz<&U%h;S z;FgwOm}PhmHF-!ZK4SCm6Bu3WE?&>y!$AHC&oGp+M2L>^;J_aatzhPjCSS(iWaEa6 z0?5!dTv16Uc_3aF<9*qG$QJ-DKRgV5Hyd!2ZHp~q6mj~0+re5X!S4*w(NM37hhMQ* z%f^D$h7zi5|H}<8VLxY0fnv*xf}Y1Fl1{pq=%kkZaVX%j9M=n`ZG^M5*9*^3oADE4Lt$}^HP zKd_NZ)6!{w+rBXARHnh;Y5mT?&MpQBtoMJO2YQP7DQ+dCxMgpDH*h3Wz66%0nH3^g zn7jEE84b@<6O`N^6S}T2ivpZxHdNW~Ud18SO9xWtJ$1o&><b>~q!qa`Zkkhn_b?ZBhnX7xE)UGT9u0|z6f-bT zrs}FG0Vii3JEE5=W3>H1=cvrQl2n3T=X2eG*f~RK~IOS%K4Pb7>iqC1NQau+t2_ zF~358X@sz-?}+}Zf(q@ifMyA`=9+QCdP_ZVZD%+|$Si!W{Nv%ITBRT(31hSJ-a*lp zENlHk#zeQUO0OVNU7K9*!d-S*ljZ{NB}8I@jgcTCSftLPr~KLgJnVFNbxva?oCDGm zTNGbFD3ME zM`e(SpVVyW@N%SeJ9=&h>RGg6KDU@>(m1CU>qV~ENmLMbsedxZxXUUmX)c<6M$Gkn z#OcAHShj0zIO+_EU@u7D9T>|=8CVJm+B=_lLV~s3QxOj>v%&=h!;Od(PN#>I?Mv@} zy6_g7zDf5~c8+Oi&=3BLI;zH+FWqNq?zGq|Mq9?dF)}IhCu1XfBC>k^lp^BSX`SHf z3Zv;I0j;A3;e`0CQkm2xP!wl3NHPAiu1gO^Oc}%upr0^+zd`H2WX7ASxsX>mVs0nA z7j~4M%Ud)BJi!pHArN;+poJ=ozSggjZ0v|R!VRcw_igu zuc9{K)ft5nLQo_c`#5Rf+q4@yo6NaI+Xw0YP~qqag3^dkem&JhQ595ZtQo?sKYtHe z9DG9(FX=xi#p3MHTjOx&PnTqdoEKBw#%Kb5!NQ4px8@=2a?%3pAw$%ID|<(O8Cyml zwJWh7^F;c{4^iXb$fVkA+oDRa#=#ch>;^FQp!~8tFS3;k51zoVEXsR2{axGx6~d7cwAY)XOAGfFHlScmPL{+r{#w|mcA8xbTvD@|#-&%fdbM;= zp6n;Yb|S~`2Bnr`lD&O>A(l8@@a8HA<+`gtgNu>ycr?>+tRdEE0ZByD7L;5>=oRCN zsb~l>Bau!%c=Yd`XWO5DyX_yb$>pNq>y0YXY)7z9?qOb>vy1AlTQAbWN#LxKucO3r z{4vv@?JGD9h}VosjO$`TTT z#I@h69~V!T=og^%-k|Ofeg3g(Nlr}!gjy=W9ikxIgJ#4&bF?>qQ5b_-$f=nlf)kX2 z|J9uM0MHJ8KZHn;C+CgRy{Lk-Z8~E?Ego!B#K*m+{z+qe@Q`nN)4}pU0W#N`u`^P=K zS{4b+C6==eqRmr`4yPaA)Cs)}|L+FCMIz$TeNFrKaJ44j{M`8>r0p{M(^Gl{>irGT zii{I#UV{VY{FEZ``s(D@A`&KALFDiDI`JKrCM@Uy%=V{$pN4^^Hv$LLoOvBA`R_yvbjMb9HfocQ z0bU#TCyF>q;3{Fqcfe~ka++Zhx)YQ!BvRQ8sw{}>5m~@R8cG1{i9phxBy(nZK(1}lYOSo6ABcs*V=UIx&53|Vff!{APu@lNhU+{9TT4g z6yg8_>JsOk?fmVs@?C03c68}`o_>WSa1`*K!SuV{(SO@SVAIjg`VO*p(rp~7HXV2&wmhY zY5_SL@yxDXrpx!F(Hf4$OXvkM_WUDcl9XBC*8s|GJU?#H$aS=9YuGie zAJcY!N{a=vHTb8oQVTN*3dP~(u}U!IzTEk1el%cOd49s~iiGf0-E;8S(s-z_2Hl}c zL^<^P47&f^t(pAC9u>Pnz;3L<%DZXo23k3oDhbrZiOgH!7$p`Ef_Y=+s&F-E!cN%} z1Tz6*mMZ7zp$k5l6GEy!m2A!~Yaga-SwR}_3S*37T zSf*cPc?c6fqGwZzuk$LwpQ<@C&Q0QUN_e}HPN(YfL*cFkG@{wYD}y^W>6I@N~oibH~s zIxmV)9t~-wPY`WxS(gn=IT-~HU`o$8iqVAz6HL`uy=-;S_=4>+rE5HP32Zj?pUODm zO3RR{n5hQ%FR3bu! z!FA=KAp)$6=&-$JMkABrc#@4CzYGJ&3r!n#yHv@t3v8vA=p*j>>FmzRIm_|4P#;B= zk!K+|*fL)FH!)OerBvFusNbpLn{BLkK+20TaS-1OWxr=pFR78moFtw^6& z$v-|+zz$FP$ZW2N%gOM6Q{tC$S;rjJMar3!@y$8*)k$br-i49B?r}>jDQP zH)Duw2P$`K6LZ&p!5{g@#pzoid<;u=d8A4eylnmei+zFapWp0=cGUmmsk^w{`kg zw-naUO|vmuEO|h(S0N9;t}JqRapPa9Re_BgD@-lbjAvt+_fL*IEcR=3W%kNLkIC}ZYH==9Sg{rMI9vI|d8=Bu za8)C-=hlH@dyjIoW2Kcb@U{LTRdnOPUJ0dxhcTh4bQMVLJyYyTAe7y*R@jOzOu&eN z#76qCGXd24ZF22i-k=1Dk7@-Oqfp|6Oh@bHSNPfjiNS`T(B)c0O-8=xCPm824ngiF zAruCG$^v4xNPw;RE;TpDw+fS(?c_b;iaTT66XE&<1pHV^LW-L(3`B-PuEQKMV($uhc`^=-{#S?%8R5hrYU!*@BgYp}~f& z>D{L+^enC@?<)^DXW7P%l`?ONou?)r>c~>`so{o*sKfIg8B|&arrEUYD7^x{DJ{)6 zM9UN%UsE@yZTEea`K zxy&;$3!|2}3M;%7Y4jxw-qGUKAtE50Mf~NOmyE)vzhNuR3x9ArcHBw1E0Mx9QU>+% zDoe-vGEGsql*|T<@sIJ9VRi#LgYKl1#W^HbHZQAI#;?QQo2YtAC@Bm%4?3DtRCEUqpeIMzh0$b!nraPd)- zwLw9rNb?`%wEzlRt~UNR5%{KA^f~IhxWU!a{6vyOH?fn>rChD8qB`M!{o#_Uw9C*k zh#EV9U|`SZ71}4V_=osTjUBf!!Ttp3C4Ef4=iP9LB?Yy_>?8G3I^NKdQl{i_7`@!P zOupIb_SI|V18`GoRf+8kP{T=9UtX2|t~H*6bqc&CB&*KX)xmkPU6C`Zp z40a#u)37F|a*nQV9JMUjjf&*;nTZozZfx#N9A`~qOv5?3AOM`8<=O)2!9`OOy zoFnwOJUgB_u!*QUCfw4cR4@|QS2epBYw-wNxU4)W$~GLE$N;iU%9IQBQ3G&ShRjA; zJd|DGl(;g|#PPv@ITM_j%Jb3vi}J`ko(Ex)*CEP*3+Hd$wSIEY(6l^Wtj$W5$^sqe zM=%gJuoNEy4ePdkI<}){rKA_=XhSzZ?_+TCfSAG=7w8mY%$EQ>U;vjz_Fje#iIA%m zx4v@Fx$=W7xn<;?_0=JU2=MccK;oEzVJGUnuP0fl;RZKXh2mErPSN(&|{eg3wae=Y+_c~IzoRTit?Pws@H+~l(PLomjq1%M+af2PHe z@L`IH-N_`0v)w7&CTMoF@y#+-z)Bclgqy4Bgbhv|Dx7#mu508j>`{#E@5@4lZ`AM_ z`LMIsBt8zR$i-xG_b8hs>=&*KXCc4-6}B+`-5oeCr}uY)jRjmzl4Ax>FDO-$dTIK9 zfz$ofA~|H;;(MoLQ3G}3EDRLdQ!sNDR|W0zoH2~>bT!oyc*^j!9=Ea4h)7MpVSAbE zxY=4iPjYl2o5(?d1D$hKzH~Tl>9bX=pgtznI~LL=6sSf;QmX6u^*Ec^&p_!n%;p8c z^z4Ei4xC>gzIGVbBv@(BS?dE;$gN&~HEGZQ@&T#>Qwx~jF?91LxGd@%;zqgtXB0<6 zW0c8TJop1BP~NbE0hM4p13PWjhDRevuyL3oC{~QAJZOkN%$9f?|Ge#@z4J37qjJ;( zzsM|!aT3m%Db`e;aicwwT=*f@4&yV=&}_74T_UrlRVkr?ImHw+>Pk4psV@N8l|ADIifD#%J ze-Gvw@&R3Z6GuZE&$TrI-w0q0gR z9n-(gAKFjI=y~(U|9Z&p4YquLlGX_t$>SM>hOSWM&v%VvZqRbrd82eI;P9)&k*dT>IMw%N+G69RpRiZdlMCa(6zEY))!nR4bh$ zZ1o}<(piiCfE9M^a-e{61zU5dL<-&y$sxe#a<;@~U_;6U*EuXyVi`k!L*1|85lc;%_D;kGSV%}ffyG?ju6^5}Zi2UyK($rSErQ(e=ylw8H+KBAw-^u_&y(6khu zLb%0V+z{PvyM_*P(V8HCxtMdZ+)AQ;DY)tv;#Fo9nv*~tN1LJ3tp)ZHFcY{CBX;IcWSJE>Fg02grp@czWjRh_YUdqk~L}t$paa$dK<`*A#M(w;VVn%g+ zC&+UI4$M$J5iZp}o59Opa?ro~EKVjU0GVoxi4)N*sa1G7d)hzuFHe5*%^qdd92&T1 zYTq`Alu^0o9H9)CvkKW`I8|!G|rk4rmlz#ov;!RHNgXBA$k9 zF0{qDRBgqaV+WLr(Jm`-G7hW7#LWfr_Tl4rx#^ubM`_1z&=D~0V%^Jns zYeHAAvo3qng0tR(HxrO5)9@cARYj$*>9TIKu{OcOC)VD&f&98!fMu{RgC6Y7O>BM4H4j0@&5Qex|k1^z(Lys5(cL2%zeN^}_)2d`(PmhjSzx zDNp=4sOT_{TzdaYFzI+ay@$B$k4_K>+Ai%{o&fDaYzKhuh2s*@&p?_H4fenz9@(Xr z1PInnddqnWEE^fTaC_81GTZx7d=yR`(7p^)+YBgwMUUE2055_mUkGt#$!h&ruD)3F zQDS6VRPynwRWYrM4N2olEa0RJcJU{|WD!vEP{RXt%1*vG-itKVxFG7IVo01dPE##l zY3Au;@Lw(}eEF&R`T4>-gpg3V!@4OIo7tj@>qmlZk)BAGgY5i})1Cv^cXjrx*e91} zrluKxIv{N<22@h*yhvy*T*Um!#w%({!|IZf{avgAT*k7zUorPO`EDo5U9~jjX;24W z$m{ua9Ny_QuXpFp%9o|(D{v1?HZB$_m+1(2epG#XplRgW(V~cblnUI90PKkd($W57 z5rNBKyIJWxgwQY~SpncRhQ2w@M{^~|yJ3ERT3x3O(vh>6I`^Sy9Z>pu5&I$&M=Q+i&4^47cGAQHo&ItVq_HMouVt-7YM4h3#$cFL zAVcxcwfeUnW3y$;6@sTrM*)6&}aLXhbQjtO5@7Ig7^h;=_SQ76B&#>>d54O zSCcZBuwyn8@Jz6oyXFbQ>BPurG~gsjA9J0uK97rBg*LY2pEq9N;+Eg#q+i6#aCmU( z$2u2>2{7NPR7_3vrz|<+je3%sT^!7rC`Z73=q4qSMMgcmDXVjlZ0a8X!cA^}LMdK% z#A>z7zL*-aPqvWuC2Tsc);d&uC;<0=gn3}767{ozNE*Hv&|D)a$VhwV-kic>P7 z(6BK%;hK**a-@^L4EUjhTg20&P$rpGNtCyWSn#6JNmq;&moK|>5+%A|ETx_UCI4mO zYF=-93hMJ%NlKi`m$4G!4qC)mwh%{*8+rhnRuJrWY)mg7O+y!s{|h{JNJQTXBn3bg z$Xg=IOQ5Si*tg#dZl(Tpg^kjG%|IPFq|!=-@3NgUr&Yds)F6I;ObZa}Mgq2xNB3y( z>sMaGUhF-|JP(?7xe^Ul0HKn?X7UNtgMxY1#mC&!=i$X8XGJHvt-NrB!>J}&Yfa(^ zN4uf6cn_mS!*lN&wG_Df*gBo(9$W<+42&|IGF~t+M3!d@6|YB?7bA>f=OAwMu8T8g>=!={o2W&Jneu@0VoDrvmrqo~~iOx$OP0UL%lW zny=RDu=$L$BDn@1uyPH5bpNnl^LK#sba#UDGIka)1`DW!|1!f&H1Qj%im%h>=?fcP zb%_bN18&Yd3}t8pS|cTIf)HZRr2TkOguOy-@J;fKiiJB2X0(aRI?JtV8dW$C9?;P{5gJ~ zM)%+?>FE6unB-))g350vY$cTP=(C!sLt-0)A4wy+Y{yxTe@igfui9iyUz~Akh9|+4 zAY6HWQNsvOQ%B{0VmFznDe5;iE>_%dCc|qTQcy~d(dfUR3Q@k89Pko zb*pJy^F9Aa2kF7bWP0 zzX~)(CxHiYqhlDoFSe8KZ|3KgPwz|IaR0 z&M+!G_mNt#(JXe4yjwnrB6{mlrE<%xGl)n(MB4okgDN5Z+ZfOft7Y!1C75lgcO6}N zlaPmLx_{>C6->ZN9rtLU7RK(v3-945_gRrVNxEy3%@lw)r z*u7YP-SKdMk}4*^ava-|+trH$UJBFsJr3C}(duZpjB|;lvhbu033qD&DP9DPrS}ip zM?kgBM*QXUD+@PZpsBAkpAR8Tv07*8tKY9*4=lNS`UR5kSo1Vk4jC>jG-0c~J`iUt zpnWfFiTS#eg5#+27I}y(6;k-nJyzew+FOc$6MCsN|38-iN#dl# z*GNPW*n&&q`bJ{Q*ZmGdxGMS6Tu)4=k6t*xa@7C+$Lz032#CK5iR=Dmgg9V=A>+BD zurVh`$Ds`z>Ry#Y@CvdbM{KbsHcT|wZW5W0`+QGktC(n~{@mmJkzqZb37!KB#VGoJ z@*F8(l|t2IDR1h_Vrnsmy7Vb_!c*Q(cLbd+Xgl$WR516B8y-oe=@ewW?%i@;E=WXP z4vdi;PD6u8x4*BDGdv&*TmpIWa5OcG>%cZnQ@z#Bfca@z4vH)pY!T=Aka>|()>hsE zeUHvoaQ1Ohi`;^^@)eit7Sd#*mjbeXEsJFv9+XWfrYmv0(sE;%Ur`QMK(>d`UVVC@LU5ZC!@o*G#4g(4=x(cO_2C(Bc|tw@E^)MAjTV6ar^ z3rw5aBs||H>hrYb0>Z)3;?HkbWFbk0lu%6TH(5vrJ%^8PEf5t+mShaYK`9(+ ztB}_`raHn4uSQ2$DBP$(&6a07W6B-FI$}vlSc+%G@GCO=MAtgY1mD$vQ#HRLC+c(5 z65OmLJ5yL7ZzIv*fdyi_m=srz_7;x6DwD6Psp~s*BVC3z%+Kdr!rV^F6I0ob1lt1l zhKko%Yn|F&FyAbk__}1B4oqY_tT_pnM7maQu5u;}AN$1DM1HhBMEbLOT^C0Its1~q)g@k2ycb;mt6in2CDWe-%GDWX{6_;u#@JZU%cIH=@5S^J@ zIBWdknmETeIjy`NO0&=Hnq;)I7U{QyoguQ-Ru3=+Ly-I$gImAYgVLww$!DjA1Z!sM zk6#PT2q&=?DjMMZM-{b}NAV)XffT&Vg08qx*3`Rd7?%ic%i-~V+t3qR)zmlr?6X*h zg$|(CZ-P;bgF{I5&CPK*jkVZflDh&1AEK(P#jiG+$aDr*0`>Cv+k}~#&BXid}_~exMypFbG4aSyB)@(;%_)H zJNFQvW3YIa8$Zr}$|fv)Zi_@1M^ppivzI(10uL{(3Tj^XL(9bmmdH)yNdV*@bK;`D zWD<0X?XBc$Od$ynS#`z!n8P3fkj;2>WEsNiP zKQ}}IA^K8UptPy4d5Y#ovGs17!g+Tma$nbM=A4laVnmUDgR}GB&cWvMc%ROW&OJvHeK>r2Cm6T z0G39zl9Vb^_34bb{Tai&{WWHdG*$|IHo@l`EFTq|^ZRgb@QgqKJ8Vw~d`e7yB`b(1-pU|LSpS2Wv$^uIo}EH8Y=taUTp4WL=c zDObA;`8-b3uJ6$Q?tn?}^+lKBbcK`p`5b6I_jhOT-L}LbFAD%^0k+M-F)Fn2@@iiG zHXy>5HIz_Vqzw&<-q7<#3tPkxWe|vupNS}6Gcp=~VSzh2XQ{P+my>JJBtVWUUy`eV z{?@KYFRFz7J%ot0w8`gU{x}38aT_;aw)|YmCSjjr-y>uMk<4Oz1Xq6Zfbljs5%VOgb84x94Utzz(SMJ-eU8q^ z>iyy}NhH4(bxpO)00=1lkQ7YDSFCk-REF9@no|Y&qE6t~TIbkabIf71%4cm1NuBRS z+;>Sm)sEoAp6ynEp;x0#FRCl!qe48zkjFWHShWvryy>m#Wdl-vCkS#!MBHcz$ZV(=Ine$|du285)p6t8xHy;{6+%w#0O)e!{#0Qhc=#&-j}T0M zw5g7#dd3vkZUOk*|L@T^l;927G7GKnrggK9W!!X?u56w{TRX7~rSnUeu|jR--Xb1#v~*5+Jg=v}({5`C~{lG$2eFUQ6Uv`ZoF?EK!nG}Rw|!=cJJ5J zqQ3PJ@$eDi*`mQOx#Ysa8^MNG#)A@VBd%{Z31;r;ngq3n}_SMi%rLVvoQ>Z7q!`vycFXKHECF7tAgFbS~ZDmPmN`PRsp zJvk1x8{1dldjS^E6cW_+ovZ|Z?g>gAGoqh+!6e}ie@LNiOJNb;pa87luTVAS| zI6tML%iLQY{M>;cos8WDD7!;%fB9QroVN400#Ek#ap`=Q9ei>u^woFRIBm`=5VOF; zMw~p9qbuH(n%h!ElpXPRs9d@u6v=Z;>?f%9$4->rJ*1GxQ}Gea<5S zl?ZDW_6|k)*Gel%O^Th#Jc`26`c`P&u9+WNKf6f*@pEOcmVM|!JZIq1e=Oqbl%UTE zbt=dPR6>_x7|^I@l2t^(%uenF{NYGvT}}cCT*0=VftCTf9<;dj8{MAsmmWrz~4qTX!V}kf%G82r>cOESf2^w~{A7Nr->k@QLHlp+jwW7k2_nNI(`RgLrxd zDkF~!S02V}p~k_!a#K2dI0|&Yg>M!ZzGPLtIU9OqMzoFPndD;$o>E-eya=6QiN9$% zANb~B%_!3!Z3IgCe;U8|hG+Oj%-J!6&p39f9zcC7AQ&ZM?J#Z1W4a)P;OSP^Y zBBnIP%*iO*^N23P58izcZBZ?+6+WESKf{cAY&=^FR<`m23MQ^1Ag63{+z@D6p33jW z?AD!plebhWK?T?g?IsvEbx`)&G7q}QoGKrcY7V{7(05UjmtNFij+l|(KJ;&I0t$V z+L_5sZI7wojKX@-{gzEpG|O8p**ya+7MIxlAk-|sncTF zEbcdCe|$cPcd_(z0{0M|j~0pmif%bE;ESt^6k#RXx2gI(Ph~fw9H%0?DOj8VEKl1` zr5{ zk7p~SwbX60jV{4%I`X$wK_A2GS_u5iQquy49pJH!b#hSeMAL}gA z2;`?EKHaXwL-hXD!}zYf%R+#wmkfNmnPO=rymkPcKy| ze=3F2Vm>V7r{RvFQ=0Ne<-g)ZBU55^FSH4tY2X@Oy57=n(2S;8an{U z4gi|fO{6uBVQO53z_0xm>dXP!Mwl4Q)m)_phiM#vC5Q#q{wsw^f2_G3 z+_yn1S>s6kcZGWS-W#b0e_=j{!>3WChCP$OV5571e%gSBZ6|Eo7-<>F#?2f;77$_` zr<1brz5v+ed`q8W5MvhjK*l1#yrn;N+9mhNave5kvwv=l2%MIq43iI zcKzLPE04IAwlOYGkZ)4B`Z8t?)<&BXf$i)RO$IuY#p zLVhMh#GfqXyuQ;Y2gdJZ?E+KgeOabCjkg{P^TN*?ocL0(Qb@8H9J);Lf3C#SFU;z7 zUPA*?BD~hQrMzemAD&^#ubm{L4UTS7pr>P`_P8w|e!%j@EGSoc+ZO5X6T}u5C2DZR z$S~(E??k(HZqoK;mLl0INVVvQqMn@&Lnz^Zhmw6-=jHYBfij zgQz=U?^YaB^77de2~oare_Lb|gr1!560ICKxT#&wDIIPo45lFjIIuj#{joXWQB~yM z*DVQgVgfg#l22YQq^(SyGGt!UtR*Mc9xX9QdKidv-UEE{Huw|LfuVsu-}tj`*H9V{ zCH|menT3`VWe?3=aMsX6tcgh4AdV6&a`8z!pQN{#M^s1slR;e;f5$z;<`EU5wA01J z*AkhB?-fs%lO%zilTdGQ+CD_Wj@-9ZubB-_ zbqj_0Zpci^ACqJhe+7}R`-P%^Sg{2oy22}WCp4;!unyI~Cq2_dieGxU9D&?MtU_k& z+8%N;Oi{v)0UNEBuokLL?YYsXLb8?5L)az#={jisCp9DPMhhE-|MugxkoT78;~Py_ zuG!tpt^+XUjvMAFgBOaID9&lhJe+QqtigAgP*P6GR8b3fe;3ZKW}@JH2$)=Sc5S-R z2%FZVQI{`<{}&7^wAxy)S>8FDdP<=G)LnnYpDw_t*|FHmM!PKakrkvy73fB!dsM}UZuMrps>hrh_V4@TdzyIt^ zn62sQvZiJnfAXG?U>y_Lo^|)C2(#;fS|hZGd+Apw*jVIe&xqUDM1p;FF6cv0se8s= z^S8v$^t{vcs}_yrjhkdp zDP?%7`Z<4oKC~cC1Yq)%rtyL~&98NL*sN;WT=63yf7_H=R)ECmrK^l6b22TN`JT#S zNQDsW0=9}c;}gUEh<)W8FhxYKyP^U)zAs(2M@YRZi#5ZxVZT&!^335jI@yEz!G$KM zCLepRo>h%3$~zP|C679xfC5yk?2#iLQVBt-3*S>S;O z-raf(e<>mF(s%dzyVFP=q6iw$MG1AF+&{wSFERgVeWtoqN!XFNr<# zBEwBR+@rOJPDhoIsNjJe^=#O z9f2Eqv}}gNJvbLlWRe3(K;J1@dyoGLD@ZYfU+nuMv(kPs9EbgAA66$HsP(d6+Faxl zzSi$d+*kvZcRgMO^Vv;>|1boT39i$3@L4ewm%ONj> zH@=C(>IpCOLS&R?W$S1AB~nV3e|q;8RIjp=AU+RYC2z_$uyQTZE(|Xh+_0ZPa_ql$ z0fJbQ$gr>*RM2r%LDIp@FpL!ccR!6q0+lnfC}NapYU4COL@9)n)YW5e!GhlM+Dq6T z%8nKjO)Kyml88hf00}~6GeUk zd6$t)d5gH`M7CQ$MIY60CtNgbB6a+jif?_;-41~&JWomt`Zn#$Si4fbn$uN{~^=*~zZ>e=d77X5^nuQ%z=E%6iFyk7SLzKX(t;J>($VORzG%s;1M-+pWjo zI%CNz@rmXawju7G@O&jBHCVR0mP}Ses zGPkaor9wE4TRI&P&?`Fnw61ga!P9jN(n;txE{u66M#alfnjHD#7M`KFt>N&7tLs5Z zs)Ci#1!N8wRsC$LzA6xlTuks;_a@iK?c(=kB|bm-VB1imt|^QX;|8}$VU)dUdp@cn z46Fk-Ebg6vf6o#pzL4?4nX%8ftn32%)s^FFeRB^xvqp-j#j3+I@jE8r7F}_P@9iMO z9YH2SYdvzL4t8%;5sIGr$LU(2CMB-z{!T*??D#4ABYc;5D~T7av*+V4_c8Lx zo`;cZXTOtmR5HvHdbHPqLVXg0Pw9`r{AIR#^T6NSf4`-F!asI%ZNi2QMr(Eu>Bttl zek-De>=-a6(9-V2d4s zRbO!h$jL~vZIc#iZjz58xCZ`fy!JPwFNM54(f6+uhq=@BB-F|+VNza71Npj5 z^B;_*e=ujJy({sn{9#8F$)UrT%CPHglZR^($wkypXOh6wu=cSL$4JPZ)ND@Vp{2=X zNdp`vjC=x9!-SH!1zgze4GewuW$ZxJk(wJ-)wiDCp3z7}zG2eQGOnZd)XVCL@kCq> z5rjjHsGl3SNsYL?L*B)|e*n!`2gQ58c!k9Syb%a-59%J_5;f3uA z{z>A~1(wQkkf!Nh<~2gMr;(SeWMTUw`jqAOlBr2}J0W(L{p@4?oWhetj>lo!H#&m~ z;$0)^36%G@ZyF~i0F-V?JXK)n@)@S9e}HBsN}Jd5$9-z&Z`RHN@#EB;>haS(zS}&b zbH~u+mrhu@mf?DNw&$%g*z{{4UH-V6E_>+5WuHEctz%4!gS`eoE{vs+Y_>Xsf)Gtj zJo+5YKCOAp>V`e{Ew!q`JHAXjw$!X2eJmTgGs>l=*N?qWTm4z90g%C7x)P1$f13FT zt;-NQPNHN*A7chiCnD8Xs!!5PjXQzHIzfD&elX8SdR@C+Ltmpa1ChHU13mJ1p>)YC zED2#D&oLr#{KZc?uT_;C`GJ=opcrZALu;*IYH6S<2QF+JN`ysE(~t?!pSt?YM@}%Q zn1}{A^_Bqlu`PxRUo6@EK2TF z($ChjS_r>)wnc4hyB*UuGs=iqqmYvS;Wvv7JH148VJy&HFBfc`zIBSbe;xgo0WHw7 z?P)cyt?}VClJ~(}R`)P;l`4Zng1ePRn{Uk`hV*CSSKn96O7&c9pP6;K@ z9b6fp<8J7n&AnPhtRO4o%Hf?laJmx{VLJQUWO9T7s)1ILgt|o~ zqf^^QQQrv=7P469MDr*WWz;;y){2YcG|^Emf2=KaN*-pm`6XfKg?AMz%9!P0Wn7uT zyXm&Pb4(mp*I2fee?&oTA8xSj8FJE(JG!rr4bB;AQGYnmz4iZSL)|+IYyQv?s5Q;A`Ie8MS+iH$l!v$yvN$IfUFrc~ zg}-<(zp)Al>PInF%-XdQN&5{=2GHBk4NSg#ED7T$qcQ*ye^s`neRlr?r4vso^a>o4 zyORnt3avR7o^!S*5`94F-(9$S^ zLL7+jvhVgB))b=`45|XZCwarTo`YNsCiSg!m!H<0f4HmG!Jj`OU*3=-=fv{L3AGZY zc2-=VBeQ7Nc>AoCq8I41l1OpNzC_4#T2C`$#Jv{n&YYEQz~{%vAxu1Ro>|UzzCMFt1rX4q0c8g$^Dg zHMpY{sl`bnky3N`1|bdh2HC`Q|1Pv+WNLpQIlo=`Nch(}_9BBYju0a5#Nr8m(M&Ey zR~=M@3}ksLPg8(m@ykEr%=`tB1MCN z^!b0^GvPMO+8KG|ATNxX#DR=*(?mc)I&X@&CYn`u)MGH5}q05Bo* zj1xe_r5Zdx)G8F3*M#Su>gZ7)IUZgsDT1>CK_8+IO>MLQ+7W&3@WC593gXHy27lg6 z?o%qIE8>Sl{bb|B3?WS>xbWyuQ-m2++Pr@ye@E|fxk9Mn^@mc!%J zg&k=cq80T};JxT|fO?c8z}2qiEPxLM2vUqv>4Q*Cw=#??2~sC9d9}CvY&3uWtoK^{ zq=L3$#ln&#_#1bEhc@tCyK}+#l`Fq5? z{Y4a{#5-Z+CEb3qh%rJNlJYR**tXp7Islv_#3W?$`AuXWZtyZlzQ2mPAJWusGbE@9 z)i?>h)9$L9+o)6;P2Lzrf4k?^o{Gu^2{UeyeV=brRP%-G=U2J$GFK$d*!z=Qt1`(y z+PWG>@RqaOKfm#|{TZTVi6G_!XR>4j`1l!9^o5gn>PYm32GHz(Zfr*OhRlE?K7Ezt zmlx3yB1x#9h~Bjb$39k5nvyg_g!FFkgLTunQ6c$$ZZtC3bb=17e{1BKjY@fZEDqaxPbf zb^7V%7}vplJXgQK?a-Hmb$jb~;YcZmEHI?=?I1#?^BH{B^oMPW8%@Qv0l9Njs@3Fp za6uMmF2RPR7=LlY?5`rJ6xnBjqBR7(APprZeS^*&BB_EqwSZpQeF9i72sRVe zc)|ccUwY(Fl1Mn{V4|9F^%TD=m%Vv6noIpnW^MQPMyJ0UjtmPO- ze#Lw^=9SyvAi%xTi1gCUe~H)lj8YXv)ITowAXa1H1YPDF-DjSduLG>C*X6#L?Aq>R z=6XlIl?bEc-+jqRC27E%bxzjqvAfE~>ued^oJFJJf5_?Tg?;o%^gegJ#TzdBVWKWUi$5?92yPdRW&8dgkeLK#`^t;)FoX)be)qiO}Ho~Mv7)aeczDX~ri$E8;Y zSS5a=2oD5|+w$G1qc6N%DYb&ng%W$HVBkb8;55v62KGzAj#kvjzj2Jpq8+$M+~usp ze}4d_>x8pGo&K}%Raolxd)6K@Gy@rOz9h%&8;Sz-6{WeEbBP4XxQ`GvHBk_UmRR>5K;yQfG zqfG)PA{hAH0Tz>!mAA_}+cG;eG(JP#D*6%lG%)$2ExE0PM?(6FwT4S|)SDm5?nDv* z(W$Kn6T9KHWeukV#E|kzO4F0e(z9@>e->Cm z#`t*HDCqVRB~!L~ttQYdgNK}oGxUk@ZpwXwig=U~lHGCl=z9Vg!_OpUg*iF0FuuWO zSV(JE-aApjlA&@flh`YOm|Z`4uHsIaK!xhB(jk+p^E1jmFDWauc64wH0h;f4du2SH4KYS$!b>f7Sb^=DiWglwk-Ys+96QVbS}e z*fO}`I1m_&d{bSGG zQ24&e6Hq~?wqPV0?}3F?!^Z2)bwckbPqNQxmI`V>TfBZ=wP)`zOCu)jF}l_)BaUo= z5)PmYj@$0$UGf4#S%soz+9h<(^vss9DYedbCn>>UKpacaw^N6U=yUe2*KJc-k6yS{ z1^nVd`Z^ulQ)dMSe~(u}9LAfvFI_3ddA_DQceUbOsxyer1+gjr$|zwAp~#l+tr_t6 z2{h&gsTSGIoiBqmWj<{^a=gsQ+Uc~KCmMQqwE2EjwF=#`nDt!a<%qa=7ggN^|9gGh zFQ&Z9`hId;X-iJHDcSo=Ps}mpfBe``g#}P$^xP0@A6h^J z(n<4PxGoxyTY4hP%$Qc=dI+|mX3f3wIg*e8R|`{68B&JeD|e?DMfHqnZunFmzpRn|O?->T)HtTTeMV^?ES36)84tvr>h)08G-kUI?# zD6KOy{XLZ2!a#qVa+662A-bwekx&Z2Wbi3kwtOo3Yl!j@>3{r8toE3H%Ht|3$D|#) z0@TfG==!Jemga`sO~qA>$=7qYhlHZL?#G=|bGIJkapkYQ3=_go_B#Y#;1?EM=>Pio%yX{=?K?gR5fyYxJk7 zZ|0j;6=3Tp%{$=;Kc>Vh=lbn^E!&9tlP+l3HzOgQK7E)_{r?F??)lzM2>pH?t%{wV zEd&xcW$Z%SoM2TZR_Z$#F}hmXFNPmuuRK%yW9U-a6n|@A ziH6>>R;YMq<1a9ktQKdjbrQb2RBqBR^Z8Dib+sy)z7(W4?Q2~~F)#B8B2Xl)f8UsH zhr>!LYl&44m9&_+T|0CB_i4_KNFh)BH&T^MD`G?Ql++qWf&;-8y*helG7P!uOT^q-p)$4&6guf$c2JN#=UiTxW zv9hrcjjK8T)i4-M9mAJ!NXm5ae~lA7V@GJ}cb)kbX7lf!Y^$#IP6?0eD&ZFBo0iZ{Nre{13cD$eLK z_Lqe>0~mcy`d^7ccRiFZkTN2VcWVxw002fA+Se4RhoM=e&yJaJ%y%Yz+6LJOhPb2RT_iKfA?1;O5yR z0(k?l=fRu})dAE6_5Zn6)IV3Hd`@&xbX=E0h$?8B+IN+bH9Rp5)!Y)yZ&`_dx+PBZXfZ=-dv)#)kh1du?Pm0bgx+df7G;s2g=}6dvM-| zQlvn-5PwOS37$WULqYXONe%Jw(A-pHSXl=x80JpucjB>sWpNN=qyYH?|mn1WMn+JW@!eXZwWo^mKa8PFyFf$ z=D26c(n~`<5#1A-UD(7qFTw{+4jVjO6%e=3G1sm- zDVkKQNxsE25WdO2m84p{C)r}l^$#`oDb>x6WVlc{el(FOSKjtWQ!p*rjR>qezO|?3 zz)tUZ52E^4!E2U*((8ZDjML$8-L|V!EO~V+%9{T=zIAXmfAl8uo}q}z(o+HgeeyB6 zbYH-x8??%ZW(^iCUsFw{M8o2u%`X5kCASuX%0M+5vQD8AJ zLngo$yjvr7s#8=x){~R0BIH!Q)ixqt(n>9fV(8ybx3P1r|Mwx#N~njPV%kqPq61)Z z-xo{{_ovdOe;dk~Gb*XO=kob48*|J8n?Nlh&IdTbeoIg1$>U4+{@5O7375X@Mtrk^ zAXhr-d;UKV=+qju0fpN)2JkB!ytpbdNa(LAmn?>iWZpBWr0P~%=$^D@Z8epDY$7@- zf(wM~@KX=INPzPmE`IRBZB8?kx18yb=(hDG?wKe1e@6E;22Y|ymln=OaI^@gv^?qa zC#0pUtr~^BVCEDJ#keS9E>onf$!&d_+_B~X;Y98*aS9inEd8sVMMrwO&Xq_9VJm_U zRT{wz{j#Ne_p9*7wy#d?`PcK<=yBBF9c#9G4E7{^#g+HY?QtIc9bnoGGjETm>suIj z803sie@JJ*evjk=Wzz$Hs1tE&*-yz#u4k&t(f&IR1O-_zZEqm&;Zy?M0orP&Hj+># zq57uW-tTu?&1!bYs>%6P-ezt<7_dcGw$BE!9>;O*Jnp2(|GCS+O3=o;iX5JZjXNsY z);`W+ID71?G@+b*qH!d#9IP%LkC^VBBi~FHf1CiKf+?EWzq>r>3-GFX3~Vm{?WzQ? zaoYZ0b);B^{XyAUC-G9sq}}AVxVuRTXhK`kM1-!X*BnCBxN8>KMHnvkcefk;rLUDS zC!U{g%Yy!ReT4X#OPgKHfHdQZYEX{SZ3iLNcfvDRO^BVnHgbqO-Nj41MfxOmC!pji ze^F15N`_F@8@AA!K1XY^praXl09JTw9TWjFSjAQsVh;u`-dOH=k3O*3$iEF8zNOp? zwuJ`go6w!DQq!6V{r96LlXn%sAKB&G=72;+zv6YJo`TE*ZINx9H-D@&0)Dg9)bmKC zonWzoA@fpp7@hOpTl=y=1WIKH(Di@V87>r_Fh}fZXD;8VkPllF0PHrS$=}$eNJ=a^ce=g^e0>}a; zH-7o*W1Gqjpujv)-P#AJ!aY00bJ4njh-?xnbf?Q-;hPG?pfJeyK04Qmsw|7JMqJt} zekDa=TiO`;#a2j5%vF7_P>-ifPlZd35R}cq{oCMY-Fm*7$J>t=#DEYFfYtq$Tq5sH z4AXnN9K+DZBeiOzWNLCTe?9S@g997O{lQkZp_wT?bRqsPvyobxyx{ zqXe=h*E@q}w=r!v(esK@{tdbRXrNAqN{-iOE-OlET1FWqV>T@f6ykuWnqiX4W~wA z@v-$Sb>O<8Qh|`TI!cN?`=;{o3`El%H-0C!@IF8?p!dtZc${uZdjz2iS4-<^BqdeU zXbO{XXi-$~oFU)PbD^GXtpk!7V+ZD?Y5QDXjSM&iAf$plxN?UjgCN}%Pa|yat>1{D zMn2&0xK++?3<3>;f4OSQ!k!&xLIQ9so5+^sDc^LDcQEUWKlbg!rhfr=&Do9#1P}O& zbA#Bsm=m+!zI1=nV4d}T06dq>i)^Z_7nx34qAE<5a~)F>D9M*gUu)rC+DPgUuH5A@ zISiDIR5sLDA*1_RE3x`%ug_S&UWlC(J1sk033;h&Ytj1(e(d>?A=(XPGzsaH(I zf+RXmMqtGEoN6OsPny?x=J=@Jv^Ej``!?(V_ei!wwY--JueDqZ!+?;Sa;J7ulpXBPz9qzCf1@l&NG5+(PMaErnwAsRQ7yu) z1k&rGd(yS#b665y0wNXK)NyDz$BcP&UlIWyHG1CE9CFdD$|@i(Ot4R}SeJnSw&3T#qjw7C5MMzCbi(; zXoEf9e+(B=zpO%AAr*I_U;1_N=WIcA*Hlf5HCbz;c)vFi5l#>V(Syc7R41K@kA_U%Lh1jYrjkDL29Y~^-Nw`7 zvE8JnYHRq)>X^;b(_%T@M=VUUZPfgFY$ww&9;NXiR+oXFbu9afS5nivn&8_6hACGcM-3qQ|1vCm{bG%rE=e2?jVWuUju{w{jDsTzl_9QA zM-j42fGdeeV`1GcTsZw>_S(X(&A+}qe_hl`7jp`}UQcNbmafIxmHN%^fZ6M@5XduUNn#LR0G@;mG@TJkED_~>Z;Pkce`-SG zW$+GiheZI#?z-DQqEFd5l@?hL+xO5h(VI(cP4d7@DZtop8dzRdr2vETCu&+%0JZ28 zoSa(U>~MQ<1(iRKjaaqRuL$fSLNN!Rn=9}=EVdyh!08M%<5T4Mt zlvc7FSM-)9onDnb=wSf<}7%WUUp1xjM>m6e=WV^9R-$JuM_Y{Ga}C@Kex11q`=UEaWt+8OXD3 zW5T7mC6PJb2hBes<(hH3u$i=d4W$YJUH&cAj=;A#IEUa&{o+^U1#+()^bqU9RrE|F z;BFGxOJm&R*mslYWI|cMe_sjVQI=2!QWV)2McRG6Hv4AU+Jf!uGIQPd&W*QE zQwno?b32T}Aw851Bd&)~`|7zyg^(b9P^c+IP^{zg^ugTp`w0z_e@nkic?5ir^6lQ@ z(bZ)U#VLfbunFFsqTMYsN>|22$Y{L;TU{<_LNvmpQi@$*)Oy)lv;sHKP;FeVGHFbd zzUxp7WDiDR<@Tn8ujbAq7M_J0_y!!=rb93aRU*)@ zdSo{~(X;J^CiFtWfBGm@2Q$a^TSVm02XIB2Y-IDKo=b>vE}gy1zl^)2~6%=AQ0Kf^s_`F;b2b;zyTmfOp) zC8a5gL&1!NQ4Ts)qe4^SQ%k;yea7q{4dMg7%BAKe+hs)3Yv`pToZR~tOJ7u z<>LeUJ#c=B0q2gc24B?jV15-2G~cE)A`PuMgS;*zw-}VUCr^2n(xdi@uc{-m^SMDh zZHScc2tWiNslT!oIEm$8&~liR*)@gs0zmbRlUNLJVaTtI-DUJ^XOmCy{Sm}}#}JBA zc5=#E^YaDde2ItvPnUqQJ=oy#OZ*B_L)r#$20Y%`7<7QCO z{w&0Hl4jlqK6K4Cc?CescwP4$ToLUjZiKeGMd&S)f2nNSQXRkax>W z{VP9y->)jX@*)U>VK6->`c>d1zMMy~K#7*V;1mdSNwq%i&mE_xNBw}mC#KgQtD^ir zXyLqCe^BYJ#ht@On0=t;`RJf0(z=t@oSSCI090s+mt&aEoj@!H3~~~5*$sdb!YC}> zV*uCDX;~&^FyX*NR;DoeV+(N6=j)|+F9i5v>b}|ILjWvXr+)6PGcK}>HA@X3hlvfl zPmkk^?f&r`BBR$~lQ3p*J*o5400Zw0PCZp^e}A2#a>6hU(xqz6+eIncr+`Q1@455`wwFmz74=Y!d7*c-0 zR^kt>7>>Hnmh3sSSy^m63y{;Lt3f#1!F|@yh=!s8TsV~Nog5Q4Rw(N6wR9wwE(qsza2^BK>lx|E&4?HfE zaUL72)ai6W+Tz_HR!~aDi?&~6KsefG5n9YQBOlD;=R2>Ih&d{c(8^-5q;t?&kP1$& zvUH#Vp_K@EoE2W%L=Gji5v5C*rX@acb*20lgMz0D9LV%dD}VfkCGHbzQ|SCoe;WVW zj43^^Dgf*AL$2U#=+HhAeic%)n1KhJCqrT8xUN)fYG^~*e9-jIBi~>>*%T2?HOvOa z%xx@!1emU=@kd~n0KBg24usZ~)kDl-`Kb$Fnj%`ke5B$5kUk3{AL?)swA2bsC07~4 zwVfp-_?#EgoDlz7abPj$b#U8^fAj2XR9^t;wga;jA;?8%Vyv=PF0JdugK$LjJ*b3i+g%5`GC|mceCHhp#Md$l1}N)e?j!OAqj$9JD;CKU-r-53CCGHt@+J zIRrkK!B$C!MH$E{#SoN(1{8EP(vv&Op^X9MZVlw}5{XJ;NTVB>soEv9r+_emYOv=u z6!#6sgi&OFIHggs|0`2`Ug%L(YnzC@6l8%=Dtaa4lBtcct~6x0e`J8u_epB#4V{LZ zf@e}!|FTPmv@!>u2vM*u3wu^mCKgIteYWmO zR;rHhLNpjJ3u&<#f7rtKXFn7J7y>pkuFJzv>hUJ4>;M*tzMA1wMWh5vMY`tjES=gA zZH$|%Ja5Yha5Dz`O7U81Ok+fra^-uLSZWA%7YEi~g0-vysAReO`3+!dvx#2+8!_qI zpe}sA^b@7yIc`{8@hFfddjg5CZ7}j3CeRweFQ@H13%Qfgf9m5SGfZc@AIBegnm#kH z7Spyy} zFyrCK(M$km3LW#cT5UIJKRz+np=xHSFpKLS}% z`9ZfV4b=O3_-i6=tUNX;L=I$|h#l}AfbQVIKQ}dS)j~#$L?hqet5mtNOm_0}6Lqfi zv>G_@D+w;`L1CNL;G+@+(So&tq>kkW-HuP=Kw8F8e^r%{Q9|&$^KQMLkUZXa^Uetf~4|m4{ z0-(Ws5RV#3+QTZ9Cg|90hQpY~rN@d+Adm~Ei~Z+}Dt8tL|K44% zBe75Yez<9K;SlU@3;~Kn_XC`1%>C|5@;4o#QrMU`>-*+K`!>57>>XHH?M&Q#`FCFh` zGX*_sX+5?88nhMm>trU$>kG=efTs1i@aZ*-)}yHWCK+f`C$`Tj9tUlk$0+EoDt+(7 zYW&l*`G1)?C9S*H8zs&XIT^VV6VoQuon^irS{LeN;y0EZK7IYW!}^NT|U&~vN% zH;b3^5Jdnsqq&Rii0Rx5R3??i6~2z?Es?bYAb%{)Z_^yRR?2KG>SkYQ+oeoaH}y6y zkbBn|3drG>)7WmeuydaWsd8@(dSX97o+gOCks%;`9?lJ}_fUaSSRuQp@!hdcOfF$RrMyL}pk-j%nh&eZ+B`EqW|Qm_XeMd5Nh4(fpi=v)K|* zUp0!iHnZ{l+*0W&Awi@-(ttNhk0y|^pp^JdDr($%9j0mp&jexheGVhgq*35?gOS$B zLbx^g7DMM^S0%Oe?{@YEncYXX>3oht7Jpy6@`3ijmn~&|EF{IXxQIghTn^J*CuY?S z-5`}vtC7@kT>@8Y3oTOc1xJH1xyfW?MDj>V$j@`0`{_Onb-|}*v-|%!_?Q7aFQUzTd~(C2?ZHHi=b<~z3Y}uwQZBbVet$1| z1!}v#!}u@ukqEOhs;IG5h=Q_CyNeg7e zcPif@{Tz=fp^O~n!D-IFyhpzc8I|TXBFeq6Bwqa5>O4tA8E^uE$uV)9ExHI&b<3i) z4E5kCeH7|hFXgI+*8AxBp#}W=baqC6PiH*fla!P6JF$GTFEE${Mlk|2j(=0m|B@P8 z?2dRot^fTfDemtBR^A8|1de|e58@(Kmyuhs|026X{1q_|MbqQq27lhujAK}VKfw{D zsn*I3MT86gJ{`L(d=n8bE@zti3|8X}-&b2o+%J#2^4%9N`IjhLg-v8>HJ=if4OqZ zpNrtGy9M?c?I@o{dF2dBY0{(Ea^zDsB}>ne#Na=WtTI#`N6Cp2b$@$PYR6Eer)#j9 zva=_kzZE(O?-_iS2rRTzd@SSYENMpl3(!JHEK99$OWn(BYp0*{X_iP3KK~lySF8snUkRuCA3`~5PT9>K zuA;mrqk)KxA~_Q%$$#Jn2)})w_)+5_KW9MECI-;lqH&l!?&_T`=0YQf$aEt{KfkRj zvZ|W?EMD6SQMn$v(=Z)H-6k&jXQ8<@`XWLCxTk(+bdW4V@T`_2xUPoJu{U#>{1$}A)7_mf z)*-vJK92TDtbg-jQrYZAFg>#CoNaEbMHd$SU$i}6R?NB(&AfI*pE)A1e>o8=a~O-y zW+Bvyy4^LU8o6-a54!iRMrgzx>SK%Wp52jQOZ&KB-3`AI8#(0UT5!c4TMzl-^(Ju8 zsP&v+Zr~c%K}cuNzl-#T1V$D3pF1ouEvK4-pbkguhQ4iqT{4IoXNJPeQ%x1nL`wc$sHhX8i?Y2RYl=mdPnSHl+tuU zco>QTZ#DV#%CY(DSCZTpQv#!|Qa%PJPxH>=LgNrP4g2N=9YGHL)GrXLbW?e#roe3% z49Y3*41Xv5u*a9;BBdn=>VF0rwxz(jSt?@ltCQAG+tXmNRQ9t2hJZ0fFCJfm7s%zuNsct{R2(Tc^?vlkaZhpJTzuO()u z>?tW>{|{25U>A*$-zbtEEpW(&R21+>Gta`k5d;ap_D1jm{C4~lW0wqTYHO6Ua~4Pt9tZSJ5@{Pm3Uoo4I<2rg9-Za0C9Kd`_710PnZozE z{DX~3CpNo|SU9A?=8G7Az+T*lwBB1@pmU)cM+iBYCLA4cj2DiQ@9FQYqmens1QyTY z$hsw&qsR8DBLBpe$OOQguXEf)K2!T0L4Q+OyH)olE|2ic*!a8VdG zA#Tpj$ecdA2%?S6eyPApPiaVR{9bAM&Pkw8II!x|YYSp>W5I&hjP3*LpKzcg z{(&ukSdyvB8MMs)jjM34%Qo=@|4T3Iq134xt(B^*k&M8iwuJ{j?>D;x-`EyIT7THZ zAJ}K9c?B_xl(?08CRk7NyimU}D`>gnvur@Uhi6v61ny@Cg#1;Go<67!{|p$ntG@}v zi9`3La612vQY*HAo1P+7CTnk2oZKof@I4DY{jZaef@7&D(-fF9b|U;mkc-VuZ+{LcnE`|~j%>*Whny$>=yf#Vq<@%7_Y<{&p;+g9 z^^=`#W3c_VAlWRH46aX7LT|bO{{XN&Ahfu6?-X);Y$PLxN%6LIupcU;Xh6=q zmr{NNyE0IDRuR9V@nYaZNo5w`GXkpKZnEn(kre++EU9a#&*9e9v>7(z)M)*NV9G}I zMSuiiTeGU!Cz}o3#DBYGr|W{!P<68-eVaC(>OHhtUO`G#0#|68vVuCvbcO#BMPjBg z7F~0f+^K5k%wWQDqMj{T{n_r{V6-qd3ypiNGH&>xWpS@ojs|T=4^BFlyG+v7oM2I& z2OqmNzoGqG949c1jFAY^M1%wUE^Q-3sN;JJt0wvE8s&9=m+ z>(Tna)+qEeOFqo7W^IBeEHm0!@0k)j--vR}Uj)mBsjYQhj-+57i}osBn^LcL`%?>i z?#MbQCEAIXzhlGnj5`gx!+H2RXT>zj_TligxK;R%3p?f8uJvxKnK<+-1}8nskKz6H z40Y)*?1v#>hksV*i)Uchr28kYP`mqU#ba8f=x2GQS;YDqt-CX+as)F!cC@KS^Hb+OcpeX z8&_@i8GnB~%WiXMx4sHt(%mmM_Ci(^p$e$>sjF9yl?*@J^_?>*j}hBJJwU^;fWrRW zC>xU^6Qp*M*1J!LwJX${!)dwtLt@P#nrdq$v1|bnNN14*X8vD*On>Ww9n4}NHiayj zbwUR#V2!fTLmf{u|0`tyn)?=IGqcA{MZ$@Sz@`IRqRqZX>i@sTOuRoTUPdEwS3;PQ-I3!pk7? zGW8~*XnHA#bf%3#Tj59Q)?YW2lnmKAP=9M=Qt^T-!E8vuuZyVRq`<$LB%Vc-*;+uU zoX&WgSEC=aC2B7@W+St1ya+f`0Luj`_3w5yT@uq0?Vz+NLCC^HQMe2?g_L>NT}}@q zo!Gi!{nLNmfMRO^Jhr35d5PH>#W2~)j|D(M3ExO-9As$a+ikxlttC>qR2&J1(0>)I zgA7cED_&%^I87GkG=oIJKtj18K8ND}w@^ zIyDQqAg8W@X@D=WSd+lAX5Zqf%6}prjwAlMfClhjT2sBgaXDC(a}7oWN@2n;GAXD) z=FCoTjcs?K{T&25<7$y$6~?w&y3(gKv5w_f(pe-X2}X;S#OLl)P9orf$Z^goBDN3L z@iJ#DS*I*(LF&)4xp@O;JRwodo5GA9woo^GB4J~%16V^{h!8HOkAL4O zP)vS{V1idaZ>-08ktv2a6Mt)#0tkpMv{V_HN;@4V-q?;jiL9rT5kt+-xZWh2)k>C? zpb}p~fG^Kkz?F_^0nq{ZR&=H7z$(KaHz_vl@SG*6p+=`jxCf59u9C-c53))r{k zp;*v-Y4%4ci&^*ZW_?&tAO1P%V4c&(`n0>hTE99)7iib9FAc90%zuTwwp7Tz7vOio z$LCqt9B`~T{a<{Tp10XeC&pz;w-Lu4Ik30TJ{M4D*aKIfbgui%Yeo0M^qc1?G3?b` zK!SpB%`$=XpIXS@HYWZUaaU;*r%x(lx;$GQ`LJPegk2t@C9Vu#EnEzA-u>lcK#sVj z^aQ{O;1%S(>A?(Bcz-nDF)9QO`;99CL$CMz-xk}c73`quP~_px%wFn)MxRS(X<*M$ z0OqWdZ?rj&c5!7^PE5WJ3J{-ELmMnQKNe*J7zQTqdf!f)3 zmz1OeUfGE#*kP?ow_zS1zXAm1ZoTI=;fz(Zh!%Sw|I`=yP=8_X{E;W#@H0^=khM@S}F$)ZdwhL>vV7WkP!wVB|IFgRj z+{)|Ylk}Qdv+@-t zj+3_kynlrs!8Y^DQgpqLzYo6D;O&Z@2)eJStG%}kP0P5X)0+k5Cc|k=_h5lRF$del zTzCm|vVYyeO@Hx#hiiQuQJx{+By?SU*8HO|DUwJxd(Cv3)u>t zRkr`Ni9uG;j0u{a)zJdv?Sj^?C-GFw1c-}guTJmdLdQpowi1c@ETK3Y4RlCUT(hC- zhkpbC(thGmYLGik@uTn4NRs6jUvbE&CRc_*5EMLM!()!@+|`4kGJR+P6@W9(h~%1+ zh_wWndvywTKr5R(##%tKksda4FEP>6xrm9x|a>i)@G=HY|yNhcym zNlVGtACnS`FG$fMpq%C5a((HiR6wq-uz&35*crnCxQ<9Pa*Clmk*G2F=UW(Nk|c)W zL(^Uw^4y4`o=eKyKJmwL?+M_l5o9MCkT~bf*EIcZ{tAvh&k0l@V#=puLolen)`e@0 zGvc1pFE!gc$zFkYOi9yTO-&QXE(pWFFxByLqcqo$eHkxrxO|$HWDnHO#wwpFr+-l3 zF=4A$g~lN?6;B-NC*4Mdw0CV5b@OR~???!qTf_%{r3i2$d-~%s2QEeE9a!TA`5ppy z#iE!7c0Q%@-#m1uQ#EQViM=>bkURGXOpsdZa%zY!DTzg?a|q0@O~;pu6MtQ--AU8i z3?Sd<6kgWFZ%*dWb)hOT7n?;!k0XHulQwM|^qKW&m=T29b^mLlH4W_=uzcKhWIeZX zBCy*b^)$Q8!yxv`N}r@;a_x7yd4Wz;BQ=4=Q^c*yVf`Zu0;kM62knQBOmNZA>MGn; z4phfxY`B&QduBnLGUzv~CVxvifRMiTXsp#y4wq@*b^~P=HD_8|1-ty5-fh3{N|B1*+WEaLFzZd0DZEC5`UOqAXKZ>xTzej zfTgOz%hRlbw;dlntH0s#A&7KJ^2qG4GLUyCAb|MCs_=q6RZ5Z8XJirp!6GG12$BJ`g?R8 z*)o8+H;R>h>n{$1Nq-<_?=dbu_Vp?a#vW$@SQ_#F6C&JPJLqpDsT@wUh zHXc4a?;JsYKcktWmo30hM>!dr1rM=x_^d1su+wThpYUNDZ!eY!JjcV@Hj2j z#?4@sc1eM1w)`rD9^4sYr>H>?sDZqvL=w`-FJ!$%+&q2qkg{g@Hgz}gGzR#Tetlbl zg>gRRhd7j1qYPUw_od9db;MTi+F_#P+>K>rQ16raa(~h2rZ2#@>~TE2<( z3)x>*f`9BJzQZy1xJYrn=g;IFBLQ-n*B5!Bc(ksCNmzYX2+q}U1NQFWX>%PvYlQX? za+zPVExs2)wFqarpg&^^nYFm0aktF;7oc5B^=`ygug6IdRpr8o*>*@Z(Ieam2Z1l3 zTLqInIa8lHuZ7=-pz!Tm@I%Q)5-{L9D_qf*8Gk&NVb#{g0yBd~SNOMhYRo?YDrh|9 zT_TB^M>RCzQTe5|(YX0Oc0Eqm;TU~OBN-ag;e)3nNUtpo(|PXp+Pf0sTaKQeHwea8 zrNfr$xdmLsT6?^sVabR9e$1D_@K@T6##)XV%*vC3n`jz-h62NQZy^j(xhQaG?Pk-W z6n`JG?E{;5V2cI|);k1O9dT=+ zw8!|pO0`E50MxZl9V=lC>1XAC$GE#;y`QX;Cfbe=1&v&e)3~9NR7B?UC5XpM_-W{; zupc5tby#Dpm7dlx>k^~o9;wa_;a?phjFu9OKAn0!fCMYyj@UtV9s*pZKr#31DKJjBn&N8)bCLx6$~O89L(z-98;hvD^}u_z06FWIdY?0*JeusC z<^m@vm6{?>ys!oKKluoj?f(-i8Gn@j1QoW75}GhMx$S3*MLHqfy!5rQF8E@>M^PtZ zVdci9)~E0Kx7c0v&-L38T5(D4x**5mTX2$KlvQBX~4bUx@Nmwa| z%9r65obF>CHFj?A#qM`UucoP8GdLbOQQ5IverZVofpd+|nRu1I8;1Am0U>d5uA z^0kNASGS}0GIk*R3& zdh~JFGDj#jtg)g+N<_GZPLC4uVwOod zPRTRCsKg>)U-GI}IM1jTyBE4tR`6ex#E*oB%DgZ>F-xOUj&0TQB_lxGAvVj^?$0+5 zhj&Z!im3C-4`%s~8Gk_Wz?mSNR%^X>0Ah6DI(%jC&5-%3r^lv6wGWi*|oeYx0zYMTG z$E8Xxk$QxHO`tSn-2AzZN;g?~ANhurxxiKrDi>$A#xR&;v8lu91^}Wzn1_!|U#z4w zzG@A=;)#1wOW>R!5ONBVhcI)9oLa4wjbIwobUD1gCGC(xLgT3eWVLwo)O6LgNd@}-Y99bB6bhM24o# z+I1IOv2rA8&jV&pfYBAjokD*KkUFoRmqLaIw-}f?c4|?bTE)&x3B-V5Cs0)Ta#Dr& z{X$5BYSLb^b77#cR?)ciJv(-5diGQ)o%|xpxX-_XH?T>EsePt<815SKXG}Jo6JL*_q*uL4 zYxc=lGukEK86wI47Fm5n(ue+XkZRXanJ9mlJCA-jA6-xismlctvKpaeQ^e&1ym71q z>KMO!`8RP5yf{T6!oTOh5&W_i`1arB#CZJ3^6pWXUP<*szNpiDxB4X z^;*z-?~`cfFX^4s;qvh#uj-XYK>!Y$(+-0X-&>ggYj^8~@XCXeoWbbASsRc=e;em*mH)mSwvGXN41BBTUeW+8X}|K1%(1x z-}C(0$7(w>wMSUVi=F;zqfpI%1aJxtr#JmCprjB7sucH^eN$C<8tnZxsWvxV8?%_9oq{q+9tt52N z33NplCf;W_eEKJG7Jdt;#?xodWPesEAH<}HKIb6P&1&VpvJs>9LxuxhXIh;}N^-iE zZ5J}i^1-0}`VtzUQ#V*4TB{mH!xzsg?Dv@GrHzJF;jD4$fo z!A^k$V90;ORC7iX1RRTzRP9$_$aZn0#Cv(>YPyD(QaX1jlg4pkU~|;q-0cS6MnJ2S zBg(p-U}{{5!tTIyqRot9dGHH#a8EkpbrNC??@u5SQe`%+hY(e3t~f4Ugvj7fBSzS> zG_I#D*#R(-iL18dINf?(V1N6;V}1&R%)q-Y)iGqEf(yJ8pEa)sR*}9^=JBtJrGO-x zILLL_2wJO^g(unXMMV2dYiIA!uQ96N8%S)9*kj;t2hIIK41uW_)1ydZ9Q{eFnfg>25hs>>}Mh%aoGI)jIfg7 zslyAWp;LmpuL&c;?}8CQUbeOrMT93&N0EPujdn!ChDR$KxZQkD?H z1kef(0OxK-aXRx~FU$Q|SwhjQQq{ZjO*|82yrwmzRc%!cp;Hm|_=Tu7p-L_?wi^sv zVU9D!3vO0rwLc zuDUnb@4@h`$A6%f{{oYV?@feqZI#TM->LEB<+p{wi?&Ay@)N-Mp#%9I&F6^Du|qgG z1)yME&D?7U?7!MAbc*k7!I+FUmN&-8gA`y*oF_ZI9w|H^Y{Z^b?|K{`XXR@7MyFtJ zC37klYJ1`JJyAYBh5NHFI1_RrJ}79`$ghUmhw5qIm49@X4TzTATQHOJe%cUTLL$Ib zx+9&<<-$3hXdLl00=$+ZOY{vqBN@Ia|8Zh9weu4DFf11#)!dkFec=f`ZN=o9l zWY8xn@#o>DvA-QGI#8cWM4fep2}1GaNU&=^5~S8A#>z*};KLc@vbo7$<^avrJ^}^z z_rQEPs()4VP~xYT>B-v9CNg6tp(u<+-0GGHt63eM{W=azjPexX4jw`Pf^6}X=4ga% zLYCp^W%=%)fP@bLZ#>GRCcG2*1D56XQJoT9<`k&J$cI#oZUM2Hc#+CtpH$#}Zbrjk zQ2x`2eg^k5aJyo6LURWW;*bUvYH(lmN);C%%70Pt3QILii2F8gV+q>$mnS-dN=!XG zlZ2TiSog(}kgc_;QQHZPkXZ|1k&fEwaQ@y3fM*)X4W474-7Ct#d+CHpbwfKbu!UG4`q z-hWVDX(TyOQs;^L%|uLQAo`^>SPmH6=t864+!O7pQ4{R&E*vmfg?WQt03aE8a4gpx1vRh4-aH2Hp4Wmy^$~C%!a=#!9}diEtuU5(ZP$N< zdA-~{m3JkfFpu|!Rg3ObhTKqqVJ9hXoz}fg4sN?G4K5IvBaT$+1Q}s(KiAamrootp zS5N2)yMJu5jP{EJ5vu78P|3<>LVx-)V?^l@(x1i0TMtq;+|pEf`_^T%s2BpurMS_l z-sO*SwDr>d#MmkbiZr}vRI10?ii|MY;e$l?{t&R3s~qGC`*?ny7^ucQuV5`}V_c9u)Y4*?+_}<*SJ{l8`3G%E z8xqP!dD>kebdc1f0Sx2Q(w6NKvon|&V6q6kPoAqFOCNDek-hp>#}|GmU32~8P%mP{ z&@dxycE3&f(P3gZAl-+}tz5!a=_k4G~G0hbSzDY7PWD7-I z2e>h=a-U{XpZGEkdA(chAR*g5nI+Dirs;Pw@IHVlkF?O1@gFA_d+$G^A3qNi7o+yCG7ny#}bOUgR%$_|$uoLUD-X5^=G%RN;u9@mR zbfE))$CnZFw1?rUE`PY4;GcZ^dz|v}G$U(Vj3-WcHd?C{zvL|Rhx-#%w3hB&DNb~w zzlcrK?h6|X%`9>*EA|H@54otHZlB(WdRqg~;HrjrJOr>0>$JCngD- zaw|tp;-!4K3N;d-?oZ2701@nXy#f>=v4qb${zaEA#(5^cnxq>D{q& zsq<^+iG^F2S;?! zul{v}@AegLRSj~s;y4)VkV}qzm4;`lqGcw(;9ZKs}l97Ke>;zL`(Ki=sfS zynhH1U;S(yV}JV9mqXL)b`-Utf$h>PkDtThKV7y9uBCV?sEH*TIWJ8$k2$y`r&Fyi zP{~O9*1pq|Fr8VQ)$06pc!{yQJzyiI&9LY+A`Ihzr^2+RB77z`tJIFZjP$Mf{$+Nl zve7nIj9akfxX6u&r24q1?`WH;NVAzG+-pv(Cpl2&_pwUD{ zBRiJ!^`2zMN}iRR^|*tgMJAg%)VliLCd=}%BqM^)c-7d^nX&<8*v`Wr=>mBqNJNEU zd(#+!1+`GNHNovogm5M>HQ=MH!!Bz6_vAp6vwtV&$+|xmNTOSo)3Ia&^ohrgcs_m| zriNK8x(Ej|^wpX{#xf$e;SC5fshunOL5v-B=UyjJLT5=agM!MJ2E}w~Ucj7Hx;9$pC7?~HMjv*lBv~v7fJsnMMBH-N3si!bkHr_NJ zp?@O!fc2cHk7T3Z*;=RVRas>!aCz z2oCsyPUB3*UJtNd{Y`Jaz-y@488kITFFkV!$A|C~v7=Wic`Z+a&PSp6Pzk!H#ZF3B zM}UDYb4PrxF*%a0ej8>`2SPGQBC85*P=6%B=IT303Dvk-F0b)^i_$e}k!7uBt+h!K$JSIy%8h4q(3NUEOrhBIrly;2XA2jy?3VCCb2_pfwI&h->jk-!b zWAau*lp8;emS;Y^Hf?>pl%>qyB}bczPZL((sJUw(-tsr^!#pMLNk$|CWLU0nYMa{5 z(Pfef&_1Def56w$wSn#J-B0h0WlGtle(MA>Gc4I4)i* z--PQf0kSM;a0Bp8-cW71qM<_7V_OLw4OjW1onri@1I|PS3wI=HIO{HvN`E2aqYy5u zQ>w%e!qe^2cLZ=9SUXfgATh3m4TA=x_d#{v{pPXdKIEMp)f!HFpYHH2f%;gGMCR%& z25r_)s917e5}0>{$38S8i@5iiH9*W;@_5NyD@Jz9sJKUDdQw!t4lb=gkVJUA4-^yG zwM>Kqm{8fOFLc$RgzOCd1b-Or>U;@Uj3RuNqr?o=A0<2%&o;F|jI&+_rY+Sl;`hQ2 zzq2F%98eK3#OA@Lt4K_s{=zQq5;B!yfZN#sG z1o-zdRmaj|fuWP~nU7EtcOOhn!>XfX(WS^tCCxbf_u#_4M*iFHMt}R%NGa^zM2WRq z24YH75^k;^`I|5aGkc&EPzP*n=1d6Q`x>EjlZ#0sFDK#y+g+=uh)W7N4b^O2PiB@o zxHtQyF)cN`4$jJ(L-nGU#$|NB@pZemY(c8^BJVkJiKCN=Pc*C*3zl*8x;htq2sX(g znOyI+5OzVh@@!V$L4Ty$X(&JsypiTIKGXUgceX45V^qxfKlxh3m6WX>ZI9#M8{LMo^2?;5?7NqVw0 zTkkb~Vd8?2G-F~yMt&Ohd6Q_@k|-}S=W;$Sih;x`UmwSm2!De*v>TOUA~+DY*{NE~ zZ1mt0xkR;R1q{N5E==LK-E5Kp`uEs45V}+Z3C2lL*^7&$gj%E)VnXN#z#>PAI&{*V z@cj$yc=5k6KR%{NdJ-e$NhXkrY6uB|zrjh$u|1(zm+h@=G)ZDEI=Vm{W=&)fh&xl4S-2?UY^W zdanXHzcSOeu>L%(qAza1o-I#t2$DlV&YIxMswEn+hJWrthva|Dev;BT!y6osp$7=j z_TOg^56TO>PPAp)dEdb1d2?&k(3WF$&#fIC!-W3=dZ=f0LcP(CZV6M|NzSz}2)9}G zznGZU=b{M(a(vrVeS;o4{ZRdN#Vt^vnx)kJBN`1h$vpaB$2(CCh)SC*-hJChWFe|Lt<9>!a$oXZ1Qz3IOoX`#l=3sWxVP*BRjKW#a$l4Em&icp%D ziSh>$rm1c3+X&&r1fyuU$jy{78-Z#45 z05OnQWG41O$*gU}^1O>%I**Gi{U>tZ9rhhv+r)n0MxEbyqbX?T?o~;ex{Hh$>4T~* zTS?FU-&8gG4T>7F!%!CxbD9z9jyr%vVRr=%4m}KQ4PLAtxId!I=lHIO_caC!Mt}Q( zeT)%!Rfo<})!Hw(5kN5U6WVTp^b1V;RVo1psNJG>HRKY- zF@t%&T=?P?W#`bgVWk@o=>GdQ-UXDYG0{4?NFZ{*L=DdSbgt^uE%dvqXmJ+u!p5)cVL zFJB(c0b`U$`m#KqFBLs!dYL}s)7nVm15h)=oR%!JM3Sj*R3g?DJAXs2n{)hPy84{J zR!SJuo=+9Y$J$YD0_snp7V^}5>%*wrzu?#h3zqlVw3Vh5l1mg0VXq@UmtJ?d`jv!4OD%rF0y7v$+H z69kjLm-Xraz;2Oidtl`4r+*)`DTds596SZhdGI_$MYCm0f>yvIqWwoseMfH)ln%mP z9G+P-T#fvewAmIEARxXzS5~h*g?3`~f;|z#B19e@E_EZ`?SEjFxnw2_I_>IN0}+fY z7$3q&{H6Nf>9~RZ;Yc(MgeHFQ}VL$*d9IEqONl#OxOcDA9}8r zFWOvmjNleIFjJd74+0N&^S(1hd^Bn9_R_~>xR|T#ot50~W0__DQgw9H$r$fuUtB(>!=ABUiv9n1(*39G(Dxkwwi| zX?#L%Y0&R#h@CHtHdYFd%%~P^Gu;8jq-mg}HzLo(zp3|t6d2HEJ1?7S(8Pk7Ps=dH z)*eunmgp`^_`*v5m1!Qecno%9XgGEOQB=mA`InPYLVvbed*H0?ugZis0|6pR zDsQTQYUk3IxkiUsl;Galfl3*^wyoR2#kG`-_Qn+38yVA5Cx{2zs%Rx8%Ksrz3wbFS zaY}3PJb#n3()@)ghKjE2Yn=O_Y-u%fm1xo-_Qr>aW-~8Wguc!aAE>7e#L;i?H2l>R z%|okomb-dkc00h{lhb>w^8pwbuzcKOcJ%GB36tVDkfv8ZLvgEX^+Zv!6oOG_3jIw6 zK2+7rj(UD%o_uE|ak@(Xt~5by*aM-uw;57nDSuY9`6mE=VOoJoa;sXulY6K3fZX5( z(7ZSNqq<5}yc%?+cxCJoH3$kBF=^p}GQs5b{-CumeABcS1T}nZ(VqZL!L@*$TT{F- zYn%k8^N_wy+XEgY(5ti?eH^Bon5dL%u=sL!^tWWI)^-U-B(&Cl`7S4Ox>GOttcQ4d z6MyeVg`*okWp}Cx*O-X8j%G5B8Uf2}bNi#Zf`x|bwfnxB*2|h-w`6re!pgsC;Q;#% zD%uV+&zBIExWOWDs`kb zFQq9JjB_JHXef+X{vv~OJ{rMsc!Ik0zG54-SsJc<4CH83 zp{;{B;tejJD?!C91Km28iQoKe#DBz`7ixjqEtF7*q-5pBXmm%M-~~_N`p~0ZtD^hP z9Be>WP^?H4>#L8(da3EDJRc7jQYdcY4Xr6&dp)t98*!>*eRiEN##pQ-x8qQ0jDPH- zT|(Pwd3J>fDUxoEKWdj7UT$~ov+Ym z4AoH1fR#O7O}1cPmBk+-ic*Px%IH|{ zGS6RH;rAsGllsi2a}pg%NAhOtNusr`_Gellcv`?#iAsxrYS9Ix$u`e`SST{GHV;aX z^J1OXe&}K;(CR&LnczqVDNX1?Yndm>ncwAM?czgR=$LIyg)>=RGL*FZF(Y0G5%@ZU&hA6&A<)aZ*#H>!f(?#4*@bTID&87 zMTA~rvd2QJG=j7(MSoWU+@{9vfB`x1UNs~8yOUSH3-HC!dit~sq@<0*qs&Q`LF zuD@lQTT~I+9ye_ca%?;a`Q8QnUQTHt@>K1q_bh{6vKurBv45lGQnMcRUylF|JC9#= z!K%nEmQM#G8xNfXGowbZ1z_OZZhM|nih^z%0prx_X8K;F1DG1k`z8zDr*Wy6V?kQs z1t^);!;WlpZO>5gwj}d*K3l4;Z%YOegmsehXn$_lyr_5eja6u!OQ-YN z`r3rf=Nf3TsqAsPgI*M97Z6G6TJB%Hbd19i-aC0DlP@m7f`orqsv5f8lb!@fE!2{B z7VkpDKqRqMy$mM5a~+K(TUY5P&cO(xq@XI-#51-D6Incj}Fxp zR6-{KG=eHsoQy#lYVU8fD9%&=?HLOi?b1G3nbFxh^V*UPv9;WmB_@@A%sMSL zHyU<)=+i#J_%qK!?VdOv0(HpguAbDYnzEjGbx091T+V9~^DRfx-qA7N(~5rA(~t7G z`r>Qyn{RZ?W@^hCBHBz8IvKXDA9zLNrM{hA!XpgSzH5Jf)72pWuNQ4lCA^mADi<*< z*Rk{YJ0Yx&V*r?;m{ZBs#sX?1b8YjV*E9C9?!sJ zzBwVhHj6KC-Mq`zRY8BaPDD#RygRoQ9wRe8M}`@C4D6%Wl22A`11#n)1l|~SE1$nq zE|rS!T7!4SF@e=6K4~Kgi@CU0Ai($<)GNH!M_7MAaVp33QFUN4X6^g1;fnI(qcqxy z={?X7VR7bSkPTd>)9-7VKhRe&#Xp{)PT?;fNP0 zTOxltEImVgr9a%o`9G<@f6@a}gqoacv%x7>z>Ac5C#rD)(ud70&9KF6gL23=#PqPl z33(6lYxX9}f($a?aX>N46dGHSUGrx{&-Lp4`(%c${zIz3&sJu+ZF#^)dOoS@usaY8 z(KHd(iR}m>$1A1f@ZJ(nGyrwnTy0&ex~zXHvAodWS1I0jEh}<0y-e-F9|=hv*3SMc zQbfJnt>RDKJNeo*xhDt3-1<_n>_(_t=_n66hpP{c4wTyJE%KdWoK{{Xhd7oh4x1Re zsznz;{WdS7?6OB~2BW^~GD?bYnigXJK&g&vIy?C=n%-Q~A<}k`Vl8Bc-_7H$A%%a$ z&1gR2YIu8gv;uE{Q6pd+YAP>}Kuv6nCYUIgb1&)%PDvTVR3|HIzpD==Jog_e2LYGW zu#1)k={FcXud6m!64_4Xj3(yYg*9-}=O`yL47NaLjf?o@R>(APyIc)kEtS)k(zn*W|N9?czP^Cjj-Kzu>3rspY5L(AG!qAh z%D>VrJMTZmEq!ZeS_S0_n0bF`sl)gNW9h@)c7jpi^xCA}gYiUi-{;V&$Pw$C`Ne*` zja-4}ErE@z;bmaj6;U4Sog64-on~b?;E+n^ffW}tu(1^EFai~BaRGsA*9@Qu;3q$a zG){|%M7ty)C12DC23pdnHIPmds%7D#!3!FLxhRDMB1&SF%bOS^#ZAi^a+V*Sve{%(?>;s!_Wo6B0@6&dXGY=2u01{v{8{8J@w<{fJ z`Pd4+lW&yHmX-C|KuM+<7c+rdWXiqqB)T{`F-mFw%C}V@F`J!_{SPbT78ygrgGj(M z$sK*$e?tv-d6Elw(mN%EQtQ`^!*&xe_M9&h!QZv8X-P3=iQ>{Cp3eP^8g<;R; z46$F?YYA^SIpb9~n4$2`JO(2|LLEpTg^KG-K=6--|H*%of|69S6zZZO@MpQglO})m zyy(CR4*if7ml zO*4UM=-ldJveADa`zxW8`lVpw3g}{M9RLkXU!r$Zicx2v`f-qr7e`UgJ?Nwv{&nQq zPw`}n=rz90C4>0f4UQ+uaaqk@?blx`>*CLLmV@vGEZSYjDAY;^r;Eq?!7*{x!jM+d zE?$YF&`#6%kVxD)I)KZu4?4-AF;9sQ<*<0%uRA~VN)LZXqNS0gWG%V?97k#mfAa)L zV{B&z5jQAMc%syToHFWHHoNpyT`$}51#-!1GOfjMi{hk zi>A}VnZRBEU3JeDLNiNpnO*=5KMVW_l1iT#86QiFb~P63NZzHlksNKN#Vw}>jCY)N zeZu%;rfGkoJ}~#kw68DtEOaw@^D=bV_<@p9qO_8FxW);&kW~<{>bharJW_fRL0WnG z-NO48z7&pp4?7JEj(HvgWzqT0(P8GRrHPL6({6WJ4hDoj8bAr7V8}%m2zszFLcTFl z@x}1eDWGq~SmF{T>MRIt8vn?_ISdaPg|Nu*J~e;dfxcpL zCH8->RJ&4mP-FDrFXeIRVdrL-A`#15AEXsF#4UO8|cnWVdJDa2qq#)*oLV^~aHk(D)RYgtEH} zx3_Myb^sB;1b(p@jzGCc-(*=uP(SjrEEvx8Ia@NA?OBh6D-BsyCw)mU8(|&bK1Jb- zgu>+0`Akr$K^LK2{hLIOhB;N!zU&LGVTi*H=l5CbH?p8<)(YlVL>byiqzzVy%Lsqd z^xC2QRth1mlIU71{b$iA*w!q7{W5peKWT}%Lz`X+lm4o3(W1uHc0$Ym@Li=4ueeYY z(z4#xVEP|h;6xFAItyZrID4jJEfu;dVeobofV}JIf&igg2D>AwqDl$~-f*DBO-MS( zuTdAT-}kGTaM-kgHnE%J7@-!WjgNo7ih|aX?O~5rwWA|FPWq`INgpDg26JyNmBe%=3t%1_s3FZ5o-{ZCvbm?T}Yu` zu3`HW_A0BEg z+tZxRB{BIQAzzd-;eX~mkn0h8Dlv!4gob(6HL+wAZPuDI?0EKyq@aI|U4(0%TR@4$ z!{tz{+T!rDpKd&!CUdyYcwNlr?KtMILNEvv>Ave(=k_dsQQe}CfL>ENt1Tx$e{a`$ zrGh0~aGsrX{mfBMt@VMYKM4Z?V4KhKw3I z7oF{MV#3R6@g!yj=6~r}9!FOv@UKVYshm??>Ql*Z+K#AKr#*iR6e&L7VBwN@;SOAc zRv&Scd#+DPnjG6;8xP#P)^vk)a4_z&T|5l6k-}Px`Vu(&g9w=_D53aJHtIYqy`V?X zo3vrmu!=%GI(`=A5s8T_DyDk~v7tQ=&LS;yD@ZcduYxl!gT>qks)Cf2&&~DpNN6qtAbOO!j6g-02kro|3AcS)NR+{RBtgLFuCVcA*zclT2(2^j zJ>d1saL+QbCw-7xDb@iH#qWxF9c9Ir?}0YcCg>DWDmjXXO#+%2_(6z<>3`(1U;ghshY(*g zUeA+Hy#RlY6KdyUsNoS@yA@j)HraO4-bD?hx3$H(sJhT^s>+{a92#(J6E6pF%>=-f ztp6CZ+F>f#f<`jRPd2ymX%s6#VYurXAheJk`SDWos zdvKI!f|Oy%yy{#b4I1E{KJDJuPU=hR!u_m%P0eK!wgvpuX!cdBbW8Z=q5@JJf zh92aVxmCu2*w@IVz&r7s<24*;CUu!{xY&QvPQu3rWCExz0q5nZh0Z@+#vy0TBq26B znQ&`1Y2lULcSO|~!!Lo5_CV-FoU`q!xA^S4p?~$19K%5}UK9#$tsd{uPyi*$;%oALs->8lr!f z8>0zbm3+aY5E_%xghOcv*C@N1NrwnHhVWbJz>l$BO2Q0E2WJo9q1ZTVk5HTRp4AMC zf7v@KDSN{PNNaG&oVNPw!Xt!s?V;1TyGb@>lyv1uWZuzP#rN0FuknmTYl)$DUj*bu zE1)T~fZS3#_(%X?i($i0CUL=Un$v&Al74Czk}H+bWOYs)`_&&uYI|rX(>#%AqFQpn z?z50C3hiOw+?0M{1&-LD8FSVfKlVuckbv~&^&3n1!u;6HA#;@-Kf2M9h!Kp=Rs=6@ zhIWoQwcFw;7qJK6i+C~PCfIrqCvc^LRmYJjcWz8(xyrj2ZFd8~=`yqLL|%W)V>2u_ zR_z;u40Ql?Iua-5eO{y5oUhtrid2pv4j(>DjMZp$FDjRUalp1Gk=29&Z_>xLx-OxX z-z1oQ;;4k~x#s_e4=`+&9z%TnUVTvC77)RWU|VCU<;5O{#iy9_A$hg?VTdTIh;f?) z6Ms`!-}nzU|LM4x6s8o}fWCj3ti?)XaJZMljfaD%GpfVtv7x8Svv9fa?st4c@nf!! zwd;!R);mtMlI?^mb|hjLYIOmCs&58FA_GTH>{?}41(#TU6X%1PfL@X#TZJl7a+MU` zxhm!=Wc1UnzBVJ~yN-f{LYEVn)64%@HqruJ`A6PWFFD6et$J!%|6qUGzc=|P;pH0w zC%b)z@G9|13iWbqLcis(apr=d9{VU zWMpv;b2yd}7pw{8z2`e&6QXX7mVvygXNUZ#8fVE_Hjl>K)QRq-a%`tx=+kX8 z)6$G%cs$<@@ap$>%Jn0FQ@w(?Cc{%es3_-yzw*1z`(A%C2i-ZHL~g-ux?xfh53C&# z=JSN_4g|uMo`MJ1B^iPxm~`lE23krK5E}EWWY%OH>XthbZgEAbXi=)=ZLldXs#9#$ z(z&ZuQkxM-Wox`_mM{{QhxvT$uVnNyRWH^;5Mz%<9gd%B&fSB3!@LAJ(#>xfVO*Du z6_#o#je&ofZb{JD$JVMxu^`k~P1-O25+<&!tJ=^@%zaS@2>m*%A8lr}`4nJ^kr#oS z=~rzTmZ6HP?S+bqT7()|tHxA!Ue*R63e9_zfcREfET&sXQHz0-kX|K)f+lzeyfV=^ zTgNfUqF>C`s85YMR!~xzrpud5&7j7EL$8?ZTEBm=^}Iu4Bm2Q;gTO;qRkc zF5&Mxy@ysMQ|tn3BKXq#W`?++Vi8P+uQ_HAS#TnDS=WN4@b2DS*ttu1UMi}RIOF0Y zkeAA9ar<=s$l|fhNdo;4dkp0u;(XBwp<i+~gkXn#sLnQvU z7mQT9p}EhPQxRnC6zX6@~uqV`ecH|VX5 zJJ5Zr`|vPECz(tG&p|)>8_SfU>w_xoz@U%&=S( zYaq!D|4Iz-brE%PtBAKLNM-ORkzoVPM{TynMKof)RG%Z366gw|YbjrNSh5oni}d92 zaFa>mvF?RzpjbPU!_StpGpo$-tXpO-(c4f&-I`*SnQ=Wmmh6_=fll|>;d_4+H)o#O z;Eo6p+@$;4b?>V4f@^9v?0(FkdmOGB4%~IlFJLAF<>T8RDuaJ9T!RZ)p`(R$dV9=F zeKh6c!ONIL43+k(Z^A=UP~EU}u8#yV!GHisb&Yv{`=1_bP~0YH?4c$GnzG2vH6bp` zI63+%rXq>;+pFnxfKrtw#QcBB;>r^0)N?-fqLPs_4m?H;N!f6}eqyv2Vkpc703A

    0zt@w>tU9+a!1UciXYT+dmc#|Xi5M0ciDc|awQ$sH# z$Lc<^6@?t&qX{VwH6Q*Z*#n(>Y;*qRk`#I|Rs1572P$KpIPX~5*t>rTbpHHsfgZfb zDf=lzivZoz?h=Lj4oXo2Fw;h96vT`o?aCBF$YM;L?{P0q(00W=k4=5&!Ue@?;87Rt zCb)ES)UZ)YF+suyHPuUTy7aWn?ecYlM}SmNRDeP80L59gfCHDGV&tB$a)la*8LK52 zmVDepQ zB6um55#!i?FjwfYV5&VKJV1$LbyB1LD zC82D3JFv+WfRlf-475~ou#d>c7bWo6Nfu4;!eJvJQlujul0% zGfbS~*zf6!y3OsQ%kyJT!R>Q$-+gtFwPQoIcZP9JVN*Am=&?tW_sugco^@tQ#k+@x zZ%FpF+CD=&c7lKGdu`ddpzGKSP@j5P(-On zS^nlMRqKcf;8A!de6|PaLskO<4j5O$Co5FZodK14n7^JUO_2lq#BNpT^WggV!$-vL zdp?%ZK(eW=sKqOl_fySJLiuzPoL!>Xr$Es{eJp5ux;a7ITD_2meqF^ZVwf}rFT>tv zr%(#6;oW~HO~nP1CFRh8-ii%Crj_<1hvsp_>RN5g!JxLP4Y?$^V)>?K?WjfW6vfpf z8`dXJ%`|F6R%kp~u+B@%V)l|aWx-mrOM+^GIMBtKx6(v(e}=(R7zh5M-i$TlwQ$kC zv7!$W=sYhaqsmdO+(!>dWU0d;DXTQoX0F)B;+cQf;qhav*x(y;AH=9pU-F5?{BE{~ zh2Brm<;r=2b*MwHk82m<<+>wdbO*(Bc%BP<-b|Giza(W|I_sdQ!ye-u8;c{h^3ILp z*{jd+pF#VbV+RDD<#|k6o9fB$a`u#+_BMI+vYiFjn~S=FeYC*xR(GPf`?6mKX3E@B zXykul2R4)zWI}Fbm(g^It6M^Ve^hNe)F706@X>5qKkSUZm7RYXjA94Gp-z|PJ~@oBq{=LCo0=Im6c{;N z79&Kddd|;3+(Aq!VOJACTXcm%H4vKwWi5OFpWMk4t}stle%_nN%8d>$!#_M2MYp-f zGAcU;f2@(wJ^3P*Sfsh{B;6-vbw>0V8?X)ogBq+-Sgc6gJ$OZNC|dYcM~smKz@>jn z(fc&RT6UefjzHx@!GH~Ix1!6k;W%ygBvIIn?O$Vw##~7=Hcv%BIw-$PK;C(lj~Iu@ zKFIEbW9Oby2tk73AE(-@BG0XS=+9>1yM58`qPY+#7#eE@Y^3X(QL@<%8^7si9aPC( z9~=~-Dsv_QQiqFr0jlzdTG>*i*D(PjhWKLR!|4<{l%JM;V+$@g+wgrV7b;o0ffLyDW5i6^%-? z)<13mM{dAcXvL`{H613-d@TcY?DR4s4cdw$x?Tj0q8IF?aOc0N@&5~YseykckmqxR zptoi#&?%)ujs866rO|hI3UW8-k}f*kI42*E$s3kSs6=nV+K0W0GQ-NR;4O023nmEQ z;`3xU_u(edI{v8>h_v&R4yP(Ek4Jq8`W7;CQysakh;iG`uagNuh((|-^$JE%K$iGi zr)Ht7PPD4}$D)upcE%S2QBNlXNM(t$ULC#vXNWN_%JfzN9rQFAtTr zBJ2B^^6K2#B3(cH4MM7>!Jx7Y3SxGZ>$5XbORPDg;$fB!56!d|JKlp1Hf+7zWkeNi zUEd7EUl!{@k%0Qw8LO*iq+9Dwpqjs7;*8NBEn=G%Y%pF`HGB@RFZX!_Ikv0wueh<4F zF8|&z&@5h+we87vl8QIjZxjut_~oStH_J_C9u+IU_`19^5<-(8=`5ER@$kU9_l;lv zpc!#^QfQV}JwXTxv_F5Il`oW{ip=e}hSfL{<%uMFlv}m+3YWomwT*5;7{faeC3~m& zBqw1Vywr?F5}EPZx5DVK)C9fwk)=!*4o^Nb?NHB*@$(LPM>?$QB^?g`P=UH?F6iG#=k4IoT?5Lj!0VkAQ!VjYNzH&yy-+?XJDHf}`~| zUCC1rf6&;e!JdZZMLTVQx%66+8c$gar z97@P_r}F+eg6sgu1!_UocOFhFFY+&iI85T`JUf$IAa^cU!gRQrwQ*-1_HkS%o~qVb zcNV%m-{F7AibFi-GyPS45OiT^VLkrmIB4%`mveJ;M%_*&fm+6j8f+4s&YpOb8BkvT zhdlOJtpe;0gt3KQry4^4y$5Jdioq@6%$YEy>A_gG$NjMhgy~6L1|yzTMjOWI>R8Gof>{`tOf z2Kj$=`)w{gpPvktPVE2)P(mnzNuDxtv&cTEZKU9pzb>?|%c(NvjNY7DaVU1iGk(Tt zk2uTSAU+CDcTupG(uTbGe6$AZ{T(Ag-Gu`R-^v2rK0u|;v_7@6Qj1K0^N`w^fAQrE zou#G?Thm*g6GeXf~;VJBi^Zu=ajI z>nIRf)4F;`Gj}jlGx{wodB0Nn8CVdmc?HLD+xn z`DDdM)eixZ-ERb($xwq^FhoetAb>CM2_eUchmy$VeMM_0oVd82e1Ps5&x1+Jicy~o zZj;0+Z2IgMM;BE!Qnb6cZMOL93foU60MLNEUirB<2AlC^E`;-QQG{;_3r-!f4KW?^ zoWH}i0H0sN-l$;P?r;We6*D7`I9%v>DZ*QUBQOTt*d3Vz_ZGr&9ee(q0Ibh|LJEn`s$ip`O@C>-K4yQmgGRVc zfXFAJs@E5y`G3jyrA>1@G__cB7)yLdlpo={Q>TFq4#;O<%mq`D;HTjg8+^g26}o_; zIoFJc?)2D%aWg3FEqbymp~XdmGq+2k%QEq{vr47mwH&!OiV)Wi3OA{J!x0sP)!S9lXGiHDfv0K6^Q&> zxe{%?z5sMk`!a{34-VGJb{P)zB(pZYJW+nM6K3RMm|Zjni-$AeQ(u@~Aq?I`g}K7t z2E0s+I|^I=c9>=YKn#wOHY^@eS5b{ARS#mXN6lb@3Q7fKhThp!#4~^U4I_v1eeTAj zhC~QLfhFTZbG?;`bz(>^pO?5A-P10ngl)x#*iZhLT+G0H7Bdt3U1YaighZo!0C4lxQ{@+?X{jJamab&~R+UPLQCO>PF=)Aye-GXZLfko9|BKs94rdg3-s76vU*~ zU$*A-xc|}M<-@G~+!Ug_HFJhZ1A2ggrTn8;RZgm3B2)S0UMyPHMG1bA*xL!eV~SV2 zMk%>H66beM;DUm%d1jFw)*YnglWAT95PM{13$s<}TYEDCb?tw69ukkRRj;N!2EE3ETyB8gyp#Ar?!-7`TZoTwY*f4(@x=1IW1Q|^xdV3gWT zk=xwnu6JgNPAO@$ucE2=F!HkA)?@+X+2reUh;G{PBpk_P%H7ngvcIR$_L_8tDyd4D z5XDmYJ;VI-phADp%Ql6)#|*IIiO&?J$l1A*F2p<0j1KEq-dC>A8|)sHT)FdFscPt) zowN33dIzgQmDTTy7T+2L85bU?mka?yQ0$T%202%g1M+DjYM!s@^uKJ{0hL8$B8^O? zZA1SSWrE^e5UT?pf&vM&wrzo1lIubWE`Xkz>?wv!o0xwnU|h-eU3O4>oSI%ui&l^7&gmOm$vk!zhf!WY+C&!KB%d^oBGy!P�g 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

    hDEQ#%l!&; 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

  1. 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­5F+Hpjr7C(p{p+q^?4!A*`RaRO< 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

    #NEPAvla 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%0A#jhaTb7v~wA3HK=O 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%0D!~#{S_Z~(#1(GGS+d}*MFm@md)U_g4>icpYK&^ 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%0AnX0mQ4pt6;q^tcAt*D)D8IUI;41kI? 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 delta 744449 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

    QvZ90i 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

    suKgH^Vv4F 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 z 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

    yW;0_>lkJCzXoX(Zxo25Ve_o>$}u#R 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 z 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�h`pn{ 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\FY7oDOY5s6aet8q6DHs_!Dl?@6ejU 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

    ;Pems7uFO+v1?Z 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%0AqX64rTS8 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 diff --git a/pass-to-make-check.patch b/pass-to-make-check.patch new file mode 100644 index 0000000..a0bc8ca --- /dev/null +++ b/pass-to-make-check.patch @@ -0,0 +1,164 @@ +From b30eda522b141cf4b26a2fb22c2123d487f4169d Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 07:49:06 -0400 +Subject: [PATCH 09/14] pass to make check. + +With this patch, when running make check command, qemu passes to +compile. + +Signed-off-by: lixianglai +--- + hw/loongarch/apic.c | 4 ++-- + hw/loongarch/ioapic.c | 4 ++-- + hw/loongarch/iocsr.c | 20 ++++++++++++++++++-- + hw/loongarch/ipi.c | 4 ++-- + hw/loongarch/larch_3a.c | 3 --- + target/loongarch64/machine.c | 7 +++++++ + 6 files changed, 31 insertions(+), 11 deletions(-) + +diff --git a/hw/loongarch/apic.c b/hw/loongarch/apic.c +index d6ba2a2ce..67994d201 100644 +--- a/hw/loongarch/apic.c ++++ b/hw/loongarch/apic.c +@@ -64,7 +64,7 @@ static int ext_irq_pre_save(void *opaque) + struct kvm_loongarch_ls3a_extirq_state *kstate; + int ret, length, i, vcpuid; + #endif +- if (!kvm_irqchip_in_kernel()) { ++ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { + return 0; + } + #ifdef CONFIG_KVM +@@ -112,7 +112,7 @@ static int ext_irq_post_load(void *opaque, int version) + struct kvm_loongarch_ls3a_extirq_state *kstate; + int ret, length, i, vcpuid; + #endif +- if (!kvm_irqchip_in_kernel()) { ++ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { + return 0; + } + #ifdef CONFIG_KVM +diff --git a/hw/loongarch/ioapic.c b/hw/loongarch/ioapic.c +index 3de0ed88d..60abff855 100644 +--- a/hw/loongarch/ioapic.c ++++ b/hw/loongarch/ioapic.c +@@ -253,7 +253,7 @@ static int kvm_ls7a_pre_save(void *opaque) + struct ls7a_ioapic_state *state; + int ret, i, length; + +- if (!kvm_irqchip_in_kernel()) { ++ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { + return 0; + } + +@@ -297,7 +297,7 @@ static int kvm_ls7a_post_load(void *opaque, int version) + struct ls7a_ioapic_state *state; + int ret, i, length; + +- if (!kvm_irqchip_in_kernel()) { ++ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { + return 0; + } + length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct ls7a_ioapic_state); +diff --git a/hw/loongarch/iocsr.c b/hw/loongarch/iocsr.c +index 60daafd6e..13d356d80 100644 +--- a/hw/loongarch/iocsr.c ++++ b/hw/loongarch/iocsr.c +@@ -95,6 +95,11 @@ static int kvm_iocsr_pre_save(void *opaque) + IOCSRState *s = opaque; + struct kvm_iocsr_entry entry; + int i = 0; ++ ++ if ((!kvm_enabled())) { ++ return 0; ++ } ++ + for (i = 0; i < IOCSR_MAX; i++) { + entry.addr = iocsr_array[i]; + kvm_vm_ioctl(kvm_state, KVM_LOONGARCH_GET_IOCSR, &entry); +@@ -172,8 +177,19 @@ static void iocsr_instance_init(Object *obj) + { + IOCSRState *s = IOCSR(obj); + int i; +- LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); +- LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ LoongarchMachineState *lsms; ++ LoongarchMachineClass *lsmc; ++ Object *machine = qdev_get_machine(); ++ ObjectClass *mc = object_get_class(machine); ++ ++ ++ /* 'lams' should be initialized */ ++ if (!strcmp(MACHINE_CLASS(mc)->name, "none")) { ++ return; ++ } ++ ++ lsms = LoongarchMACHINE(machine); ++ lsmc = LoongarchMACHINE_GET_CLASS(lsms); + + init_vendor_cpuname((uint64_t *)&iocsr_init.iocsr_val[IOCSR_VENDOR], + (uint64_t *)&iocsr_init.iocsr_val[IOCSR_CPUNAME], +diff --git a/hw/loongarch/ipi.c b/hw/loongarch/ipi.c +index ade182abc..59186f1de 100644 +--- a/hw/loongarch/ipi.c ++++ b/hw/loongarch/ipi.c +@@ -25,7 +25,7 @@ static int gipi_pre_save(void *opaque) + int ret, i, j, length; + #endif + +- if (!kvm_irqchip_in_kernel()) { ++ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { + return 0; + } + +@@ -67,7 +67,7 @@ static int gipi_post_load(void *opaque, int version) + int ret, i, j, length; + #endif + +- if (!kvm_irqchip_in_kernel()) { ++ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { + return 0; + } + +diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c +index 6eaa53d74..f83bd3750 100644 +--- a/hw/loongarch/larch_3a.c ++++ b/hw/loongarch/larch_3a.c +@@ -1435,9 +1435,6 @@ static void ls3a5k_bios_init(LoongarchMachineState *lsms, + + if (kernel_filename) { + lsms->reset_info[0]->vector = load_kernel(); +- } else { +- error_report("Please specify at lease one of -bios and -kernel"); +- exit(1); + } + } + } +diff --git a/target/loongarch64/machine.c b/target/loongarch64/machine.c +index b69bca6a9..dea6a7034 100644 +--- a/target/loongarch64/machine.c ++++ b/target/loongarch64/machine.c +@@ -15,6 +15,10 @@ static int cpu_post_load(void *opaque, int version_id) + CPULOONGARCHState *env = &cpu->env; + int r = 0; + ++ if (!kvm_enabled()) { ++ return 0; ++ } ++ + #ifdef CONFIG_KVM + struct kvm_loongarch_vcpu_state vcpu_state; + int i; +@@ -48,6 +52,9 @@ static int cpu_pre_save(void *opaque) + LOONGARCHCPU *cpu = opaque; + struct kvm_loongarch_vcpu_state vcpu_state; + int i, r = 0; ++ if (!kvm_enabled()) { ++ return 0; ++ } + + r = kvm_vcpu_ioctl(CPU(cpu), KVM_LARCH_GET_VCPU_STATE, &vcpu_state); + if (r < 0) { +-- +2.27.0 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 2e4d7ab..8938155 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -914,6 +914,21 @@ Patch1006: 0006-Add-disas-gdb.patch Patch1007: 0007-Modify-kvm-cpu-vga-qapi.patch Patch1008: 0008-Modify-compile-script.patch Patch1009: 0009-Add-loongarch64-rh-devices.mak.patch +Patch1010: Modify-smbios-option-lack-and-Modify-the-maximum-num.patch +Patch1011: rename-kvm_msr_buf-with-kvm_csr_buf.patch +Patch1012: code-cleanup-for-loongarch-kvm.patch +Patch1013: Support-TPM.patch +Patch1014: kvm-csr-save-and-restore-optimization.patch +Patch1015: address-space-code-cleanup-on-7A-virt-machine.patch +Patch1016: Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch +Patch1017: Support-vfio-config.patch +Patch1018: pass-to-make-check.patch +Patch1019: fixup-can-t-find-cpu-type.patch +Patch1020: fix-smbios-type4-info-for-numa-support.patch +Patch1021: Fix-smp.cores-value.patch +Patch1022: Add-lbt-support-for-kvm.patch +Patch1023: Modify-the-ioctl-command-of-kvm.patch + BuildRequires: wget BuildRequires: rpm-build @@ -2156,6 +2171,20 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : - Adjust limit for virtiofsd minor version - Add loongarch supporti (lixianglai@loongson.cn) - Add package qemu-user-static (fuyuan.wh@alibaba-inc.com) +- Modify-smbios-option-lack-and-Modify-the-maximum-num.patch (lixianglai@loongson.cn) +- rename-kvm_msr_buf-with-kvm_csr_buf.patch (lixianglai@loongson.cn) +- code-cleanup-for-loongarch-kvm.patch (lixianglai@loongson.cn) +- Support-TPM.patch (lixianglai@loongson.cn) +- kvm-csr-save-and-restore-optimization.patch (lixianglai@loongson.cn) +- address-space-code-cleanup-on-7A-virt-machine.patch (lixianglai@loongson.cn) +- Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch (lixianglai@loongson.cn) +- Support-vfio-config.patch (lixianglai@loongson.cn) +- pass-to-make-check.patch (lixianglai@loongson.cn) +- fixup-can-t-find-cpu-type.patch (lixianglai@loongson.cn) +- fix-smbios-type4-info-for-numa-support.patch (lixianglai@loongson.cn) +- Fix-smp.cores-value.patch (lixianglai@loongson.cn) +- Add-lbt-support-for-kvm.patch (lixianglai@loongson.cn) +- Modify-the-ioctl-command-of-kvm.patch (lixianglai@loongson.cn) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] diff --git a/rename-kvm_msr_buf-with-kvm_csr_buf.patch b/rename-kvm_msr_buf-with-kvm_csr_buf.patch new file mode 100644 index 0000000..4ebe9fd --- /dev/null +++ b/rename-kvm_msr_buf-with-kvm_csr_buf.patch @@ -0,0 +1,638 @@ +From be136658b2055e4835f1d41c0729dba7b68cba16 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 29 May 2023 05:57:27 -0400 +Subject: [PATCH 02/14] rename kvm_msr_buf with kvm_csr_buf. + +Signed-off-by: lixianglai +--- + target/loongarch64/cpu.h | 2 +- + target/loongarch64/kvm.c | 564 +++++++++++++++++++-------------------- + 2 files changed, 283 insertions(+), 283 deletions(-) + +diff --git a/target/loongarch64/cpu.h b/target/loongarch64/cpu.h +index 10facb3b7..078556a22 100644 +--- a/target/loongarch64/cpu.h ++++ b/target/loongarch64/cpu.h +@@ -200,7 +200,7 @@ struct LOONGARCHCPU { + VMChangeStateEntry *cpuStateEntry; + int32_t node_id; /* NUMA node this CPU belongs to */ + int32_t core_id; +- struct kvm_msrs *kvm_msr_buf; ++ struct kvm_msrs *kvm_csr_buf; + /* 'compatible' string for this CPU for Linux device trees */ + const char *dtb_compatible; + }; +diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c +index 404a605eb..b5c655812 100644 +--- a/target/loongarch64/kvm.c ++++ b/target/loongarch64/kvm.c +@@ -31,7 +31,7 @@ + #define DEBUG_KVM 0 + /* A 16384-byte buffer can hold the 8-byte kvm_msrs header, plus + * 2047 kvm_msr_entry structs */ +-#define MSR_BUF_SIZE 16384 ++#define CSR_BUF_SIZE 16384 + + #define DPRINTF(fmt, ...) \ + do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0) +@@ -101,7 +101,7 @@ int kvm_arch_init_vcpu(CPUState *cs) + int ret = 0; + + cpu->cpuStateEntry = qemu_add_vm_change_state_handler(kvm_loongarch_update_state, cs); +- cpu->kvm_msr_buf = g_malloc0(MSR_BUF_SIZE); ++ cpu->kvm_csr_buf = g_malloc0(CSR_BUF_SIZE); + DPRINTF("%s\n", __func__); + return ret; + } +@@ -111,15 +111,15 @@ int kvm_arch_destroy_vcpu(CPUState *cs) + return 0; + } + +-static void kvm_msr_buf_reset(LOONGARCHCPU *cpu) ++static void kvm_csr_buf_reset(LOONGARCHCPU *cpu) + { +- memset(cpu->kvm_msr_buf, 0, MSR_BUF_SIZE); ++ memset(cpu->kvm_csr_buf, 0, CSR_BUF_SIZE); + } + +-static void kvm_msr_entry_add(LOONGARCHCPU *cpu, uint32_t index, uint64_t value) ++static void kvm_csr_entry_add(LOONGARCHCPU *cpu, uint32_t index, uint64_t value) + { +- struct kvm_msrs *msrs = cpu->kvm_msr_buf; +- void *limit = ((void *)msrs) + MSR_BUF_SIZE; ++ struct kvm_msrs *msrs = cpu->kvm_csr_buf; ++ void *limit = ((void *)msrs) + CSR_BUF_SIZE; + struct kvm_csr_entry *entry = &msrs->entries[msrs->ncsrs]; + + assert((void *)(entry + 1) <= limit); +@@ -767,144 +767,144 @@ static int kvm_loongarch_put_csr_registers(CPUState *cs, int level) + + (void)level; + +- kvm_msr_buf_reset(cpu); +- +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CRMD, env->CSR_CRMD); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRMD, env->CSR_PRMD); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_EUEN, env->CSR_EUEN); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_MISC, env->CSR_MISC); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ECFG, env->CSR_ECFG); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ESTAT, env->CSR_ESTAT); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERA, env->CSR_ERA); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADV, env->CSR_BADV); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADI, env->CSR_BADI); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_EEPN, env->CSR_EEPN); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, env->CSR_TLBIDX); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, env->CSR_TLBEHI); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, env->CSR_TLBELO0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, env->CSR_TLBELO1); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GTLBC, env->CSR_GTLBC); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TRGP, env->CSR_TRGP); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ASID, env->CSR_ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDL, env->CSR_PGDL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDH, env->CSR_PGDH); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGD, env->CSR_PGD); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, env->CSR_PWCTL0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, env->CSR_PWCTL1); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, env->CSR_STLBPGSIZE); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_RVACFG, env->CSR_RVACFG); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CPUID, env->CSR_CPUID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, env->CSR_PRCFG1); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, env->CSR_PRCFG2); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, env->CSR_PRCFG3); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS0, env->CSR_KS0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS1, env->CSR_KS1); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS2, env->CSR_KS2); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS3, env->CSR_KS3); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS4, env->CSR_KS4); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS5, env->CSR_KS5); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS6, env->CSR_KS6); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS7, env->CSR_KS7); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TMID, env->CSR_TMID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CNTC, env->CSR_CNTC); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, env->CSR_TINTCLR); +- +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GSTAT, env->CSR_GSTAT); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCFG, env->CSR_GCFG); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GINTC, env->CSR_GINTC); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCNTC, env->CSR_GCNTC); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, env->CSR_LLBCTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, env->CSR_IMPCTL1); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, env->CSR_IMPCTL2); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GNMI, env->CSR_GNMI); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, env->CSR_TLBRENT); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, env->CSR_TLBRBADV); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, env->CSR_TLBRERA); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, env->CSR_TLBRSAVE); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, env->CSR_TLBRELO0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, env->CSR_TLBRELO1); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, env->CSR_TLBREHI); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, env->CSR_TLBRPRMD); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, env->CSR_ERRCTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, env->CSR_ERRINFO); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, env->CSR_ERRINFO1); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRENT, env->CSR_ERRENT); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRERA, env->CSR_ERRERA); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, env->CSR_ERRSAVE); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CTAG, env->CSR_CTAG); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, env->CSR_DMWIN0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, env->CSR_DMWIN1); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, env->CSR_DMWIN2); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, env->CSR_DMWIN3); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, env->CSR_PERFCTRL0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, env->CSR_PERFCNTR0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, env->CSR_PERFCTRL1); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, env->CSR_PERFCNTR1); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, env->CSR_PERFCTRL2); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, env->CSR_PERFCNTR2); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, env->CSR_PERFCTRL3); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, env->CSR_PERFCNTR3); ++ kvm_csr_buf_reset(cpu); ++ ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CRMD, env->CSR_CRMD); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRMD, env->CSR_PRMD); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_EUEN, env->CSR_EUEN); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MISC, env->CSR_MISC); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ECFG, env->CSR_ECFG); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ESTAT, env->CSR_ESTAT); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERA, env->CSR_ERA); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_BADV, env->CSR_BADV); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_BADI, env->CSR_BADI); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_EEPN, env->CSR_EEPN); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, env->CSR_TLBIDX); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, env->CSR_TLBEHI); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, env->CSR_TLBELO0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, env->CSR_TLBELO1); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GTLBC, env->CSR_GTLBC); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TRGP, env->CSR_TRGP); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ASID, env->CSR_ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGDL, env->CSR_PGDL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGDH, env->CSR_PGDH); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGD, env->CSR_PGD); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, env->CSR_PWCTL0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, env->CSR_PWCTL1); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, env->CSR_STLBPGSIZE); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_RVACFG, env->CSR_RVACFG); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CPUID, env->CSR_CPUID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, env->CSR_PRCFG1); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, env->CSR_PRCFG2); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, env->CSR_PRCFG3); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS0, env->CSR_KS0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS1, env->CSR_KS1); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS2, env->CSR_KS2); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS3, env->CSR_KS3); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS4, env->CSR_KS4); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS5, env->CSR_KS5); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS6, env->CSR_KS6); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS7, env->CSR_KS7); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TMID, env->CSR_TMID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CNTC, env->CSR_CNTC); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, env->CSR_TINTCLR); ++ ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GSTAT, env->CSR_GSTAT); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GCFG, env->CSR_GCFG); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GINTC, env->CSR_GINTC); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GCNTC, env->CSR_GCNTC); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, env->CSR_LLBCTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, env->CSR_IMPCTL1); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, env->CSR_IMPCTL2); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GNMI, env->CSR_GNMI); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, env->CSR_TLBRENT); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, env->CSR_TLBRBADV); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, env->CSR_TLBRERA); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, env->CSR_TLBRSAVE); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, env->CSR_TLBRELO0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, env->CSR_TLBRELO1); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, env->CSR_TLBREHI); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, env->CSR_TLBRPRMD); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, env->CSR_ERRCTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, env->CSR_ERRINFO); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, env->CSR_ERRINFO1); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRENT, env->CSR_ERRENT); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRERA, env->CSR_ERRERA); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, env->CSR_ERRSAVE); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CTAG, env->CSR_CTAG); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, env->CSR_DMWIN0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, env->CSR_DMWIN1); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, env->CSR_DMWIN2); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, env->CSR_DMWIN3); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, env->CSR_PERFCTRL0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, env->CSR_PERFCNTR0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, env->CSR_PERFCTRL1); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, env->CSR_PERFCNTR1); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, env->CSR_PERFCTRL2); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, env->CSR_PERFCNTR2); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, env->CSR_PERFCTRL3); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, env->CSR_PERFCNTR3); + + /* debug */ +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPC, env->CSR_MWPC); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPS, env->CSR_MWPS); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, env->CSR_DB0ADDR); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, env->CSR_DB0MASK); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, env->CSR_DB0CTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, env->CSR_DB0ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, env->CSR_DB1ADDR); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, env->CSR_DB1MASK); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, env->CSR_DB1CTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, env->CSR_DB1ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, env->CSR_DB2ADDR); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, env->CSR_DB2MASK); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, env->CSR_DB2CTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, env->CSR_DB2ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, env->CSR_DB3ADDR); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, env->CSR_DB3MASK); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, env->CSR_DB3CTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, env->CSR_DB3ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPC, env->CSR_FWPC); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPS, env->CSR_FWPS); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, env->CSR_IB0ADDR); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, env->CSR_IB0MASK); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, env->CSR_IB0CTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, env->CSR_IB0ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, env->CSR_IB1ADDR); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, env->CSR_IB1MASK); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, env->CSR_IB1CTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, env->CSR_IB1ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, env->CSR_IB2ADDR); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, env->CSR_IB2MASK); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, env->CSR_IB2CTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, env->CSR_IB2ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, env->CSR_IB3ADDR); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, env->CSR_IB3MASK); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, env->CSR_IB3CTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, env->CSR_IB3ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, env->CSR_IB4ADDR); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, env->CSR_IB4MASK); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, env->CSR_IB4CTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, env->CSR_IB4ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, env->CSR_IB5ADDR); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, env->CSR_IB5MASK); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, env->CSR_IB5CTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, env->CSR_IB5ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, env->CSR_IB6ADDR); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, env->CSR_IB6MASK); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, env->CSR_IB6CTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, env->CSR_IB6ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, env->CSR_IB7ADDR); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, env->CSR_IB7MASK); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, env->CSR_IB7CTL); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, env->CSR_IB7ASID); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DEBUG, env->CSR_DEBUG); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DERA, env->CSR_DERA); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DESAVE, env->CSR_DESAVE); +- +- ret = kvm_vcpu_ioctl(cs, KVM_SET_MSRS, cpu->kvm_msr_buf); +- if (ret < cpu->kvm_msr_buf->ncsrs) { +- struct kvm_csr_entry *e = &cpu->kvm_msr_buf->entries[ret]; ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MWPC, env->CSR_MWPC); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MWPS, env->CSR_MWPS); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, env->CSR_DB0ADDR); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, env->CSR_DB0MASK); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, env->CSR_DB0CTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, env->CSR_DB0ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, env->CSR_DB1ADDR); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, env->CSR_DB1MASK); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, env->CSR_DB1CTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, env->CSR_DB1ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, env->CSR_DB2ADDR); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, env->CSR_DB2MASK); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, env->CSR_DB2CTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, env->CSR_DB2ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, env->CSR_DB3ADDR); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, env->CSR_DB3MASK); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, env->CSR_DB3CTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, env->CSR_DB3ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_FWPC, env->CSR_FWPC); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_FWPS, env->CSR_FWPS); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, env->CSR_IB0ADDR); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, env->CSR_IB0MASK); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, env->CSR_IB0CTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, env->CSR_IB0ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, env->CSR_IB1ADDR); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, env->CSR_IB1MASK); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, env->CSR_IB1CTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, env->CSR_IB1ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, env->CSR_IB2ADDR); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, env->CSR_IB2MASK); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, env->CSR_IB2CTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, env->CSR_IB2ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, env->CSR_IB3ADDR); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, env->CSR_IB3MASK); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, env->CSR_IB3CTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, env->CSR_IB3ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, env->CSR_IB4ADDR); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, env->CSR_IB4MASK); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, env->CSR_IB4CTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, env->CSR_IB4ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, env->CSR_IB5ADDR); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, env->CSR_IB5MASK); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, env->CSR_IB5CTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, env->CSR_IB5ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, env->CSR_IB6ADDR); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, env->CSR_IB6MASK); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, env->CSR_IB6CTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, env->CSR_IB6ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, env->CSR_IB7ADDR); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, env->CSR_IB7MASK); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, env->CSR_IB7CTL); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, env->CSR_IB7ASID); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DEBUG, env->CSR_DEBUG); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DERA, env->CSR_DERA); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DESAVE, env->CSR_DESAVE); ++ ++ ret = kvm_vcpu_ioctl(cs, KVM_SET_MSRS, cpu->kvm_csr_buf); ++ if (ret < cpu->kvm_csr_buf->ncsrs) { ++ struct kvm_csr_entry *e = &cpu->kvm_csr_buf->entries[ret]; + printf("error: failed to set CSR 0x%" PRIx32 " to 0x%" PRIx64"\n", + (uint32_t)e->index, (uint64_t)e->data); + } +@@ -935,147 +935,147 @@ static int kvm_loongarch_get_csr_registers(CPUState *cs) + LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); + CPULOONGARCHState *env = &cpu->env; + int ret = 0, i; +- struct kvm_csr_entry *csrs = cpu->kvm_msr_buf->entries; +- +- kvm_msr_buf_reset(cpu); +- +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CRMD, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRMD, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_EUEN, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_MISC, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ECFG, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ESTAT, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERA, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADV, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADI, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_EEPN, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GTLBC, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TRGP, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDH, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGD, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_RVACFG, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CPUID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS0, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS1, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS2, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS3, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS4, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS5, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS6, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS7, 0); +- +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TMID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CNTC, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GSTAT, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCFG, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GINTC, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCNTC, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GNMI, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRENT, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRERA, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CTAG, 0); +- +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, 0); ++ struct kvm_csr_entry *csrs = cpu->kvm_csr_buf->entries; ++ ++ kvm_csr_buf_reset(cpu); ++ ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CRMD, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRMD, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_EUEN, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MISC, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ECFG, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ESTAT, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERA, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_BADV, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_BADI, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_EEPN, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GTLBC, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TRGP, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGDL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGDH, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGD, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_RVACFG, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CPUID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS0, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS1, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS2, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS3, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS4, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS5, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS6, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS7, 0); ++ ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TMID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CNTC, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GSTAT, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GCFG, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GINTC, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GCNTC, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GNMI, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRENT, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRERA, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CTAG, 0); ++ ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, 0); + + /* debug */ +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPC, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPS, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPC, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPS, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DEBUG, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DERA, 0); +- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DESAVE, 0); +- +- ret = kvm_vcpu_ioctl(cs, KVM_GET_MSRS, cpu->kvm_msr_buf); +- if (ret < cpu->kvm_msr_buf->ncsrs) { +- struct kvm_csr_entry *e = &cpu->kvm_msr_buf->entries[ret]; ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MWPC, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MWPS, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_FWPC, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_FWPS, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DEBUG, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DERA, 0); ++ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DESAVE, 0); ++ ++ ret = kvm_vcpu_ioctl(cs, KVM_GET_MSRS, cpu->kvm_csr_buf); ++ if (ret < cpu->kvm_csr_buf->ncsrs) { ++ struct kvm_csr_entry *e = &cpu->kvm_csr_buf->entries[ret]; + printf("error: failed to get CSR 0x%" PRIx32"\n", + (uint32_t)e->index); + } +-- +2.27.0 + -- Gitee From 1a6092fbcf62e9305fd478296eb9183548901b2b Mon Sep 17 00:00:00 2001 From: zhaotianrui Date: Mon, 19 Jun 2023 10:51:06 -0400 Subject: [PATCH 06/17] Bug fix for loongarch Add usb storage config for loongarch. Add loongarch into QEMU_ARCH_VIRTIO_PCI to support qdev alias. Fix host architecture macro of LoongArch to HOST_LOONGARCH64. Fix LoongArch KVM header macros. Signed-off-by: zhaotianrui --- ...to-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch | 28 ++++++++++++++++ Add-usb-storage-config-for-loongarch.patch | 26 +++++++++++++++ Fix-LoongArch-KVM-header-macros.patch | 32 +++++++++++++++++++ ...cture-macro-of-LoongArch-to-HOST_LOO.patch | 26 +++++++++++++++ qemu-kvm.spec | 9 +++++- 5 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch create mode 100644 Add-usb-storage-config-for-loongarch.patch create mode 100644 Fix-LoongArch-KVM-header-macros.patch create mode 100644 Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch diff --git a/Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch b/Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch new file mode 100644 index 0000000..7991934 --- /dev/null +++ b/Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch @@ -0,0 +1,28 @@ +From 1ebc0cc2ede04d6e70291ff1344ee80c38e5ebd2 Mon Sep 17 00:00:00 2001 +From: Tianrui Zhao +Date: Mon, 19 Jun 2023 09:38:16 +0800 +Subject: [PATCH] Add loongarch into QEMU_ARCH_VIRTIO_PCI to support qdev + alias + +Signed-off-by: Tianrui Zhao +--- + softmmu/qdev-monitor.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c +index 01f3834db..49491d74a 100644 +--- a/softmmu/qdev-monitor.c ++++ b/softmmu/qdev-monitor.c +@@ -60,7 +60,8 @@ typedef struct QDevAlias + QEMU_ARCH_HPPA | QEMU_ARCH_I386 | \ + QEMU_ARCH_MIPS | QEMU_ARCH_PPC | \ + QEMU_ARCH_RISCV | QEMU_ARCH_SH4 | \ +- QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA) ++ QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA | \ ++ QEMU_ARCH_LOONGARCH64) + #define QEMU_ARCH_VIRTIO_CCW (QEMU_ARCH_S390X) + #define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K) + +-- +2.39.3 + diff --git a/Add-usb-storage-config-for-loongarch.patch b/Add-usb-storage-config-for-loongarch.patch new file mode 100644 index 0000000..86857da --- /dev/null +++ b/Add-usb-storage-config-for-loongarch.patch @@ -0,0 +1,26 @@ +From be087165d6ff6c45e768b85a23834d5e68fa0197 Mon Sep 17 00:00:00 2001 +From: Tianrui Zhao +Date: Mon, 19 Jun 2023 09:34:02 +0800 +Subject: [PATCH] Add usb-storage config for loongarch + +Signed-off-by: Tianrui Zhao +--- + configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak +index 696ee9b72..15fc2d00f 100644 +--- a/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak ++++ b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak +@@ -147,6 +147,8 @@ CONFIG_USB_EHCI=y + CONFIG_USB_EHCI_PCI=y + CONFIG_USB_EHCI_SYSBUS=y + CONFIG_USB_STORAGE_BOT=y ++CONFIG_USB_STORAGE_CORE=y ++CONFIG_USB_STORAGE_CLASSIC=y + CONFIG_TPM_EMULATOR=y + CONFIG_TPM_TIS=y + CONFIG_PLATFORM_BUS=y +-- +2.39.3 + diff --git a/Fix-LoongArch-KVM-header-macros.patch b/Fix-LoongArch-KVM-header-macros.patch new file mode 100644 index 0000000..a6c8233 --- /dev/null +++ b/Fix-LoongArch-KVM-header-macros.patch @@ -0,0 +1,32 @@ +From 6291b67e4a12d65595de2884e5939a19a3c7b052 Mon Sep 17 00:00:00 2001 +From: Tianrui Zhao +Date: Tue, 20 Jun 2023 16:34:43 +0800 +Subject: [PATCH] Fix LoongArch KVM header macros + +Signed-off-by: Tianrui Zhao +--- + linux-headers/linux/kvm.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 1e6aed0fb..f99455294 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -2057,10 +2057,10 @@ struct kvm_loongarch_vcpu_state { + __u64 core_ext_ioisr[4]; + }; + +-#define KVM_CAP_LOONGARCH_FPU 800 +-#define KVM_CAP_LOONGARCH_LSX 801 +-#define KVM_CAP_LOONGARCH_VZ 802 +-#define KVM_REG_LOONGARCH 0x9000000000000000ULL ++#define KVM_CAP_LOONGARCH_FPU 165 ++#define KVM_CAP_LOONGARCH_LSX 166 ++#define KVM_CAP_LOONGARCH_VZ 167 ++#define KVM_REG_LOONGARCH 0x8000000000000000ULL + #define KVM_LARCH_GET_VCPU_STATE _IOR(KVMIO, 0xc0, struct kvm_loongarch_vcpu_state) + #define KVM_LARCH_SET_VCPU_STATE _IOW(KVMIO, 0xc1, struct kvm_loongarch_vcpu_state) + #define KVM_LARCH_GET_CPUCFG _IOR(KVMIO, 0xc2, struct kvm_cpucfg) +-- +2.39.3 + diff --git a/Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch b/Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch new file mode 100644 index 0000000..ea7daee --- /dev/null +++ b/Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch @@ -0,0 +1,26 @@ +From 442aa58bc9508065c85a3d2b9790943559c2c812 Mon Sep 17 00:00:00 2001 +From: Tianrui Zhao +Date: Mon, 19 Jun 2023 16:38:29 +0800 +Subject: [PATCH] Fix host architecture macro of LoongArch to HOST_LOONGARCH64 + +Signed-off-by: Tianrui Zhao +--- + accel/kvm/kvm-all.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index e7d1e9ace..fbd6f5fcc 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -2423,7 +2423,7 @@ static int kvm_init(MachineState *ms) + soft_vcpus_limit = kvm_recommended_vcpus(s); + hard_vcpus_limit = kvm_max_vcpus(s); + +-#if defined(HOST_PPC64) || defined(HOST_LOONGARCH) ++#if defined(HOST_PPC64) || defined(HOST_LOONGARCH64) + /* + * On POWER, the kernel advertises a soft limit based on the + * number of CPU threads on the host. We want to allow exceeding +-- +2.39.3 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 8938155..5c85f7f 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -928,7 +928,10 @@ Patch1020: fix-smbios-type4-info-for-numa-support.patch Patch1021: Fix-smp.cores-value.patch Patch1022: Add-lbt-support-for-kvm.patch Patch1023: Modify-the-ioctl-command-of-kvm.patch - +Patch1024: Add-usb-storage-config-for-loongarch.patch +Patch1025: Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch +Patch1026: Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch +Patch1027: Fix-LoongArch-KVM-header-macros.patch BuildRequires: wget BuildRequires: rpm-build @@ -2185,6 +2188,10 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : - Fix-smp.cores-value.patch (lixianglai@loongson.cn) - Add-lbt-support-for-kvm.patch (lixianglai@loongson.cn) - Modify-the-ioctl-command-of-kvm.patch (lixianglai@loongson.cn) +- Add-usb-storage-config-for-loongarch.patch (zhaotianrui@loongson.c) +- Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch (zhaotianrui@loongson.c) +- Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch (zhaotianrui@loongson.c) +- Fix-LoongArch-KVM-header-macros.patch (zhaotianrui@loongson.c) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] -- Gitee From 918c0ee366300fbf77ac1bec5969e4ffda979439 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Thu, 24 Aug 2023 08:09:04 -0400 Subject: [PATCH 07/17] Fixed the issue where qemu specifies the boot order Fixed the issue that the device path of bootorder in the generated fw_cfg was abnormal because the PCIeHost device did not initialize the memory space of sysbus, which caused the QEMU boot order to not take effect. Signed-off-by: lixianglai --- ...-where-qemu-specifies-the-boot-order.patch | 140 ++++++++++++++++++ qemu-kvm.spec | 2 + 2 files changed, 142 insertions(+) create mode 100644 Fixed-the-issue-where-qemu-specifies-the-boot-order.patch diff --git a/Fixed-the-issue-where-qemu-specifies-the-boot-order.patch b/Fixed-the-issue-where-qemu-specifies-the-boot-order.patch new file mode 100644 index 0000000..781123a --- /dev/null +++ b/Fixed-the-issue-where-qemu-specifies-the-boot-order.patch @@ -0,0 +1,140 @@ +From 4e2e6a0576cdf365bf7df1693e7d6debd0179de5 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Wed, 23 Aug 2023 07:10:25 -0400 +Subject: [PATCH] Fixed the issue where qemu specifies the boot order + +Fixed the issue that the device path of bootorder +in the generated fw_cfg was abnormal because the +PCIeHost device did not initialize the memory space +of sysbus, which caused the QEMU boot order to not +take effect. + +Change-Id: Ifde4c8b8432c5c8748c1b38a3c33bafef4f24083 +Signed-off-by: lixianglai +--- + hw/loongarch/larch_3a.c | 14 -------------- + hw/loongarch/ls7a_nb.c | 28 ++++++++++++++++++++++++++-- + include/hw/loongarch/larch.h | 6 ++++++ + include/hw/loongarch/ls7a.h | 2 ++ + 4 files changed, 34 insertions(+), 16 deletions(-) + +diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c +index 2affc5048..1a4e982b7 100644 +--- a/hw/loongarch/larch_3a.c ++++ b/hw/loongarch/larch_3a.c +@@ -86,12 +86,6 @@ + + #define TARGET_REALPAGE_MASK (TARGET_PAGE_MASK << 2) + +-#ifdef CONFIG_KVM +-#define LS_ISA_IO_SIZE 0x02000000 +-#else +-#define LS_ISA_IO_SIZE 0x00010000 +-#endif +- + #ifdef CONFIG_KVM + #define align(x) (((x) + 63) & ~63) + #else +@@ -1618,8 +1612,6 @@ static void ls3a5k_init(MachineState *args) + ram_addr_t ram_size = args->ram_size; + MemoryRegion *address_space_mem = get_system_memory(); + ram_addr_t offset = 0; +- MemoryRegion *isa_io = g_new(MemoryRegion, 1); +- MemoryRegion *isa_mem = g_new(MemoryRegion, 1); + MachineState *machine = args; + MachineClass *mc = MACHINE_GET_CLASS(machine); + LoongarchMachineState *lsms = LoongarchMACHINE(machine); +@@ -1799,12 +1791,6 @@ static void ls3a5k_init(MachineState *args) + &machine->device_memory->mr); + } + +- memory_region_init_alias(isa_io, NULL, "isa-io", +- get_system_io(), 0, LS_ISA_IO_SIZE); +- memory_region_init(isa_mem, NULL, "isa-mem", PCIE_MEMORY_SIZE); +- memory_region_add_subregion(get_system_memory(), lsmc->isa_io_base, isa_io); +- memory_region_add_subregion(get_system_memory(), PCIE_MEMORY_BASE, isa_mem); +- + if (!strcmp(lsmc->bridge_name, "ls7a")) { + /*Initialize the 7A IO interrupt subsystem*/ + DeviceState *ls7a_dev; +diff --git a/hw/loongarch/ls7a_nb.c b/hw/loongarch/ls7a_nb.c +index 5a231e6f0..f11b855a7 100644 +--- a/hw/loongarch/ls7a_nb.c ++++ b/hw/loongarch/ls7a_nb.c +@@ -162,17 +162,41 @@ static PCIBus *pci_ls7a_init(MachineState *machine, DeviceState *dev, + { + LoongarchMachineState *lsms = LoongarchMACHINE(machine); + LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ LS7APCIEHost *pciehost = LS7A_PCIE_HOST_BRIDGE(dev); + PCIExpressHost *e; ++ SysBusDevice *sysbus; + PCIHostState *phb; ++ MemoryRegion *mmio_alias; + + e = PCIE_HOST_BRIDGE(dev); ++ sysbus = SYS_BUS_DEVICE(e); + phb = PCI_HOST_BRIDGE(e); ++ ++ sysbus_init_mmio(sysbus, &e->mmio); ++ ++ memory_region_init(&pciehost->io_mmio, OBJECT(pciehost), ++ "pciehost-mmio", UINT64_MAX); ++ sysbus_init_mmio(sysbus, &pciehost->io_mmio); ++ mmio_alias = g_new0(MemoryRegion, 1); ++ memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio", ++ &pciehost->io_mmio, PCIE_MEMORY_BASE, ++ PCIE_MEMORY_SIZE); ++ memory_region_add_subregion(get_system_memory(), ++ PCIE_MEMORY_BASE, mmio_alias); ++ ++ memory_region_init(&pciehost->io_ioport, OBJECT(pciehost), ++ "pciehost-ioport", LS_ISA_IO_SIZE); ++ sysbus_init_mmio(sysbus, &pciehost->io_ioport); ++ ++ sysbus_mmio_map(sysbus, 2, LS3A5K_ISA_IO_BASE); ++ ++ + phb->bus = pci_register_root_bus(dev, "pcie.0", pci_ls7a_set_irq, + pci_ls7a_map_irq, pic, +- get_system_memory(), get_system_io(), ++ &pciehost->io_mmio, &pciehost->io_ioport, + (1 << 3), 128, TYPE_PCIE_BUS); ++ /*update pcie config memory*/ + pcie_host_mmcfg_update(e, true, lsmc->pciecfg_base, LS_PCIECFG_SIZE); +- DPRINTF("------ %d\n", __LINE__); + + pci_bus_set_route_irq_fn(phb->bus, ls7a_route_intx_pin_to_irq); + +diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h +index b8f28e330..3f4fdd946 100644 +--- a/include/hw/loongarch/larch.h ++++ b/include/hw/loongarch/larch.h +@@ -40,6 +40,12 @@ + #define LOONGARCH_HOTPLUG_MEM_ALIGN (1ULL << 28) + #define LOONGARCH_MAX_RAM_SLOTS 10 + ++#ifdef CONFIG_KVM ++#define LS_ISA_IO_SIZE 0x02000000 ++#else ++#define LS_ISA_IO_SIZE 0x00010000 ++#endif ++ + /* Memory types: */ + #define SYSTEM_RAM 1 + #define SYSTEM_RAM_RESERVED 2 +diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h +index 63a070296..05edee603 100644 +--- a/include/hw/loongarch/ls7a.h ++++ b/include/hw/loongarch/ls7a.h +@@ -121,6 +121,8 @@ + typedef struct LS7APCIState LS7APCIState; + typedef struct LS7APCIEHost { + PCIExpressHost parent_obj; ++ MemoryRegion io_ioport; ++ MemoryRegion io_mmio; + LS7APCIState *pci_dev; + } LS7APCIEHost; + +-- +2.27.0 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 5c85f7f..3fb214c 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -932,6 +932,7 @@ Patch1024: Add-usb-storage-config-for-loongarch.patch Patch1025: Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch Patch1026: Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch Patch1027: Fix-LoongArch-KVM-header-macros.patch +Patch1028: Fixed-the-issue-where-qemu-specifies-the-boot-order.patch BuildRequires: wget BuildRequires: rpm-build @@ -2192,6 +2193,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : - Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch (zhaotianrui@loongson.c) - Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch (zhaotianrui@loongson.c) - Fix-LoongArch-KVM-header-macros.patch (zhaotianrui@loongson.c) +- loongarch: Fixed the issue where qemu specifies the boot order (lixianglai@loongson.cn) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] -- Gitee From 67911f15d9003b04b52f355dd76af125e72c5db0 Mon Sep 17 00:00:00 2001 From: Liwei Ge Date: Thu, 10 Nov 2022 13:15:12 +0800 Subject: [PATCH 08/17] spec: rename rules file --- 81-kvm-rhel.rules => 81-kvm-anolis.rules | 0 qemu-kvm.spec | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename 81-kvm-rhel.rules => 81-kvm-anolis.rules (100%) diff --git a/81-kvm-rhel.rules b/81-kvm-anolis.rules similarity index 100% rename from 81-kvm-rhel.rules rename to 81-kvm-anolis.rules diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 3fb214c..b8600f1 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -124,7 +124,7 @@ Source30: kvm-s390x.conf Source31: kvm-x86.conf Source32: qemu-pr-helper.service Source33: qemu-pr-helper.socket -Source34: 81-kvm-rhel.rules +Source34: 81-kvm-anolis.rules Source35: udev-kvm-check.c Source36: README.tests Source37: tests_data_acpi_pc_SSDT.dimmpxm @@ -2005,7 +2005,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %{_unitdir}/ksmtuned.service %{_sbindir}/ksmtuned %{_udevdir}/udev-kvm-check -%{_udevrulesdir}/81-kvm-rhel.rules +%{_udevrulesdir}/81-kvm-anolis.rules %ghost %{_sysconfdir}/kvm %config(noreplace) %{_sysconfdir}/ksmtuned.conf %dir %{_sysconfdir}/%{name} -- Gitee From abbac79f52c3829c9d94b67ee8235c3773ac49d9 Mon Sep 17 00:00:00 2001 From: Xin Jiang Date: Thu, 14 Sep 2023 13:59:45 +0800 Subject: [PATCH 09/17] Support Hygon CSV3 feature CSV3 feature integrates secure processor, memory encryption and memory isolation to provide the ability to protect guest's private data. The CSV guest's context like CPU registers, control block and nested page table is accessed only by the guest itself and the secure processor. Neither other guests nor the host can tamper with the guest's context. Signed-off-by: Xin Jiang --- 0001-anolis-csv-i386-add-CSV-context.patch | 205 ++++++++++++++++++ ...add-command-to-initialize-CSV-contex.patch | 204 +++++++++++++++++ ...add-command-to-load-data-to-guest-me.patch | 164 ++++++++++++++ ...add-command-to-load-vmcb-to-guest-me.patch | 107 +++++++++ ...populate-CPUID-0x8000_001F-when-CSV-.patch | 41 ++++ ...CSV-guest-do-not-need-register-unreg.patch | 35 +++ ...86-csv-load-initial-image-to-private.patch | 44 ++++ ...-vga-force-full-update-for-CSV-guest.patch | 47 ++++ qemu-kvm.spec | 19 ++ 9 files changed, 866 insertions(+) create mode 100644 0001-anolis-csv-i386-add-CSV-context.patch create mode 100644 0002-anolis-csv-i386-add-command-to-initialize-CSV-contex.patch create mode 100644 0003-anolis-csv-i386-add-command-to-load-data-to-guest-me.patch create mode 100644 0004-anolis-csv-i386-add-command-to-load-vmcb-to-guest-me.patch create mode 100644 0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch create mode 100644 0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch create mode 100644 0007-anolis-target-i386-csv-load-initial-image-to-private.patch create mode 100644 0008-anolis-vga-force-full-update-for-CSV-guest.patch diff --git a/0001-anolis-csv-i386-add-CSV-context.patch b/0001-anolis-csv-i386-add-CSV-context.patch new file mode 100644 index 0000000..89e3d49 --- /dev/null +++ b/0001-anolis-csv-i386-add-CSV-context.patch @@ -0,0 +1,205 @@ +From fda324e163898d543e215cfec1aa3d26ba816426 Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Tue, 24 Aug 2021 14:57:28 +0800 +Subject: [PATCH 1/8] anolis: csv/i386: add CSV context + +CSV is the secure virtualization feature on Hygon CPU. +It is compatible with the AMD SEV/SEV-ES and extends out +specific funtionality by setting bit 6 of guest policy. + +Add the context and the build option. + +Change-Id: I02b48c779dd25ddda4546fe3e28c1fe0c8c2e4c6 +Signed-off-by: Xin Jiang +--- + configs/devices/i386-softmmu/default.mak | 1 + + .../x86_64-softmmu/x86_64-rh-devices.mak | 1 + + hw/i386/Kconfig | 5 ++ + target/i386/csv-sysemu-stub.c | 16 ++++++ + target/i386/csv.c | 51 +++++++++++++++++++ + target/i386/csv.h | 35 +++++++++++++ + target/i386/meson.build | 1 + + 7 files changed, 110 insertions(+) + create mode 100644 target/i386/csv-sysemu-stub.c + create mode 100644 target/i386/csv.c + create mode 100644 target/i386/csv.h + +diff --git a/configs/devices/i386-softmmu/default.mak b/configs/devices/i386-softmmu/default.mak +index 598c6646df..db83ffcab9 100644 +--- a/configs/devices/i386-softmmu/default.mak ++++ b/configs/devices/i386-softmmu/default.mak +@@ -23,6 +23,7 @@ + #CONFIG_TPM_TIS_ISA=n + #CONFIG_VTD=n + #CONFIG_SGX=n ++#CONFIG_CSV=n + + # Boards: + # +diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak +index 31ce08edab..ee1df7aa52 100644 +--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak ++++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak +@@ -102,3 +102,4 @@ CONFIG_TPM_TIS_ISA=y + CONFIG_TPM_EMULATOR=y + CONFIG_TPM_PASSTHROUGH=y + CONFIG_SGX=y ++CONFIG_CSV=y +diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig +index d22ac4a4b9..ed35d762b3 100644 +--- a/hw/i386/Kconfig ++++ b/hw/i386/Kconfig +@@ -10,6 +10,10 @@ config SGX + bool + depends on KVM + ++config CSV ++ bool ++ depends on SEV ++ + config PC + bool + imply APPLESMC +@@ -26,6 +30,7 @@ config PC + imply QXL + imply SEV + imply SGX ++ imply CSV + imply SGA + imply TEST_DEVICES + imply TPM_CRB +diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c +new file mode 100644 +index 0000000000..a89b2600e7 +--- /dev/null ++++ b/target/i386/csv-sysemu-stub.c +@@ -0,0 +1,16 @@ ++/* ++ * QEMU CSV support ++ * ++ * Copyright: Hygon Info Technologies Ltd. 2022 ++ * ++ * Author: ++ * Jiang Xin ++ * ++ * 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 "sev.h" ++#include "csv.h" +diff --git a/target/i386/csv.c b/target/i386/csv.c +new file mode 100644 +index 0000000000..aac825d3f9 +--- /dev/null ++++ b/target/i386/csv.c +@@ -0,0 +1,51 @@ ++/* ++ * QEMU CSV support ++ * ++ * Copyright: Hygon Info Technologies Ltd. 2022 ++ * ++ * Author: ++ * Jiang Xin ++ * ++ * 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 "sev.h" ++#include "csv.h" ++ ++CsvGuestState csv_guest = { 0 }; ++ ++#define CPUID_VENDOR_HYGON_EBX 0x6f677948 /* "Hygo" */ ++#define CPUID_VENDOR_HYGON_ECX 0x656e6975 /* "uine" */ ++#define CPUID_VENDOR_HYGON_EDX 0x6e65476e /* "nGen" */ ++ ++#define GUEST_POLICY_CSV_BIT (1 << 6) ++ ++static bool is_hygon_cpu(void) ++{ ++ uint32_t ebx = 0; ++ uint32_t ecx = 0; ++ uint32_t edx = 0; ++ ++ host_cpuid(0, 0, NULL, &ebx, &ecx, &edx); ++ ++ if (ebx == CPUID_VENDOR_HYGON_EBX && ++ ecx == CPUID_VENDOR_HYGON_ECX && ++ edx == CPUID_VENDOR_HYGON_EDX) ++ return true; ++ else ++ return false; ++} ++ ++bool ++csv_enabled(void) ++{ ++ if (!is_hygon_cpu()) ++ return false; ++ ++ return sev_es_enabled() && (csv_guest.policy & GUEST_POLICY_CSV_BIT); ++} +diff --git a/target/i386/csv.h b/target/i386/csv.h +new file mode 100644 +index 0000000000..057d37d975 +--- /dev/null ++++ b/target/i386/csv.h +@@ -0,0 +1,35 @@ ++/* ++ * QEMU CSV support ++ * ++ * Copyright: Hygon Info Technologies Ltd. 2022 ++ * ++ * Author: ++ * Jiang Xin ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or later. ++ * See the COPYING file in the top-level directory. ++ * ++ */ ++ ++#ifndef QEMU_CSV_H ++#define QEMU_CSV_H ++ ++#include "qapi/qapi-commands-misc-target.h" ++ ++#ifdef CONFIG_CSV ++bool csv_enabled(void); ++#else ++#define csv_enabled() 0 ++#endif ++ ++struct CsvGuestState { ++ uint32_t policy; ++ int sev_fd; ++ void *state; ++}; ++ ++typedef struct CsvGuestState CsvGuestState; ++ ++extern struct CsvGuestState csv_guest; ++ ++#endif +diff --git a/target/i386/meson.build b/target/i386/meson.build +index ae38dc9563..361dea9290 100644 +--- a/target/i386/meson.build ++++ b/target/i386/meson.build +@@ -21,6 +21,7 @@ i386_softmmu_ss.add(files( + 'cpu-sysemu.c', + )) + i386_softmmu_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('sev-sysemu-stub.c')) ++i386_softmmu_ss.add(when: 'CONFIG_CSV', if_true: files('csv.c'), if_false: files('csv-sysemu-stub.c')) + + i386_user_ss = ss.source_set() + +-- +2.17.1 + diff --git a/0002-anolis-csv-i386-add-command-to-initialize-CSV-contex.patch b/0002-anolis-csv-i386-add-command-to-initialize-CSV-contex.patch new file mode 100644 index 0000000..a62796a --- /dev/null +++ b/0002-anolis-csv-i386-add-command-to-initialize-CSV-contex.patch @@ -0,0 +1,204 @@ +From 3239acc6c33806fac55fc08d7e5a81ef9ce85e23 Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Wed, 25 Aug 2021 11:07:41 +0800 +Subject: [PATCH 2/8] anolis: csv/i386: add command to initialize CSV context + +When CSV is enabled, KVM_CSV_INIT command is used to initialize +the platform, which is implemented by reusing the SEV API +framework and extending the functionality. + +The KVM_CSV_INIT command should be performed earlier than +any other command. + +Signed-off-by: Xin Jiang +Change-Id: Ia4201dc90c250c23658e1cf5e19b528df9075330 +--- + linux-headers/linux/kvm.h | 11 +++++++++ + target/i386/csv-sysemu-stub.c | 5 ++++ + target/i386/csv.c | 44 +++++++++++++++++++++++++++++++++++ + target/i386/csv.h | 3 +++ + target/i386/sev.c | 17 ++++++++++++++ + target/i386/sev.h | 5 ++++ + 6 files changed, 85 insertions(+) + +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index bcaf66cc4d..b15b8f5550 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -1808,6 +1808,17 @@ struct kvm_sev_receive_update_data { + __u32 trans_len; + }; + ++/* CSV command */ ++enum csv_cmd_id { ++ KVM_CSV_NR_MIN = 0xc0, ++ ++ KVM_CSV_INIT = KVM_CSV_NR_MIN, ++}; ++ ++struct kvm_csv_init_data { ++ __u64 nodemask; ++}; ++ + #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) + #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) + #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) +diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c +index a89b2600e7..dbd710dc6f 100644 +--- a/target/i386/csv-sysemu-stub.c ++++ b/target/i386/csv-sysemu-stub.c +@@ -14,3 +14,8 @@ + #include "qemu/osdep.h" + #include "sev.h" + #include "csv.h" ++ ++int csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) ++{ ++ return 0; ++} +diff --git a/target/i386/csv.c b/target/i386/csv.c +index aac825d3f9..c11f59f30c 100644 +--- a/target/i386/csv.c ++++ b/target/i386/csv.c +@@ -13,6 +13,12 @@ + + #include "qemu/osdep.h" + ++#include ++ ++#ifdef CONFIG_NUMA ++#include ++#endif ++ + #include "cpu.h" + #include "sev.h" + #include "csv.h" +@@ -41,6 +47,44 @@ static bool is_hygon_cpu(void) + return false; + } + ++int ++csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) ++{ ++ int fw_error; ++ int ret; ++ struct kvm_csv_init_data data = { 0 }; ++ ++#ifdef CONFIG_NUMA ++ int mode; ++ unsigned long nodemask; ++ ++ /* Set flags as 0 to retrieve the default NUMA policy. */ ++ ret = get_mempolicy(&mode, &nodemask, sizeof(nodemask) * 8, NULL, 0); ++ if (ret == 0 && (mode == MPOL_BIND)) ++ data.nodemask = nodemask; ++#endif ++ ++ if (!ops || !ops->sev_ioctl || !ops->fw_error_to_str) ++ return -1; ++ ++ csv_guest.policy = policy; ++ if (csv_enabled()) { ++ ret = ops->sev_ioctl(fd, KVM_CSV_INIT, &data, &fw_error); ++ if (ret) { ++ csv_guest.policy = 0; ++ error_report("%s: Fail to initialize ret=%d fw_error=%d '%s'", ++ __func__, ret, fw_error, ops->fw_error_to_str(fw_error)); ++ return -1; ++ } ++ ++ csv_guest.sev_fd = fd; ++ csv_guest.state = state; ++ csv_guest.sev_ioctl = ops->sev_ioctl; ++ csv_guest.fw_error_to_str = ops->fw_error_to_str; ++ } ++ return 0; ++} ++ + bool + csv_enabled(void) + { +diff --git a/target/i386/csv.h b/target/i386/csv.h +index 057d37d975..886dbb2613 100644 +--- a/target/i386/csv.h ++++ b/target/i386/csv.h +@@ -26,10 +26,13 @@ struct CsvGuestState { + uint32_t policy; + int sev_fd; + void *state; ++ int (*sev_ioctl)(int fd, int cmd, void *data, int *error); ++ const char *(*fw_error_to_str)(int code); + }; + + typedef struct CsvGuestState CsvGuestState; + + extern struct CsvGuestState csv_guest; ++extern int csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops); + + #endif +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 025ff7a6f8..023532f4ec 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -26,6 +26,7 @@ + #include "crypto/hash.h" + #include "sysemu/kvm.h" + #include "sev.h" ++#include "csv.h" + #include "sysemu/sysemu.h" + #include "sysemu/runstate.h" + #include "trace.h" +@@ -43,6 +44,8 @@ + OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST) + + ++extern struct sev_ops sev_ops; ++ + /** + * SevGuestState: + * +@@ -952,6 +955,15 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + goto err; + } + ++ /* Support CSV */ ++ if (!ret && cmd == KVM_SEV_ES_INIT) { ++ ret = csv_init(sev_guest->policy, sev->sev_fd, &sev->state, &sev_ops); ++ if (ret) { ++ error_setg(errp, "%s: failed to init csv context", __func__); ++ goto err; ++ } ++ } ++ + ret = sev_launch_start(sev); + if (ret) { + error_setg(errp, "%s: failed to create encryption context", __func__); +@@ -1332,6 +1344,11 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) + return ret; + } + ++struct sev_ops sev_ops = { ++ .sev_ioctl = sev_ioctl, ++ .fw_error_to_str = fw_error_to_str, ++}; ++ + static void + sev_register_types(void) + { +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 83e82aa42c..1c97bff99e 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -59,4 +59,9 @@ void sev_es_set_reset_vector(CPUState *cpu); + + int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); + ++struct sev_ops { ++ int (*sev_ioctl)(int fd, int cmd, void *data, int *error); ++ const char *(*fw_error_to_str)(int code); ++}; ++ + #endif +-- +2.17.1 + diff --git a/0003-anolis-csv-i386-add-command-to-load-data-to-guest-me.patch b/0003-anolis-csv-i386-add-command-to-load-data-to-guest-me.patch new file mode 100644 index 0000000..ba1f14a --- /dev/null +++ b/0003-anolis-csv-i386-add-command-to-load-data-to-guest-me.patch @@ -0,0 +1,164 @@ +From 6dcfcd61e610da4e8d7dcfb6c3eefd7fc8a67c45 Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Wed, 25 Aug 2021 09:59:16 +0800 +Subject: [PATCH 3/8] anolis: csv/i386: add command to load data to guest + memory + +The KVM_CSV_LAUNCH_ENCRYPT_DATA command is used to load data to an +encrypted guest memory in an isolated memory region that guest owns. + +Signed-off-by: Xin Jiang +Change-Id: I6d4bea4969a0afa87fb8f2e52fb7ab02ec0db2ed +--- + linux-headers/linux/kvm.h | 7 ++++ + target/i386/csv-sysemu-stub.c | 5 +++ + target/i386/csv.c | 69 +++++++++++++++++++++++++++++++++++ + target/i386/csv.h | 2 + + target/i386/trace-events | 3 ++ + 5 files changed, 86 insertions(+) + +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index b15b8f5550..53f9202ffb 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -1813,6 +1813,13 @@ enum csv_cmd_id { + KVM_CSV_NR_MIN = 0xc0, + + KVM_CSV_INIT = KVM_CSV_NR_MIN, ++ KVM_CSV_LAUNCH_ENCRYPT_DATA, ++}; ++ ++struct kvm_csv_launch_encrypt_data { ++ __u64 gpa; ++ __u64 uaddr; ++ __u32 len; + }; + + struct kvm_csv_init_data { +diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c +index dbd710dc6f..236a6909d2 100644 +--- a/target/i386/csv-sysemu-stub.c ++++ b/target/i386/csv-sysemu-stub.c +@@ -19,3 +19,8 @@ int csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) + { + return 0; + } ++ ++int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) ++{ ++ g_assert_not_reached(); ++} +diff --git a/target/i386/csv.c b/target/i386/csv.c +index c11f59f30c..3b3dff5174 100644 +--- a/target/i386/csv.c ++++ b/target/i386/csv.c +@@ -14,11 +14,13 @@ + #include "qemu/osdep.h" + + #include ++#include "qapi/error.h" + + #ifdef CONFIG_NUMA + #include + #endif + ++#include "trace.h" + #include "cpu.h" + #include "sev.h" + #include "csv.h" +@@ -93,3 +95,70 @@ csv_enabled(void) + + return sev_es_enabled() && (csv_guest.policy & GUEST_POLICY_CSV_BIT); + } ++ ++static bool ++csv_check_state(SevState state) ++{ ++ return *((SevState *)csv_guest.state) == state ? true : false; ++} ++ ++static int ++csv_ioctl(int cmd, void *data, int *error) ++{ ++ if (csv_guest.sev_ioctl) ++ return csv_guest.sev_ioctl(csv_guest.sev_fd, cmd, data, error); ++ else ++ return -1; ++} ++ ++static const char * ++fw_error_to_str(int code) ++{ ++ if (csv_guest.fw_error_to_str) ++ return csv_guest.fw_error_to_str(code); ++ else ++ return NULL; ++} ++ ++static int ++csv_launch_encrypt_data(uint64_t gpa, uint8_t *addr, uint64_t len) ++{ ++ int ret, fw_error; ++ struct kvm_csv_launch_encrypt_data update; ++ ++ if (!addr || !len) { ++ return 1; ++ } ++ ++ update.gpa = (__u64)gpa; ++ update.uaddr = (__u64)(unsigned long)addr; ++ update.len = len; ++ trace_kvm_csv_launch_encrypt_data(gpa, addr, len); ++ ret = csv_ioctl(KVM_CSV_LAUNCH_ENCRYPT_DATA, &update, &fw_error); ++ if (ret) { ++ error_report("%s: CSV LAUNCH_ENCRYPT_DATA ret=%d fw_error=%d '%s'", ++ __func__, ret, fw_error, fw_error_to_str(fw_error)); ++ } ++ ++ return ret; ++} ++ ++int ++csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) ++{ ++ int ret = 0; ++ ++ if (!csv_enabled()) { ++ error_setg(errp, "%s: CSV is not enabled", __func__); ++ return -1; ++ } ++ ++ /* if CSV is in update state then load the data to secure memory */ ++ if (csv_check_state(SEV_STATE_LAUNCH_UPDATE)) { ++ ret = csv_launch_encrypt_data(gpa, ptr, len); ++ if (ret) ++ error_setg(errp, "%s: CSV fail to encrypt data", __func__); ++ } ++ ++ return ret; ++} +diff --git a/target/i386/csv.h b/target/i386/csv.h +index 886dbb2613..6f7b112d96 100644 +--- a/target/i386/csv.h ++++ b/target/i386/csv.h +@@ -35,4 +35,6 @@ typedef struct CsvGuestState CsvGuestState; + extern struct CsvGuestState csv_guest; + extern int csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops); + ++int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); ++ + #endif +diff --git a/target/i386/trace-events b/target/i386/trace-events +index 2cd8726eeb..b7da9bd748 100644 +--- a/target/i386/trace-events ++++ b/target/i386/trace-events +@@ -11,3 +11,6 @@ kvm_sev_launch_measurement(const char *value) "data %s" + kvm_sev_launch_finish(void) "" + kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d" + kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data %s" ++ ++# csv.c ++kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 +-- +2.17.1 + diff --git a/0004-anolis-csv-i386-add-command-to-load-vmcb-to-guest-me.patch b/0004-anolis-csv-i386-add-command-to-load-vmcb-to-guest-me.patch new file mode 100644 index 0000000..1ea643b --- /dev/null +++ b/0004-anolis-csv-i386-add-command-to-load-vmcb-to-guest-me.patch @@ -0,0 +1,107 @@ +From 630d76cc15bd98669162f785861cdd81f2ee8f01 Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Wed, 25 Aug 2021 12:25:05 +0800 +Subject: [PATCH 4/8] anolis: csv/i386: add command to load vmcb to guest + memory + +The KVM_CSV_LAUNCH_ENCRYPT_VMCB command is used to load and encrypt +the initial VMCB data to secure memory in an isolated region +that guest owns. + +Signed-off-by: Xin Jiang +Change-Id: I821bc8ab726f1bd22df36c163196951504eaa8da +--- + linux-headers/linux/kvm.h | 1 + + target/i386/csv-sysemu-stub.c | 5 +++++ + target/i386/csv.c | 21 +++++++++++++++++++++ + target/i386/csv.h | 1 + + target/i386/sev.c | 7 +++++-- + 5 files changed, 33 insertions(+), 2 deletions(-) + +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 53f9202ffb..c6cd3a619a 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -1814,6 +1814,7 @@ enum csv_cmd_id { + + KVM_CSV_INIT = KVM_CSV_NR_MIN, + KVM_CSV_LAUNCH_ENCRYPT_DATA, ++ KVM_CSV_LAUNCH_ENCRYPT_VMCB, + }; + + struct kvm_csv_launch_encrypt_data { +diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c +index 236a6909d2..a5ce986e3c 100644 +--- a/target/i386/csv-sysemu-stub.c ++++ b/target/i386/csv-sysemu-stub.c +@@ -24,3 +24,8 @@ int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) + { + g_assert_not_reached(); + } ++ ++int csv_launch_encrypt_vmcb(void) ++{ ++ g_assert_not_reached(); ++} +diff --git a/target/i386/csv.c b/target/i386/csv.c +index 3b3dff5174..d166d3775e 100644 +--- a/target/i386/csv.c ++++ b/target/i386/csv.c +@@ -162,3 +162,24 @@ csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) + + return ret; + } ++ ++int ++csv_launch_encrypt_vmcb(void) ++{ ++ int ret, fw_error; ++ ++ if (!csv_enabled()) { ++ error_report("%s: CSV is not enabled",__func__); ++ return -1; ++ } ++ ++ ret = csv_ioctl(KVM_CSV_LAUNCH_ENCRYPT_VMCB, NULL, &fw_error); ++ if (ret) { ++ error_report("%s: CSV LAUNCH_ENCRYPT_VMCB ret=%d fw_error=%d '%s'", ++ __func__, ret, fw_error, fw_error_to_str(fw_error)); ++ goto err; ++ } ++ ++err: ++ return ret; ++} +diff --git a/target/i386/csv.h b/target/i386/csv.h +index 6f7b112d96..7dc5c75366 100644 +--- a/target/i386/csv.h ++++ b/target/i386/csv.h +@@ -34,6 +34,7 @@ typedef struct CsvGuestState CsvGuestState; + + extern struct CsvGuestState csv_guest; + extern int csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops); ++extern int csv_launch_encrypt_vmcb(void); + + int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 023532f4ec..73a794ef74 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -770,8 +770,11 @@ sev_launch_get_measure(Notifier *notifier, void *unused) + } + + if (sev_es_enabled()) { +- /* measure all the VM save areas before getting launch_measure */ +- ret = sev_launch_update_vmsa(sev); ++ if (csv_enabled()) ++ ret = csv_launch_encrypt_vmcb(); ++ else ++ /* measure all the VM save areas before getting launch_measure */ ++ ret = sev_launch_update_vmsa(sev); + if (ret) { + exit(1); + } +-- +2.17.1 + diff --git a/0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch b/0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch new file mode 100644 index 0000000..97cb7cc --- /dev/null +++ b/0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch @@ -0,0 +1,41 @@ +From 501e16b4b4cf5a302363c1ae55fb4fb8e68beb8d Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Tue, 24 Aug 2021 17:31:28 +0800 +Subject: [PATCH 5/8] anolis: cpu/i386: populate CPUID 0x8000_001F when CSV is + active + +On Hygon platform, bit 30 of EAX indicates whether +this feature is supported in hardware. + +When CSV is active, CPUID 0x8000_001F provides +information for it. + +Signed-off-by: Xin Jiang +Change-Id: Ifdd2a20f7cb4a079ba918928f012e5f64f7059e6 +--- + target/i386/cpu.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index aa9e636800..970d9bf184 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -27,6 +27,7 @@ + #include "sysemu/hvf.h" + #include "kvm/kvm_i386.h" + #include "sev.h" ++#include "csv.h" + #include "qapi/error.h" + #include "qapi/qapi-visit-machine.h" + #include "qapi/qmp/qerror.h" +@@ -5769,6 +5770,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + if (sev_enabled()) { + *eax = 0x2; + *eax |= sev_es_enabled() ? 0x8 : 0; ++ *eax |= csv_enabled() ? 0x40000000 : 0; /* bit 30 for CSV */ + *ebx = sev_get_cbit_position() & 0x3f; /* EBX[5:0] */ + *ebx |= (sev_get_reduced_phys_bits() & 0x3f) << 6; /* EBX[11:6] */ + } +-- +2.17.1 + diff --git a/0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch b/0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch new file mode 100644 index 0000000..af4851e --- /dev/null +++ b/0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch @@ -0,0 +1,35 @@ +From e25884e4e0ee839b591836ae33681ac9a52883ce Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Wed, 25 Aug 2021 12:36:00 +0800 +Subject: [PATCH 6/8] anolis: csv/i386: CSV guest do not need + register/unregister guest secure memory + +CSV guest memory is allocated by firmware in secure processor +from dedicated memory reserved upon system boot up, +consequently it is not necessary to add notifier to pin/unpin memory. + +Signed-off-by: Xin Jiang +Change-Id: I10d5b5ee8dbc3a1bf9ed1935c006c61a094f1e8d +--- + target/i386/sev.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 73a794ef74..36669bbdf4 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -973,7 +973,10 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + goto err; + } + +- ram_block_notifier_add(&sev_ram_notifier); ++ /* CSV guest needs no notifier to reg/unreg memory */ ++ if (!csv_enabled()) { ++ ram_block_notifier_add(&sev_ram_notifier); ++ } + qemu_add_machine_init_done_notifier(&sev_machine_done_notify); + qemu_add_vm_change_state_handler(sev_vm_state_change, sev); + +-- +2.17.1 + diff --git a/0007-anolis-target-i386-csv-load-initial-image-to-private.patch b/0007-anolis-target-i386-csv-load-initial-image-to-private.patch new file mode 100644 index 0000000..a40bcfe --- /dev/null +++ b/0007-anolis-target-i386-csv-load-initial-image-to-private.patch @@ -0,0 +1,44 @@ +From 2df9c321195bd47485867e1d821913f1f3c21fc2 Mon Sep 17 00:00:00 2001 +From: Xin Jiang +Date: Fri, 25 Aug 2023 14:51:16 +0800 +Subject: [PATCH 7/8] anolis: target/i386: csv: load initial image to private + memory + +The initial image of CSV guest should be loaded into private memory +before guest boot. + +Add APIs to implement the image load. + +Signed-off-by: Xin Jiang +Change-Id: I708e7521bfe079216c0e0aea619a9c6bb1d7af04 +--- + hw/i386/pc_sysfw.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c +index c8b17af953..84aad306dc 100644 +--- a/hw/i386/pc_sysfw.c ++++ b/hw/i386/pc_sysfw.c +@@ -38,6 +38,7 @@ + #include "hw/block/flash.h" + #include "sysemu/kvm.h" + #include "sev.h" ++#include "csv.h" + + #define FLASH_SECTOR_SIZE 4096 + +@@ -208,7 +209,10 @@ static void pc_system_flash_map(PCMachineState *pcms, + exit(1); + } + +- sev_encrypt_flash(flash_ptr, flash_size, &error_fatal); ++ if (csv_enabled()) ++ csv_load_data(flash_mem->addr, flash_ptr, flash_size, &error_fatal); ++ else ++ sev_encrypt_flash(flash_ptr, flash_size, &error_fatal); + } + } + } +-- +2.17.1 + diff --git a/0008-anolis-vga-force-full-update-for-CSV-guest.patch b/0008-anolis-vga-force-full-update-for-CSV-guest.patch new file mode 100644 index 0000000..40842ec --- /dev/null +++ b/0008-anolis-vga-force-full-update-for-CSV-guest.patch @@ -0,0 +1,47 @@ +From 42d8658a8868721a0c4fb08295a8957e9fdc96c6 Mon Sep 17 00:00:00 2001 +From: Xin Jiang +Date: Thu, 13 Jul 2023 09:35:10 +0800 +Subject: [PATCH 8/8] anolis: vga: force full update for CSV guest + +As CSV's NPT(nested page table) is managed by firmware, VMM is hard +to track the dirty pages of vga buffer. Although VMM could perform +a command to firmware to update read/write attribute of vga buffer +in NPT, it costs more time due to communication between VMM and +firmware. So the simplest method is to fully update vga buffer +always. + +Signed-off-by: Xin Jiang +Change-Id: I51ff00440483011fb9088a75005644beb378f8dd +--- + hw/display/vga.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/hw/display/vga.c b/hw/display/vga.c +index 9d1f66af40..be4282a2f5 100644 +--- a/hw/display/vga.c ++++ b/hw/display/vga.c +@@ -36,6 +36,9 @@ + #include "migration/vmstate.h" + #include "trace.h" + ++#include "target/i386/sev.h" ++#include "target/i386/csv.h" ++ + //#define DEBUG_VGA_MEM + //#define DEBUG_VGA_REG + +@@ -1779,6 +1782,11 @@ static void vga_update_display(void *opaque) + s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); + full_update = 1; + } ++ ++ /* Force to full update in CSV guest. */ ++ if (csv_enabled()) ++ full_update = 1; ++ + switch(graphic_mode) { + case GMODE_TEXT: + vga_draw_text(s, full_update); +-- +2.17.1 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index b8600f1..ca1c0ec 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -934,6 +934,16 @@ Patch1026: Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch Patch1027: Fix-LoongArch-KVM-header-macros.patch Patch1028: Fixed-the-issue-where-qemu-specifies-the-boot-order.patch +# CSV3 feature on Hygon hardware +Patch1030: 0001-anolis-csv-i386-add-CSV-context.patch +Patch1031: 0002-anolis-csv-i386-add-command-to-initialize-CSV-contex.patch +Patch1032: 0003-anolis-csv-i386-add-command-to-load-data-to-guest-me.patch +Patch1033: 0004-anolis-csv-i386-add-command-to-load-vmcb-to-guest-me.patch +Patch1034: 0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch +Patch1035: 0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch +Patch1036: 0007-anolis-target-i386-csv-load-initial-image-to-private.patch +Patch1037: 0008-anolis-vga-force-full-update-for-CSV-guest.patch + BuildRequires: wget BuildRequires: rpm-build BuildRequires: ninja-build @@ -2194,6 +2204,15 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : - Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch (zhaotianrui@loongson.c) - Fix-LoongArch-KVM-header-macros.patch (zhaotianrui@loongson.c) - loongarch: Fixed the issue where qemu specifies the boot order (lixianglai@loongson.cn) +- 0001-anolis-csv-i386-add-CSV-context.patch (jiangxin@hygon.cn) +- 0002-anolis-csv-i386-add-command-to-initialize-CSV-contex.patch (jiangxin@hygon.cn) +- 0003-anolis-csv-i386-add-command-to-load-data-to-guest-me.patch (jiangxin@hygon.cn) +- 0004-anolis-csv-i386-add-command-to-load-vmcb-to-guest-me.patch (jiangxin@hygon.cn) +- 0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch (jiangxin@hygon.cn) +- 0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch (jiangxin@hygon.cn) +- 0007-anolis-target-i386-csv-load-initial-image-to-private.patch (jiangxin@hygon.cn) +- 0008-anolis-vga-force-full-update-for-CSV-guest.patch (jiangxin@hygon.cn) + (Hygon CSV3 feature) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] -- Gitee From a38512ea0954382bc5f96e1cfdc1d2519d7012ca Mon Sep 17 00:00:00 2001 From: hanliyang Date: Thu, 30 Nov 2023 16:26:13 +0000 Subject: [PATCH 10/17] Support Hygon CSV/CSV2 live migration, CSV2 reboot When migrate a CSV/CSV2 guest, the sender need retrive cert chains of the target host (i.e. receiver), this cert chains will help to negotiate a shared keys between sender and target host. The sender issues SEND_START, SEND_UPDATE_DATA, SEND_FINISH APIs to migrate the encrypted pages to target host, and the receiver issues RECEIVE_START, RECEIVE_UPDATE_DATA, RECEIVE_FINISH to restore the encrypted pages. In addition, the GHCB states and VMSAs are also need migrated to target host, so we introduce interface to support set/get/migrate GHCB states and make use of SEND_UPDATE_VMSA, RECEIVE_UPDATE_VMSA APIs to migrate VMSAs. When launch a CSV2 guest, the vCPU register states will be encrypted and prevent change by the host. In order to support reboot a CSV2 guest, we introduce kvm ioctl interfaces to notify KVM to reset the vCPU states to its initial encrypted states. Signed-off-by: hanliyang --- ...D-SEV-to-include-Live-migration-flow.patch | 69 +++ ...dd-AMD-SEV-specific-migration-parame.patch | 253 +++++++++++ ...st-support-introduce-ConfidentialGue.patch | 67 +++ ...provide-callback-to-setup-outgoing-c.patch | 135 ++++++ ...do-not-create-launch-context-for-an-.patch | 48 ++ ...add-support-to-encrypt-the-outgoing-.patch | 324 ++++++++++++++ ...add-support-to-load-incoming-encrypt.patch | 224 ++++++++++ ...for-SEV-shared-regions-list-and-KVM_.patch | 293 ++++++++++++ ...pport-to-migrate-shared-regions-list.patch | 103 +++++ ...-add-support-to-send-encrypted-pages.patch | 338 ++++++++++++++ ...rce-encrypted-status-for-flash0-flas.patch | 44 ++ ...V-live-migration-bump-downtime-limit.patch | 64 +++ ...86-kvm-Add-support-for-MSR-filtering.patch | 201 +++++++++ ...for-userspace-MSR-filtering-and-hand.patch | 118 +++++ ...-ram-Force-encrypted-status-for-VGA-.patch | 33 ++ ...86-sev-Clear-shared_regions_list-whe.patch | 58 +++ ...-ram-Fix-calculation-of-gfn-correpon.patch | 57 +++ ...86-csv-Move-is_hygon_cpu-to-header-f.patch | 85 ++++ ...86-csv-Read-cert-chain-from-file-whe.patch | 131 ++++++ ...86-csv-add-support-to-queue-the-outg.patch | 270 ++++++++++++ ...86-csv-add-support-to-encrypt-the-ou.patch | 204 +++++++++ ...86-csv-add-support-to-queue-the-inco.patch | 171 +++++++ ...86-csv-add-support-to-load-incoming-.patch | 108 +++++ ...-ram-Accelerate-the-transmission-of-.patch | 229 ++++++++++ ...-ram-Accelerate-the-loading-of-CSV-g.patch | 37 ++ ...86-csv-Add-support-for-migrate-VMSA-.patch | 416 ++++++++++++++++++ ...rget-i386-get-set-migrate-GHCB-state.patch | 175 ++++++++ ...86-kvm-Return-resettable-when-emulat.patch | 39 ++ ...olis-kvm-Add-support-for-CSV2-reboot.patch | 170 +++++++ qemu-kvm.spec | 30 ++ 30 files changed, 4494 insertions(+) create mode 100644 1038-doc-update-AMD-SEV-to-include-Live-migration-flow.patch create mode 100644 1039-migration.json-add-AMD-SEV-specific-migration-parame.patch create mode 100644 1040-confidential-guest-support-introduce-ConfidentialGue.patch create mode 100644 1041-target-i386-sev-provide-callback-to-setup-outgoing-c.patch create mode 100644 1042-target-i386-sev-do-not-create-launch-context-for-an-.patch create mode 100644 1043-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch create mode 100644 1044-target-i386-sev-add-support-to-load-incoming-encrypt.patch create mode 100644 1045-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch create mode 100644 1046-migration-add-support-to-migrate-shared-regions-list.patch create mode 100644 1047-migration-ram-add-support-to-send-encrypted-pages.patch create mode 100644 1048-migration-ram-Force-encrypted-status-for-flash0-flas.patch create mode 100644 1049-migration-for-SEV-live-migration-bump-downtime-limit.patch create mode 100644 1050-i386-kvm-Add-support-for-MSR-filtering.patch create mode 100644 1051-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch create mode 100644 1052-anolis-migration-ram-Force-encrypted-status-for-VGA-.patch create mode 100644 1053-anolis-target-i386-sev-Clear-shared_regions_list-whe.patch create mode 100644 1054-anolis-migration-ram-Fix-calculation-of-gfn-correpon.patch create mode 100644 1055-anolis-target-i386-csv-Move-is_hygon_cpu-to-header-f.patch create mode 100644 1056-anolis-target-i386-csv-Read-cert-chain-from-file-whe.patch create mode 100644 1057-anolis-target-i386-csv-add-support-to-queue-the-outg.patch create mode 100644 1058-anolis-target-i386-csv-add-support-to-encrypt-the-ou.patch create mode 100644 1059-anolis-target-i386-csv-add-support-to-queue-the-inco.patch create mode 100644 1060-anolis-target-i386-csv-add-support-to-load-incoming-.patch create mode 100644 1061-anolis-migration-ram-Accelerate-the-transmission-of-.patch create mode 100644 1062-anolis-migration-ram-Accelerate-the-loading-of-CSV-g.patch create mode 100644 1063-anolis-target-i386-csv-Add-support-for-migrate-VMSA-.patch create mode 100644 1064-anolis-target-i386-get-set-migrate-GHCB-state.patch create mode 100644 1065-anolis-target-i386-kvm-Return-resettable-when-emulat.patch create mode 100644 1066-anolis-kvm-Add-support-for-CSV2-reboot.patch diff --git a/1038-doc-update-AMD-SEV-to-include-Live-migration-flow.patch b/1038-doc-update-AMD-SEV-to-include-Live-migration-flow.patch new file mode 100644 index 0000000..6672e3f --- /dev/null +++ b/1038-doc-update-AMD-SEV-to-include-Live-migration-flow.patch @@ -0,0 +1,69 @@ +From 5152d49cc4aead7dc06e9f788e9c078701c5a160 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +Date: Thu, 7 May 2020 22:26:17 +0000 +Subject: [PATCH 01/29] doc: update AMD SEV to include Live migration flow + +cherry-picked from https://github.com/AMDESE/qemu/commit/0e2b3d80e3. + +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Brijesh Singh +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + docs/amd-memory-encryption.txt | 40 +++++++++++++++++++++++++++++++++- + 1 file changed, 39 insertions(+), 1 deletion(-) + +diff --git a/docs/amd-memory-encryption.txt b/docs/amd-memory-encryption.txt +index ffca382b5..17e2714d9 100644 +--- a/docs/amd-memory-encryption.txt ++++ b/docs/amd-memory-encryption.txt +@@ -126,7 +126,45 @@ TODO + + Live Migration + ---------------- +-TODO ++AMD SEV encrypts the memory of VMs and because a different key is used ++in each VM, the hypervisor will be unable to simply copy the ++ciphertext from one VM to another to migrate the VM. Instead the AMD SEV Key ++Management API provides sets of function which the hypervisor can use ++to package a guest page for migration, while maintaining the confidentiality ++provided by AMD SEV. ++ ++SEV guest VMs have the concept of private and shared memory. The private ++memory is encrypted with the guest-specific key, while shared memory may ++be encrypted with the hypervisor key. The migration APIs provided by the ++SEV API spec should be used for migrating the private pages. The ++KVM_GET_PAGE_ENC_BITMAP ioctl can be used to get the guest page encryption ++bitmap. The bitmap can be used to check if the given guest page is ++private or shared. ++ ++Before initiating the migration, we need to know the targets machine's public ++Diffie-Hellman key (PDH) and certificate chain. It can be retrieved ++with the 'query-sev-capabilities' QMP command or using the sev-tool. The ++migrate-set-parameter can be used to pass the target machine's PDH and ++certificate chain. ++ ++During the migration flow, the SEND_START is called on the source hypervisor ++to create an outgoing encryption context. The SEV guest policy dictates whether ++the certificate passed through the migrate-sev-set-info command will be ++validated. SEND_UPDATE_DATA is called to encrypt the guest private pages. ++After migration is completed, SEND_FINISH is called to destroy the encryption ++context and make the VM non-runnable to protect it against cloning. ++ ++On the target machine, RECEIVE_START is called first to create an ++incoming encryption context. The RECEIVE_UPDATE_DATA is called to copy ++the received encrypted page into guest memory. After migration has ++completed, RECEIVE_FINISH is called to make the VM runnable. ++ ++For more information about the migration see SEV API Appendix A ++Usage flow (Live migration section). ++ ++NOTE: ++To protect against the memory clone SEV APIs are designed to make the VM ++unrunnable in case of the migration failure. + + References + ----------------- +-- +2.31.1 + diff --git a/1039-migration.json-add-AMD-SEV-specific-migration-parame.patch b/1039-migration.json-add-AMD-SEV-specific-migration-parame.patch new file mode 100644 index 0000000..bd46ba7 --- /dev/null +++ b/1039-migration.json-add-AMD-SEV-specific-migration-parame.patch @@ -0,0 +1,253 @@ +From 7dc7f0659bfe9c8be64f65873df9595b3791dce5 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +Date: Tue, 27 Jul 2021 11:27:00 +0000 +Subject: [PATCH 02/29] migration.json: add AMD SEV specific migration + parameters + +cherry-picked from https://github.com/AMDESE/qemu/commit/d6a23bde6b6e. + +AMD SEV migration flow requires that target machine's public Diffie-Hellman +key (PDH) and certificate chain must be passed before initiating the guest +migration. User can use QMP 'migrate-set-parameters' to pass the certificate +chain. The certificate chain will be used while creating the outgoing +encryption context. + +Signed-off-by: Brijesh Singh +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + migration/migration.c | 66 +++++++++++++++++++++++++++++++++++++++++++ + monitor/hmp-cmds.c | 18 ++++++++++++ + qapi/migration.json | 40 ++++++++++++++++++++++++-- + 3 files changed, 121 insertions(+), 3 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 0885549de..6810bcefc 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -932,6 +932,12 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) + params->announce_rounds = s->parameters.announce_rounds; + params->has_announce_step = true; + params->announce_step = s->parameters.announce_step; ++ params->has_sev_pdh = true; ++ params->sev_pdh = g_strdup(s->parameters.sev_pdh); ++ params->has_sev_plat_cert = true; ++ params->sev_plat_cert = g_strdup(s->parameters.sev_plat_cert); ++ params->has_sev_amd_cert = true; ++ params->sev_amd_cert = g_strdup(s->parameters.sev_amd_cert); + + if (s->parameters.has_block_bitmap_mapping) { + params->has_block_bitmap_mapping = true; +@@ -1633,6 +1639,19 @@ static void migrate_params_test_apply(MigrateSetParameters *params, + dest->has_block_bitmap_mapping = true; + dest->block_bitmap_mapping = params->block_bitmap_mapping; + } ++ ++ if (params->has_sev_pdh) { ++ assert(params->sev_pdh->type == QTYPE_QSTRING); ++ dest->sev_pdh = g_strdup(params->sev_pdh->u.s); ++ } ++ if (params->has_sev_plat_cert) { ++ assert(params->sev_plat_cert->type == QTYPE_QSTRING); ++ dest->sev_plat_cert = g_strdup(params->sev_plat_cert->u.s); ++ } ++ if (params->has_sev_amd_cert) { ++ assert(params->sev_amd_cert->type == QTYPE_QSTRING); ++ dest->sev_amd_cert = g_strdup(params->sev_amd_cert->u.s); ++ } + } + + static void migrate_params_apply(MigrateSetParameters *params, Error **errp) +@@ -1755,6 +1774,22 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp) + QAPI_CLONE(BitmapMigrationNodeAliasList, + params->block_bitmap_mapping); + } ++ ++ if (params->has_sev_pdh) { ++ g_free(s->parameters.sev_pdh); ++ assert(params->sev_pdh->type == QTYPE_QSTRING); ++ s->parameters.sev_pdh = g_strdup(params->sev_pdh->u.s); ++ } ++ if (params->has_sev_plat_cert) { ++ g_free(s->parameters.sev_plat_cert); ++ assert(params->sev_plat_cert->type == QTYPE_QSTRING); ++ s->parameters.sev_plat_cert = g_strdup(params->sev_plat_cert->u.s); ++ } ++ if (params->has_sev_amd_cert) { ++ g_free(s->parameters.sev_amd_cert); ++ assert(params->sev_amd_cert->type == QTYPE_QSTRING); ++ s->parameters.sev_amd_cert = g_strdup(params->sev_amd_cert->u.s); ++ } + } + + void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) +@@ -1775,6 +1810,27 @@ void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) + params->tls_hostname->type = QTYPE_QSTRING; + params->tls_hostname->u.s = strdup(""); + } ++ /* TODO Rewrite "" to null instead */ ++ if (params->has_sev_pdh ++ && params->sev_pdh->type == QTYPE_QNULL) { ++ qobject_unref(params->sev_pdh->u.n); ++ params->sev_pdh->type = QTYPE_QSTRING; ++ params->sev_pdh->u.s = strdup(""); ++ } ++ /* TODO Rewrite "" to null instead */ ++ if (params->has_sev_plat_cert ++ && params->sev_plat_cert->type == QTYPE_QNULL) { ++ qobject_unref(params->sev_plat_cert->u.n); ++ params->sev_plat_cert->type = QTYPE_QSTRING; ++ params->sev_plat_cert->u.s = strdup(""); ++ } ++ /* TODO Rewrite "" to null instead */ ++ if (params->has_sev_amd_cert ++ && params->sev_amd_cert->type == QTYPE_QNULL) { ++ qobject_unref(params->sev_amd_cert->u.n); ++ params->sev_amd_cert->type = QTYPE_QSTRING; ++ params->sev_amd_cert->u.s = strdup(""); ++ } + + migrate_params_test_apply(params, &tmp); + +@@ -4332,6 +4388,9 @@ static void migration_instance_finalize(Object *obj) + qemu_mutex_destroy(&ms->qemu_file_lock); + g_free(params->tls_hostname); + g_free(params->tls_creds); ++ g_free(params->sev_pdh); ++ g_free(params->sev_plat_cert); ++ g_free(params->sev_amd_cert); + qemu_sem_destroy(&ms->wait_unplug_sem); + qemu_sem_destroy(&ms->rate_limit_sem); + qemu_sem_destroy(&ms->pause_sem); +@@ -4383,6 +4442,13 @@ static void migration_instance_init(Object *obj) + params->has_tls_hostname = true; + params->has_tls_authz = true; + ++ params->sev_pdh = g_strdup(""); ++ params->sev_plat_cert = g_strdup(""); ++ params->sev_amd_cert = g_strdup(""); ++ params->has_sev_pdh = true; ++ params->has_sev_plat_cert = true; ++ params->has_sev_amd_cert = true; ++ + qemu_sem_init(&ms->postcopy_pause_sem, 0); + qemu_sem_init(&ms->postcopy_pause_rp_sem, 0); + qemu_sem_init(&ms->rp_state.rp_sem, 0); +diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c +index f7216ab5d..409bd15a6 100644 +--- a/monitor/hmp-cmds.c ++++ b/monitor/hmp-cmds.c +@@ -1349,6 +1349,24 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) + error_setg(&err, "The block-bitmap-mapping parameter can only be set " + "through QMP"); + break; ++ case MIGRATION_PARAMETER_SEV_PDH: ++ p->has_sev_pdh = true; ++ p->sev_pdh = g_new0(StrOrNull, 1); ++ p->sev_pdh->type = QTYPE_QSTRING; ++ visit_type_str(v, param, &p->sev_pdh->u.s, &err); ++ break; ++ case MIGRATION_PARAMETER_SEV_PLAT_CERT: ++ p->has_sev_plat_cert = true; ++ p->sev_plat_cert = g_new0(StrOrNull, 1); ++ p->sev_plat_cert->type = QTYPE_QSTRING; ++ visit_type_str(v, param, &p->sev_plat_cert->u.s, &err); ++ break; ++ case MIGRATION_PARAMETER_SEV_AMD_CERT: ++ p->has_sev_amd_cert = true; ++ p->sev_amd_cert = g_new0(StrOrNull, 1); ++ p->sev_amd_cert->type = QTYPE_QSTRING; ++ visit_type_str(v, param, &p->sev_amd_cert->u.s, &err); ++ break; + default: + assert(0); + } +diff --git a/qapi/migration.json b/qapi/migration.json +index 94bc5c69d..bad53a2f8 100644 +--- a/qapi/migration.json ++++ b/qapi/migration.json +@@ -774,6 +774,15 @@ + # block device name if there is one, and to their node name + # otherwise. (Since 5.2) + # ++# @sev-pdh: The target host platform diffie-hellman key encoded in base64 ++# (Since 4.2) ++# ++# @sev-plat-cert: The target host platform certificate chain encoded in base64 ++# (Since 4.2) ++# ++# @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in ++# base64 (Since 4.2) ++# + # Features: + # @unstable: Member @x-checkpoint-delay is experimental. + # +@@ -794,7 +803,8 @@ + 'xbzrle-cache-size', 'max-postcopy-bandwidth', + 'max-cpu-throttle', 'multifd-compression', + 'multifd-zlib-level' ,'multifd-zstd-level', +- 'block-bitmap-mapping' ] } ++ 'block-bitmap-mapping', ++ 'sev-pdh', 'sev-plat-cert', 'sev-amd-cert' ] } + + ## + # @MigrateSetParameters: +@@ -939,6 +949,15 @@ + # block device name if there is one, and to their node name + # otherwise. (Since 5.2) + # ++# @sev-pdh: The target host platform diffie-hellman key encoded in base64 ++# (Since 4.2) ++# ++# @sev-plat-cert: The target host platform certificate chain encoded in base64 ++# (Since 4.2) ++# ++# @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in ++# base64 (Since 4.2) ++# + # Features: + # @unstable: Member @x-checkpoint-delay is experimental. + # +@@ -974,7 +993,10 @@ + '*multifd-compression': 'MultiFDCompression', + '*multifd-zlib-level': 'uint8', + '*multifd-zstd-level': 'uint8', +- '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } } ++ '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ], ++ '*sev-pdh':'StrOrNull', ++ '*sev-plat-cert': 'StrOrNull', ++ '*sev-amd-cert' : 'StrOrNull' } } + + ## + # @migrate-set-parameters: +@@ -1139,6 +1161,15 @@ + # block device name if there is one, and to their node name + # otherwise. (Since 5.2) + # ++# @sev-pdh: The target host platform diffie-hellman key encoded in base64 ++# (Since 4.2) ++# ++# @sev-plat-cert: The target host platform certificate chain encoded in base64 ++# (Since 4.2) ++# ++# @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in ++# base64 (Since 4.2) ++# + # Features: + # @unstable: Member @x-checkpoint-delay is experimental. + # +@@ -1172,7 +1203,10 @@ + '*multifd-compression': 'MultiFDCompression', + '*multifd-zlib-level': 'uint8', + '*multifd-zstd-level': 'uint8', +- '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } } ++ '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ], ++ '*sev-pdh':'str', ++ '*sev-plat-cert': 'str', ++ '*sev-amd-cert' : 'str'} } + + ## + # @query-migrate-parameters: +-- +2.31.1 + diff --git a/1040-confidential-guest-support-introduce-ConfidentialGue.patch b/1040-confidential-guest-support-introduce-ConfidentialGue.patch new file mode 100644 index 0000000..c76a7dc --- /dev/null +++ b/1040-confidential-guest-support-introduce-ConfidentialGue.patch @@ -0,0 +1,67 @@ +From 7b50e920f4faacb529a43230565ae9e022e61649 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +Date: Tue, 27 Jul 2021 11:41:37 +0000 +Subject: [PATCH 03/29] confidential guest support: introduce + ConfidentialGuestMemoryEncryptionOps for encrypted VMs + +cherry-picked from https://github.com/AMDESE/qemu/commit/74fce7be9bd. + +When memory encryption is enabled in VM, the guest RAM will be encrypted +with the guest-specific key, to protect the confidentiality of data while +in transit we need to platform specific hooks to save or migrate the +guest RAM. + +Introduce the new ConfidentialGuestMemoryEncryptionOps in this patch +which will be later used by the encrypted guest for migration. + +Signed-off-by: Brijesh Singh +Co-developed-by: Ashish Kalra +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + include/exec/confidential-guest-support.h | 27 +++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h +index ba2dd4b5d..343f686fc 100644 +--- a/include/exec/confidential-guest-support.h ++++ b/include/exec/confidential-guest-support.h +@@ -53,8 +53,35 @@ struct ConfidentialGuestSupport { + bool ready; + }; + ++/** ++ * The functions registers with ConfidentialGuestMemoryEncryptionOps will be ++ * used during the encrypted guest migration. ++ */ ++struct ConfidentialGuestMemoryEncryptionOps { ++ /* Initialize the platform specific state before starting the migration */ ++ int (*save_setup)(const char *pdh, const char *plat_cert, ++ const char *amd_cert); ++ ++ /* Write the encrypted page and metadata associated with it */ ++ int (*save_outgoing_page)(QEMUFile *f, uint8_t *ptr, uint32_t size, ++ uint64_t *bytes_sent); ++ ++ /* Load the incoming encrypted page into guest memory */ ++ int (*load_incoming_page)(QEMUFile *f, uint8_t *ptr); ++ ++ /* Check if gfn is in shared/unencrypted region */ ++ bool (*is_gfn_in_unshared_region)(unsigned long gfn); ++ ++ /* Write the shared regions list */ ++ int (*save_outgoing_shared_regions_list)(QEMUFile *f); ++ ++ /* Load the shared regions list */ ++ int (*load_incoming_shared_regions_list)(QEMUFile *f); ++}; ++ + typedef struct ConfidentialGuestSupportClass { + ObjectClass parent; ++ struct ConfidentialGuestMemoryEncryptionOps *memory_encryption_ops; + } ConfidentialGuestSupportClass; + + #endif /* !CONFIG_USER_ONLY */ +-- +2.31.1 + diff --git a/1041-target-i386-sev-provide-callback-to-setup-outgoing-c.patch b/1041-target-i386-sev-provide-callback-to-setup-outgoing-c.patch new file mode 100644 index 0000000..f7c60e2 --- /dev/null +++ b/1041-target-i386-sev-provide-callback-to-setup-outgoing-c.patch @@ -0,0 +1,135 @@ +From 4e400056b6e3d895814d091da819ba742602581b Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +Date: Tue, 27 Jul 2021 12:10:23 +0000 +Subject: [PATCH 04/29] target/i386: sev: provide callback to setup outgoing + context + +cherry-picked from https://github.com/AMDESE/qemu/commit/7521883afc0. + +The user provides the target machine's Platform Diffie-Hellman key (PDH) +and certificate chain before starting the SEV guest migration. Cache the +certificate chain as we need them while creating the outgoing context. + +Signed-off-by: Brijesh Singh +Co-developed-by: Ashish Kalra +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + target/i386/sev.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ + target/i386/sev.h | 2 ++ + 2 files changed, 61 insertions(+) + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 36669bbdf..5dd6c0a3f 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -76,6 +76,12 @@ struct SevGuestState { + int sev_fd; + SevState state; + gchar *measurement; ++ guchar *remote_pdh; ++ size_t remote_pdh_len; ++ guchar *remote_plat_cert; ++ size_t remote_plat_cert_len; ++ guchar *amd_cert; ++ size_t amd_cert_len; + + uint32_t reset_cs; + uint32_t reset_ip; +@@ -160,6 +166,12 @@ static const char *const sev_fw_errlist[] = { + + #define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist) + ++#define SEV_FW_BLOB_MAX_SIZE 0x4000 /* 16KB */ ++ ++static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { ++ .save_setup = sev_save_setup, ++}; ++ + static int + sev_ioctl(int fd, int cmd, void *data, int *error) + { +@@ -872,6 +884,48 @@ sev_vm_state_change(void *opaque, bool running, RunState state) + } + } + ++static inline bool check_blob_length(size_t value) ++{ ++ if (value > SEV_FW_BLOB_MAX_SIZE) { ++ error_report("invalid length max=%d got=%ld", ++ SEV_FW_BLOB_MAX_SIZE, value); ++ return false; ++ } ++ ++ return true; ++} ++ ++int sev_save_setup(const char *pdh, const char *plat_cert, ++ const char *amd_cert) ++{ ++ SevGuestState *s = sev_guest; ++ ++ s->remote_pdh = g_base64_decode(pdh, &s->remote_pdh_len); ++ if (!check_blob_length(s->remote_pdh_len)) { ++ goto error; ++ } ++ ++ s->remote_plat_cert = g_base64_decode(plat_cert, ++ &s->remote_plat_cert_len); ++ if (!check_blob_length(s->remote_plat_cert_len)) { ++ goto error; ++ } ++ ++ s->amd_cert = g_base64_decode(amd_cert, &s->amd_cert_len); ++ if (!check_blob_length(s->amd_cert_len)) { ++ goto error; ++ } ++ ++ return 0; ++ ++error: ++ g_free(s->remote_pdh); ++ g_free(s->remote_plat_cert); ++ g_free(s->amd_cert); ++ ++ return 1; ++} ++ + int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + { + SevGuestState *sev +@@ -886,6 +940,9 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + return 0; + } + ++ ConfidentialGuestSupportClass *cgs_class = ++ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(cgs)); ++ + ret = ram_block_discard_disable(true); + if (ret) { + error_report("%s: cannot disable RAM discard", __func__); +@@ -980,6 +1037,8 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + qemu_add_machine_init_done_notifier(&sev_machine_done_notify); + qemu_add_vm_change_state_handler(sev_vm_state_change, sev); + ++ cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; ++ + cgs->ready = true; + + return 0; +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 1c97bff99..14801ec44 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -51,6 +51,8 @@ extern uint32_t sev_get_reduced_phys_bits(void); + extern bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp); + + int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp); ++int sev_save_setup(const char *pdh, const char *plat_cert, ++ const char *amd_cert); + int sev_inject_launch_secret(const char *hdr, const char *secret, + uint64_t gpa, Error **errp); + +-- +2.31.1 + diff --git a/1042-target-i386-sev-do-not-create-launch-context-for-an-.patch b/1042-target-i386-sev-do-not-create-launch-context-for-an-.patch new file mode 100644 index 0000000..da664a3 --- /dev/null +++ b/1042-target-i386-sev-do-not-create-launch-context-for-an-.patch @@ -0,0 +1,48 @@ +From 36b08d0392f2baec061e6fb90416db42dfad20f7 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +Date: Tue, 27 Jul 2021 12:16:09 +0000 +Subject: [PATCH 05/29] target/i386: sev: do not create launch context for an + incoming guest + +cherry-picked from https://github.com/AMDESE/qemu/commit/b85694233495. + +The LAUNCH_START is used for creating an encryption context to encrypt +newly created guest, for an incoming guest the RECEIVE_START should be +used. + +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Brijesh Singh +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + target/i386/sev.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 5dd6c0a3f..fc8a2bb61 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -1024,10 +1024,16 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + } + } + +- ret = sev_launch_start(sev); +- if (ret) { +- error_setg(errp, "%s: failed to create encryption context", __func__); +- goto err; ++ /* ++ * The LAUNCH context is used for new guest, if its an incoming guest ++ * then RECEIVE context will be created after the connection is established. ++ */ ++ if (!runstate_check(RUN_STATE_INMIGRATE)) { ++ ret = sev_launch_start(sev); ++ if (ret) { ++ error_setg(errp, "%s: failed to create encryption context", __func__); ++ goto err; ++ } + } + + /* CSV guest needs no notifier to reg/unreg memory */ +-- +2.31.1 + diff --git a/1043-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch b/1043-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch new file mode 100644 index 0000000..f0a412a --- /dev/null +++ b/1043-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch @@ -0,0 +1,324 @@ +From 196380db46216f207e57b00e4bbc95178683d0cf Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +Date: Tue, 27 Jul 2021 12:55:25 +0000 +Subject: [PATCH 06/29] target/i386: sev: add support to encrypt the outgoing + page + +cherry-picked from https://github.com/AMDESE/qemu/commit/5187c6f86bd. + +The sev_save_outgoing_page() provide the implementation to encrypt the +guest private pages during the transit. The routines uses the SEND_START +command to create the outgoing encryption context on the first call then +uses the SEND_UPDATE_DATA command to encrypt the data before writing it +to the socket. While encrypting the data SEND_UPDATE_DATA produces some +metadata (e.g MAC, IV). The metadata is also sent to the target machine. +After migration is completed, we issue the SEND_FINISH command to transition +the SEV guest state from sending to unrunnable state. + +Signed-off-by: Brijesh Singh +Co-developed-by: Ashish Kalra +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + target/i386/sev.c | 221 +++++++++++++++++++++++++++++++++++++++ + target/i386/sev.h | 2 + + target/i386/trace-events | 3 + + 3 files changed, 226 insertions(+) + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index fc8a2bb61..622150106 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -31,6 +31,8 @@ + #include "sysemu/runstate.h" + #include "trace.h" + #include "migration/blocker.h" ++#include "migration/qemu-file.h" ++#include "migration/misc.h" + #include "qom/object.h" + #include "monitor/monitor.h" + #include "monitor/hmp-target.h" +@@ -82,6 +84,8 @@ struct SevGuestState { + size_t remote_plat_cert_len; + guchar *amd_cert; + size_t amd_cert_len; ++ gchar *send_packet_hdr; ++ size_t send_packet_hdr_len; + + uint32_t reset_cs; + uint32_t reset_ip; +@@ -170,6 +174,7 @@ static const char *const sev_fw_errlist[] = { + + static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { + .save_setup = sev_save_setup, ++ .save_outgoing_page = sev_save_outgoing_page, + }; + + static int +@@ -926,6 +931,40 @@ error: + return 1; + } + ++static void ++sev_send_finish(void) ++{ ++ int ret, error; ++ ++ trace_kvm_sev_send_finish(); ++ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_FINISH, 0, &error); ++ if (ret) { ++ error_report("%s: SEND_FINISH ret=%d fw_error=%d '%s'", ++ __func__, ret, error, fw_error_to_str(error)); ++ } ++ ++ g_free(sev_guest->send_packet_hdr); ++ sev_set_guest_state(sev_guest, SEV_STATE_RUNNING); ++} ++ ++static void ++sev_migration_state_notifier(Notifier *notifier, void *data) ++{ ++ MigrationState *s = data; ++ ++ if (migration_has_finished(s) || ++ migration_in_postcopy_after_devices(s) || ++ migration_has_failed(s)) { ++ if (sev_check_state(sev_guest, SEV_STATE_SEND_UPDATE)) { ++ sev_send_finish(); ++ } ++ } ++} ++ ++static Notifier sev_migration_state_notify = { ++ .notify = sev_migration_state_notifier, ++}; ++ + int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + { + SevGuestState *sev +@@ -1042,6 +1081,7 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + } + qemu_add_machine_init_done_notifier(&sev_machine_done_notify); + qemu_add_vm_change_state_handler(sev_vm_state_change, sev); ++ add_migration_state_change_notifier(&sev_migration_state_notify); + + cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; + +@@ -1283,6 +1323,187 @@ int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size) + return 0; + } + ++static int ++sev_get_send_session_length(void) ++{ ++ int ret, fw_err = 0; ++ struct kvm_sev_send_start start = {}; ++ ++ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_START, &start, &fw_err); ++ if (fw_err != SEV_RET_INVALID_LEN) { ++ ret = -1; ++ error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", ++ __func__, ret, fw_err, fw_error_to_str(fw_err)); ++ goto err; ++ } ++ ++ ret = start.session_len; ++err: ++ return ret; ++} ++ ++static int ++sev_send_start(SevGuestState *s, QEMUFile *f, uint64_t *bytes_sent) ++{ ++ gsize pdh_len = 0, plat_cert_len; ++ int session_len, ret, fw_error; ++ struct kvm_sev_send_start start = { }; ++ guchar *pdh = NULL, *plat_cert = NULL, *session = NULL; ++ Error *local_err = NULL; ++ ++ if (!s->remote_pdh || !s->remote_plat_cert || !s->amd_cert_len) { ++ error_report("%s: missing remote PDH or PLAT_CERT", __func__); ++ return 1; ++ } ++ ++ start.pdh_cert_uaddr = (uintptr_t) s->remote_pdh; ++ start.pdh_cert_len = s->remote_pdh_len; ++ ++ start.plat_certs_uaddr = (uintptr_t)s->remote_plat_cert; ++ start.plat_certs_len = s->remote_plat_cert_len; ++ ++ start.amd_certs_uaddr = (uintptr_t)s->amd_cert; ++ start.amd_certs_len = s->amd_cert_len; ++ ++ /* get the session length */ ++ session_len = sev_get_send_session_length(); ++ if (session_len < 0) { ++ ret = 1; ++ goto err; ++ } ++ ++ session = g_new0(guchar, session_len); ++ start.session_uaddr = (unsigned long)session; ++ start.session_len = session_len; ++ ++ /* Get our PDH certificate */ ++ ret = sev_get_pdh_info(s->sev_fd, &pdh, &pdh_len, ++ &plat_cert, &plat_cert_len, &local_err); ++ if (ret) { ++ error_report("Failed to get our PDH cert"); ++ goto err; ++ } ++ ++ trace_kvm_sev_send_start(start.pdh_cert_uaddr, start.pdh_cert_len, ++ start.plat_certs_uaddr, start.plat_certs_len, ++ start.amd_certs_uaddr, start.amd_certs_len); ++ ++ ret = sev_ioctl(s->sev_fd, KVM_SEV_SEND_START, &start, &fw_error); ++ if (ret < 0) { ++ error_report("%s: SEND_START ret=%d fw_error=%d '%s'", ++ __func__, ret, fw_error, fw_error_to_str(fw_error)); ++ goto err; ++ } ++ ++ qemu_put_be32(f, start.policy); ++ qemu_put_be32(f, pdh_len); ++ qemu_put_buffer(f, (uint8_t *)pdh, pdh_len); ++ qemu_put_be32(f, start.session_len); ++ qemu_put_buffer(f, (uint8_t *)start.session_uaddr, start.session_len); ++ *bytes_sent = 12 + pdh_len + start.session_len; ++ ++ sev_set_guest_state(s, SEV_STATE_SEND_UPDATE); ++ ++err: ++ g_free(pdh); ++ g_free(plat_cert); ++ return ret; ++} ++ ++static int ++sev_send_get_packet_len(int *fw_err) ++{ ++ int ret; ++ struct kvm_sev_send_update_data update = { 0, }; ++ ++ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_UPDATE_DATA, ++ &update, fw_err); ++ if (*fw_err != SEV_RET_INVALID_LEN) { ++ ret = -1; ++ error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", ++ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); ++ goto err; ++ } ++ ++ ret = update.hdr_len; ++ ++err: ++ return ret; ++} ++ ++static int ++sev_send_update_data(SevGuestState *s, QEMUFile *f, uint8_t *ptr, uint32_t size, ++ uint64_t *bytes_sent) ++{ ++ int ret, fw_error; ++ guchar *trans; ++ struct kvm_sev_send_update_data update = { }; ++ ++ /* ++ * If this is first call then query the packet header bytes and allocate ++ * the packet buffer. ++ */ ++ if (!s->send_packet_hdr) { ++ s->send_packet_hdr_len = sev_send_get_packet_len(&fw_error); ++ if (s->send_packet_hdr_len < 1) { ++ error_report("%s: SEND_UPDATE fw_error=%d '%s'", ++ __func__, fw_error, fw_error_to_str(fw_error)); ++ return 1; ++ } ++ ++ s->send_packet_hdr = g_new(gchar, s->send_packet_hdr_len); ++ } ++ ++ /* allocate transport buffer */ ++ trans = g_new(guchar, size); ++ ++ update.hdr_uaddr = (uintptr_t)s->send_packet_hdr; ++ update.hdr_len = s->send_packet_hdr_len; ++ update.guest_uaddr = (uintptr_t)ptr; ++ update.guest_len = size; ++ update.trans_uaddr = (uintptr_t)trans; ++ update.trans_len = size; ++ ++ trace_kvm_sev_send_update_data(ptr, trans, size); ++ ++ ret = sev_ioctl(s->sev_fd, KVM_SEV_SEND_UPDATE_DATA, &update, &fw_error); ++ if (ret) { ++ error_report("%s: SEND_UPDATE_DATA ret=%d fw_error=%d '%s'", ++ __func__, ret, fw_error, fw_error_to_str(fw_error)); ++ goto err; ++ } ++ ++ qemu_put_be32(f, update.hdr_len); ++ qemu_put_buffer(f, (uint8_t *)update.hdr_uaddr, update.hdr_len); ++ *bytes_sent = 4 + update.hdr_len; ++ ++ qemu_put_be32(f, update.trans_len); ++ qemu_put_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); ++ *bytes_sent += (4 + update.trans_len); ++ ++err: ++ g_free(trans); ++ return ret; ++} ++ ++int sev_save_outgoing_page(QEMUFile *f, uint8_t *ptr, ++ uint32_t sz, uint64_t *bytes_sent) ++{ ++ SevGuestState *s = sev_guest; ++ ++ /* ++ * If this is a first buffer then create outgoing encryption context ++ * and write our PDH, policy and session data. ++ */ ++ if (!sev_check_state(s, SEV_STATE_SEND_UPDATE) && ++ sev_send_start(s, f, bytes_sent)) { ++ error_report("Failed to create outgoing context"); ++ return 1; ++ } ++ ++ return sev_send_update_data(s, f, ptr, sz, bytes_sent); ++} ++ + static const QemuUUID sev_hash_table_header_guid = { + .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, + 0xd4, 0x11, 0xfd, 0x21) +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 14801ec44..19d3136dd 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -53,6 +53,8 @@ extern bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **er + int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp); + int sev_save_setup(const char *pdh, const char *plat_cert, + const char *amd_cert); ++int sev_save_outgoing_page(QEMUFile *f, uint8_t *ptr, ++ uint32_t size, uint64_t *bytes_sent); + int sev_inject_launch_secret(const char *hdr, const char *secret, + uint64_t gpa, Error **errp); + +diff --git a/target/i386/trace-events b/target/i386/trace-events +index b7da9bd74..c165e3737 100644 +--- a/target/i386/trace-events ++++ b/target/i386/trace-events +@@ -11,6 +11,9 @@ kvm_sev_launch_measurement(const char *value) "data %s" + kvm_sev_launch_finish(void) "" + kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d" + kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data %s" ++kvm_sev_send_start(uint64_t pdh, int l1, uint64_t plat, int l2, uint64_t amd, int l3) "pdh 0x%" PRIx64 " len %d plat 0x%" PRIx64 " len %d amd 0x%" PRIx64 " len %d" ++kvm_sev_send_update_data(void *src, void *dst, int len) "guest %p trans %p len %d" ++kvm_sev_send_finish(void) "" + + # csv.c + kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 +-- +2.31.1 + diff --git a/1044-target-i386-sev-add-support-to-load-incoming-encrypt.patch b/1044-target-i386-sev-add-support-to-load-incoming-encrypt.patch new file mode 100644 index 0000000..cf10880 --- /dev/null +++ b/1044-target-i386-sev-add-support-to-load-incoming-encrypt.patch @@ -0,0 +1,224 @@ +From 10e03772a0a14f65602c496d65a4392b5b70da51 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +Date: Tue, 27 Jul 2021 13:00:50 +0000 +Subject: [PATCH 07/29] target/i386: sev: add support to load incoming + encrypted page + +cherry-picked from https://github.com/AMDESE/qemu/commit/e86e5dccb045. + +The sev_load_incoming_page() provide the implementation to read the +incoming guest private pages from the socket and load it into the guest +memory. The routines uses the RECEIVE_START command to create the +incoming encryption context on the first call then uses the +RECEIEVE_UPDATE_DATA command to load the encrypted pages into the guest +memory. After migration is completed, we issue the RECEIVE_FINISH command +to transition the SEV guest to the runnable state so that it can be +executed. + +Signed-off-by: Brijesh Singh +Co-developed-by: Ashish Kalra +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + target/i386/sev.c | 137 ++++++++++++++++++++++++++++++++++++++- + target/i386/sev.h | 1 + + target/i386/trace-events | 3 + + 3 files changed, 140 insertions(+), 1 deletion(-) + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 622150106..bdd77fd0e 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -175,6 +175,7 @@ static const char *const sev_fw_errlist[] = { + static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { + .save_setup = sev_save_setup, + .save_outgoing_page = sev_save_outgoing_page, ++ .load_incoming_page = sev_load_incoming_page, + }; + + static int +@@ -877,13 +878,33 @@ sev_launch_finish(SevGuestState *sev) + migrate_add_blocker(sev_mig_blocker, &error_fatal); + } + ++static int ++sev_receive_finish(SevGuestState *s) ++{ ++ int error, ret = 1; ++ ++ trace_kvm_sev_receive_finish(); ++ ret = sev_ioctl(s->sev_fd, KVM_SEV_RECEIVE_FINISH, 0, &error); ++ if (ret) { ++ error_report("%s: RECEIVE_FINISH ret=%d fw_error=%d '%s'", ++ __func__, ret, error, fw_error_to_str(error)); ++ goto err; ++ } ++ ++ sev_set_guest_state(s, SEV_STATE_RUNNING); ++err: ++ return ret; ++} ++ + static void + sev_vm_state_change(void *opaque, bool running, RunState state) + { + SevGuestState *sev = opaque; + + if (running) { +- if (!sev_check_state(sev, SEV_STATE_RUNNING)) { ++ if (sev_check_state(sev, SEV_STATE_RECEIVE_UPDATE)) { ++ sev_receive_finish(sev); ++ } else if (!sev_check_state(sev, SEV_STATE_RUNNING)) { + sev_launch_finish(sev); + } + } +@@ -1504,6 +1525,120 @@ int sev_save_outgoing_page(QEMUFile *f, uint8_t *ptr, + return sev_send_update_data(s, f, ptr, sz, bytes_sent); + } + ++static int ++sev_receive_start(SevGuestState *sev, QEMUFile *f) ++{ ++ int ret = 1; ++ int fw_error; ++ struct kvm_sev_receive_start start = { }; ++ gchar *session = NULL, *pdh_cert = NULL; ++ ++ /* get SEV guest handle */ ++ start.handle = object_property_get_int(OBJECT(sev), "handle", ++ &error_abort); ++ ++ /* get the source policy */ ++ start.policy = qemu_get_be32(f); ++ ++ /* get source PDH key */ ++ start.pdh_len = qemu_get_be32(f); ++ if (!check_blob_length(start.pdh_len)) { ++ return 1; ++ } ++ ++ pdh_cert = g_new(gchar, start.pdh_len); ++ qemu_get_buffer(f, (uint8_t *)pdh_cert, start.pdh_len); ++ start.pdh_uaddr = (uintptr_t)pdh_cert; ++ ++ /* get source session data */ ++ start.session_len = qemu_get_be32(f); ++ if (!check_blob_length(start.session_len)) { ++ return 1; ++ } ++ session = g_new(gchar, start.session_len); ++ qemu_get_buffer(f, (uint8_t *)session, start.session_len); ++ start.session_uaddr = (uintptr_t)session; ++ ++ trace_kvm_sev_receive_start(start.policy, session, pdh_cert); ++ ++ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_RECEIVE_START, ++ &start, &fw_error); ++ if (ret < 0) { ++ error_report("Error RECEIVE_START ret=%d fw_error=%d '%s'", ++ ret, fw_error, fw_error_to_str(fw_error)); ++ goto err; ++ } ++ ++ object_property_set_int(OBJECT(sev), "handle", start.handle, &error_abort); ++ sev_set_guest_state(sev, SEV_STATE_RECEIVE_UPDATE); ++err: ++ g_free(session); ++ g_free(pdh_cert); ++ ++ return ret; ++} ++ ++static int sev_receive_update_data(QEMUFile *f, uint8_t *ptr) ++{ ++ int ret = 1, fw_error = 0; ++ gchar *hdr = NULL, *trans = NULL; ++ struct kvm_sev_receive_update_data update = {}; ++ ++ /* get packet header */ ++ update.hdr_len = qemu_get_be32(f); ++ if (!check_blob_length(update.hdr_len)) { ++ return 1; ++ } ++ ++ hdr = g_new(gchar, update.hdr_len); ++ qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len); ++ update.hdr_uaddr = (uintptr_t)hdr; ++ ++ /* get transport buffer */ ++ update.trans_len = qemu_get_be32(f); ++ if (!check_blob_length(update.trans_len)) { ++ goto err; ++ } ++ ++ trans = g_new(gchar, update.trans_len); ++ update.trans_uaddr = (uintptr_t)trans; ++ qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); ++ ++ update.guest_uaddr = (uintptr_t) ptr; ++ update.guest_len = update.trans_len; ++ ++ trace_kvm_sev_receive_update_data(trans, ptr, update.guest_len, ++ hdr, update.hdr_len); ++ ++ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_RECEIVE_UPDATE_DATA, ++ &update, &fw_error); ++ if (ret) { ++ error_report("Error RECEIVE_UPDATE_DATA ret=%d fw_error=%d '%s'", ++ ret, fw_error, fw_error_to_str(fw_error)); ++ goto err; ++ } ++err: ++ g_free(trans); ++ g_free(hdr); ++ return ret; ++} ++ ++int sev_load_incoming_page(QEMUFile *f, uint8_t *ptr) ++{ ++ SevGuestState *s = sev_guest; ++ ++ /* ++ * If this is first buffer and SEV is not in recieiving state then ++ * use RECEIVE_START command to create a encryption context. ++ */ ++ if (!sev_check_state(s, SEV_STATE_RECEIVE_UPDATE) && ++ sev_receive_start(s, f)) { ++ return 1; ++ } ++ ++ return sev_receive_update_data(f, ptr); ++} ++ + static const QemuUUID sev_hash_table_header_guid = { + .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, + 0xd4, 0x11, 0xfd, 0x21) +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 19d3136dd..1040b0cb2 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -55,6 +55,7 @@ int sev_save_setup(const char *pdh, const char *plat_cert, + const char *amd_cert); + int sev_save_outgoing_page(QEMUFile *f, uint8_t *ptr, + uint32_t size, uint64_t *bytes_sent); ++int sev_load_incoming_page(QEMUFile *f, uint8_t *ptr); + int sev_inject_launch_secret(const char *hdr, const char *secret, + uint64_t gpa, Error **errp); + +diff --git a/target/i386/trace-events b/target/i386/trace-events +index c165e3737..e32b0319b 100644 +--- a/target/i386/trace-events ++++ b/target/i386/trace-events +@@ -14,6 +14,9 @@ kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data + kvm_sev_send_start(uint64_t pdh, int l1, uint64_t plat, int l2, uint64_t amd, int l3) "pdh 0x%" PRIx64 " len %d plat 0x%" PRIx64 " len %d amd 0x%" PRIx64 " len %d" + kvm_sev_send_update_data(void *src, void *dst, int len) "guest %p trans %p len %d" + kvm_sev_send_finish(void) "" ++kvm_sev_receive_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p" ++kvm_sev_receive_update_data(void *src, void *dst, int len, void *hdr, int hdr_len) "guest %p trans %p len %d hdr %p hdr_len %d" ++kvm_sev_receive_finish(void) "" + + # csv.c + kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 +-- +2.31.1 + diff --git a/1045-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch b/1045-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch new file mode 100644 index 0000000..27daa6b --- /dev/null +++ b/1045-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch @@ -0,0 +1,293 @@ +From da756577d513a92fdfd4c1bdda3961dc704ccf12 Mon Sep 17 00:00:00 2001 +From: Ashish Kalra +Date: Tue, 27 Jul 2021 15:05:49 +0000 +Subject: [PATCH 08/29] kvm: Add support for SEV shared regions list and + KVM_EXIT_HYPERCALL. + +cherry-picked from https://github.com/AMDESE/qemu/commit/fcbbd9b19ac. + +KVM_HC_MAP_GPA_RANGE hypercall is used by the SEV guest to notify a +change in the page encryption status to the hypervisor. The hypercall +should be invoked only when the encryption attribute is changed from +encrypted -> decrypted and vice versa. By default all guest pages are +considered encrypted. + +The hypercall exits to userspace with KVM_EXIT_HYPERCALL exit code, +currently this is used only by SEV guests for guest page encryptiion +status tracking. Add support to handle this exit and invoke SEV +shared regions list handlers. + +Add support for SEV guest shared regions and implementation of the +SEV shared regions list. + +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + linux-headers/linux/kvm.h | 3 ++ + target/i386/kvm/kvm.c | 48 +++++++++++++++++ + target/i386/sev.c | 105 ++++++++++++++++++++++++++++++++++++++ + target/i386/sev.h | 3 ++ + 4 files changed, 159 insertions(+) + +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 3bc062a18..b640e72c8 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -344,6 +344,7 @@ struct kvm_run { + } mmio; + /* KVM_EXIT_HYPERCALL */ + struct { ++#define KVM_HC_MAP_GPA_RANGE 12 + __u64 nr; + __u64 args[6]; + __u64 ret; +@@ -1154,6 +1155,8 @@ struct kvm_ppc_resize_hpt { + #define KVM_CAP_S390_ZPCI_OP 221 + #define KVM_CAP_S390_CPU_TOPOLOGY 222 + ++#define KVM_EXIT_HYPERCALL_VALID_MASK (1 << KVM_HC_MAP_GPA_RANGE) ++ + #ifdef KVM_CAP_IRQ_ROUTING + + struct kvm_irq_routing_irqchip { +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index a06221d3e..5262806c4 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -127,6 +127,7 @@ static int has_xsave2; + static int has_xcrs; + static int has_pit_state2; + static int has_exception_payload; ++static int has_map_gpa_range; + + static bool has_msr_mcg_ext_ctl; + +@@ -2052,6 +2053,17 @@ int kvm_arch_init_vcpu(CPUState *cs) + c->eax = MAX(c->eax, KVM_CPUID_SIGNATURE | 0x10); + } + ++ if (sev_enabled()) { ++ c = cpuid_find_entry(&cpuid_data.cpuid, ++ KVM_CPUID_FEATURES | kvm_base, 0); ++ if (c) { ++ c->eax |= (1 << KVM_FEATURE_MIGRATION_CONTROL); ++ if (has_map_gpa_range) { ++ c->eax |= (1 << KVM_FEATURE_HC_MAP_GPA_RANGE); ++ } ++ } ++ } ++ + cpuid_data.cpuid.nent = cpuid_i; + + cpuid_data.cpuid.padding = 0; +@@ -2397,6 +2409,17 @@ int kvm_arch_init(MachineState *ms, KVMState *s) + } + } + ++ has_map_gpa_range = kvm_check_extension(s, KVM_CAP_EXIT_HYPERCALL); ++ if (has_map_gpa_range) { ++ ret = kvm_vm_enable_cap(s, KVM_CAP_EXIT_HYPERCALL, 0, ++ KVM_EXIT_HYPERCALL_VALID_MASK); ++ if (ret < 0) { ++ error_report("kvm: Failed to enable MAP_GPA_RANGE cap: %s", ++ strerror(-ret)); ++ return ret; ++ } ++ } ++ + ret = kvm_get_supported_msrs(s); + if (ret < 0) { + return ret; +@@ -4612,6 +4635,28 @@ static int kvm_handle_tpr_access(X86CPU *cpu) + return 1; + } + ++static int kvm_handle_exit_hypercall(X86CPU *cpu, struct kvm_run *run) ++{ ++ /* ++ * Currently this exit is only used by SEV guests for ++ * guest page encryption status tracking. ++ */ ++ if (run->hypercall.nr == KVM_HC_MAP_GPA_RANGE) { ++ unsigned long enc = run->hypercall.args[2]; ++ unsigned long gpa = run->hypercall.args[0]; ++ unsigned long npages = run->hypercall.args[1]; ++ unsigned long gfn_start = gpa >> TARGET_PAGE_BITS; ++ unsigned long gfn_end = gfn_start + npages; ++ ++ if (enc) { ++ sev_remove_shared_regions_list(gfn_start, gfn_end); ++ } else { ++ sev_add_shared_regions_list(gfn_start, gfn_end); ++ } ++ } ++ return 0; ++} ++ + int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) + { + static const uint8_t int3 = 0xcc; +@@ -4902,6 +4947,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) + /* already handled in kvm_arch_post_run */ + ret = 0; + break; ++ case KVM_EXIT_HYPERCALL: ++ ret = kvm_handle_exit_hypercall(cpu, run); ++ break; + default: + fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); + ret = -1; +diff --git a/target/i386/sev.c b/target/i386/sev.c +index bdd77fd0e..de57b0a27 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -45,6 +45,10 @@ + #define TYPE_SEV_GUEST "sev-guest" + OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST) + ++struct shared_region { ++ unsigned long gfn_start, gfn_end; ++ QTAILQ_ENTRY(shared_region) list; ++}; + + extern struct sev_ops sev_ops; + +@@ -90,6 +94,8 @@ struct SevGuestState { + uint32_t reset_cs; + uint32_t reset_ip; + bool reset_data_valid; ++ ++ QTAILQ_HEAD(, shared_region) shared_regions_list; + }; + + #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */ +@@ -1105,6 +1111,7 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + add_migration_state_change_notifier(&sev_migration_state_notify); + + cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; ++ QTAILQ_INIT(&sev->shared_regions_list); + + cgs->ready = true; + +@@ -1639,6 +1646,104 @@ int sev_load_incoming_page(QEMUFile *f, uint8_t *ptr) + return sev_receive_update_data(f, ptr); + } + ++int sev_remove_shared_regions_list(unsigned long start, unsigned long end) ++{ ++ SevGuestState *s = sev_guest; ++ struct shared_region *pos; ++ ++ QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { ++ unsigned long l, r; ++ unsigned long curr_gfn_end = pos->gfn_end; ++ ++ /* ++ * Find if any intersection exists ? ++ * left bound for intersecting segment ++ */ ++ l = MAX(start, pos->gfn_start); ++ /* right bound for intersecting segment */ ++ r = MIN(end, pos->gfn_end); ++ if (l <= r) { ++ if (pos->gfn_start == l && pos->gfn_end == r) { ++ QTAILQ_REMOVE(&s->shared_regions_list, pos, list); ++ } else if (l == pos->gfn_start) { ++ pos->gfn_start = r; ++ } else if (r == pos->gfn_end) { ++ pos->gfn_end = l; ++ } else { ++ /* Do a de-merge -- split linked list nodes */ ++ struct shared_region *shrd_region; ++ ++ pos->gfn_end = l; ++ shrd_region = g_malloc0(sizeof(*shrd_region)); ++ if (!shrd_region) { ++ return 0; ++ } ++ shrd_region->gfn_start = r; ++ shrd_region->gfn_end = curr_gfn_end; ++ QTAILQ_INSERT_AFTER(&s->shared_regions_list, pos, ++ shrd_region, list); ++ } ++ } ++ if (end <= curr_gfn_end) { ++ break; ++ } ++ } ++ return 0; ++} ++ ++int sev_add_shared_regions_list(unsigned long start, unsigned long end) ++{ ++ struct shared_region *shrd_region; ++ struct shared_region *pos; ++ SevGuestState *s = sev_guest; ++ ++ if (QTAILQ_EMPTY(&s->shared_regions_list)) { ++ shrd_region = g_malloc0(sizeof(*shrd_region)); ++ if (!shrd_region) { ++ return -1; ++ } ++ shrd_region->gfn_start = start; ++ shrd_region->gfn_end = end; ++ QTAILQ_INSERT_TAIL(&s->shared_regions_list, shrd_region, list); ++ return 0; ++ } ++ ++ /* ++ * shared regions list is a sorted list in ascending order ++ * of guest PA's and also merges consecutive range of guest PA's ++ */ ++ QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { ++ /* handle duplicate overlapping regions */ ++ if (start >= pos->gfn_start && end <= pos->gfn_end) { ++ return 0; ++ } ++ if (pos->gfn_end < start) { ++ continue; ++ } ++ /* merge consecutive guest PA(s) -- forward merge */ ++ if (pos->gfn_start <= start && pos->gfn_end >= start) { ++ pos->gfn_end = end; ++ return 0; ++ } ++ break; ++ } ++ /* ++ * Add a new node ++ */ ++ shrd_region = g_malloc0(sizeof(*shrd_region)); ++ if (!shrd_region) { ++ return -1; ++ } ++ shrd_region->gfn_start = start; ++ shrd_region->gfn_end = end; ++ if (pos) { ++ QTAILQ_INSERT_BEFORE(pos, shrd_region, list); ++ } else { ++ QTAILQ_INSERT_TAIL(&s->shared_regions_list, shrd_region, list); ++ } ++ return 1; ++} ++ + static const QemuUUID sev_hash_table_header_guid = { + .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, + 0xd4, 0x11, 0xfd, 0x21) +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 1040b0cb2..8423b5522 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -61,6 +61,9 @@ int sev_inject_launch_secret(const char *hdr, const char *secret, + + int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size); + void sev_es_set_reset_vector(CPUState *cpu); ++int sev_remove_shared_regions_list(unsigned long gfn_start, ++ unsigned long gfn_end); ++int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end); + + int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); + +-- +2.31.1 + diff --git a/1046-migration-add-support-to-migrate-shared-regions-list.patch b/1046-migration-add-support-to-migrate-shared-regions-list.patch new file mode 100644 index 0000000..72e8cbe --- /dev/null +++ b/1046-migration-add-support-to-migrate-shared-regions-list.patch @@ -0,0 +1,103 @@ +From 9f9b6fbfc4cf9f73a001686954d34c40b29e3538 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +Date: Tue, 27 Jul 2021 16:31:36 +0000 +Subject: [PATCH 09/29] migration: add support to migrate shared regions list + +cherry-picked from https://github.com/AMDESE/qemu/commit/9236f522e48b6. + +When memory encryption is enabled, the hypervisor maintains a shared +regions list which is referred by hypervisor during migration to check +if page is private or shared. This list is built during the VM bootup and +must be migrated to the target host so that hypervisor on target host can +use it for future migration. + +Signed-off-by: Brijesh Singh +Co-developed-by: Ashish Kalra +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + target/i386/sev.c | 43 +++++++++++++++++++++++++++++++++++++++++++ + target/i386/sev.h | 2 ++ + 2 files changed, 45 insertions(+) + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index de57b0a27..30cd436ab 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -178,10 +178,15 @@ static const char *const sev_fw_errlist[] = { + + #define SEV_FW_BLOB_MAX_SIZE 0x4000 /* 16KB */ + ++#define SHARED_REGION_LIST_CONT 0x1 ++#define SHARED_REGION_LIST_END 0x2 ++ + static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { + .save_setup = sev_save_setup, + .save_outgoing_page = sev_save_outgoing_page, + .load_incoming_page = sev_load_incoming_page, ++ .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, ++ .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, + }; + + static int +@@ -1744,6 +1749,44 @@ int sev_add_shared_regions_list(unsigned long start, unsigned long end) + return 1; + } + ++int sev_save_outgoing_shared_regions_list(QEMUFile *f) ++{ ++ SevGuestState *s = sev_guest; ++ struct shared_region *pos; ++ ++ QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { ++ qemu_put_be32(f, SHARED_REGION_LIST_CONT); ++ qemu_put_be32(f, pos->gfn_start); ++ qemu_put_be32(f, pos->gfn_end); ++ } ++ ++ qemu_put_be32(f, SHARED_REGION_LIST_END); ++ return 0; ++} ++ ++int sev_load_incoming_shared_regions_list(QEMUFile *f) ++{ ++ SevGuestState *s = sev_guest; ++ struct shared_region *shrd_region; ++ int status; ++ ++ status = qemu_get_be32(f); ++ while (status == SHARED_REGION_LIST_CONT) { ++ ++ shrd_region = g_malloc0(sizeof(*shrd_region)); ++ if (!shrd_region) { ++ return 0; ++ } ++ shrd_region->gfn_start = qemu_get_be32(f); ++ shrd_region->gfn_end = qemu_get_be32(f); ++ ++ QTAILQ_INSERT_TAIL(&s->shared_regions_list, shrd_region, list); ++ ++ status = qemu_get_be32(f); ++ } ++ return 0; ++} ++ + static const QemuUUID sev_hash_table_header_guid = { + .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, + 0xd4, 0x11, 0xfd, 0x21) +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 8423b5522..34814b9f2 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -64,6 +64,8 @@ void sev_es_set_reset_vector(CPUState *cpu); + int sev_remove_shared_regions_list(unsigned long gfn_start, + unsigned long gfn_end); + int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end); ++int sev_save_outgoing_shared_regions_list(QEMUFile *f); ++int sev_load_incoming_shared_regions_list(QEMUFile *f); + + int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); + +-- +2.31.1 + diff --git a/1047-migration-ram-add-support-to-send-encrypted-pages.patch b/1047-migration-ram-add-support-to-send-encrypted-pages.patch new file mode 100644 index 0000000..42223d6 --- /dev/null +++ b/1047-migration-ram-add-support-to-send-encrypted-pages.patch @@ -0,0 +1,338 @@ +From a973e7ee1489c9ee089f8c502f9b10f5ca4a4772 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +Date: Tue, 27 Jul 2021 16:53:19 +0000 +Subject: [PATCH 10/29] migration/ram: add support to send encrypted pages + +cherry-picked from https://github.com/AMDESE/qemu/commit/2d6bda0d4cf. + +When memory encryption is enabled, the guest memory will be encrypted with +the guest specific key. The patch introduces RAM_SAVE_FLAG_ENCRYPTED_PAGE +flag to distinguish the encrypted data from plaintext. Encrypted pages +may need special handling. The sev_save_outgoing_page() is used +by the sender to write the encrypted pages onto the socket, similarly the +sev_load_incoming_page() is used by the target to read the +encrypted pages from the socket and load into the guest memory. + +Signed-off-by: Brijesh Singh +Co-developed-by: Ashish Kalra +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + migration/migration.h | 2 + + migration/ram.c | 163 +++++++++++++++++++++++++++++++++++++++++- + target/i386/sev.c | 14 ++++ + target/i386/sev.h | 4 ++ + 4 files changed, 182 insertions(+), 1 deletion(-) + +diff --git a/migration/migration.h b/migration/migration.h +index 0ae213332..596668d80 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -403,4 +403,6 @@ void migration_cancel(const Error *error); + + void populate_vfio_info(MigrationInfo *info); + ++bool memcrypt_enabled(void); ++ + #endif +diff --git a/migration/ram.c b/migration/ram.c +index 93cdb456a..57f2c01bf 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -55,6 +55,10 @@ + #include "qemu/iov.h" + #include "multifd.h" + #include "sysemu/runstate.h" ++#include "exec/confidential-guest-support.h" ++ ++/* Defines RAM_SAVE_ENCRYPTED_PAGE and RAM_SAVE_SHARED_REGION_LIST */ ++#include "target/i386/sev.h" + + #include "hw/boards.h" /* for machine_dump_guest_core() */ + +@@ -80,6 +84,16 @@ + #define RAM_SAVE_FLAG_XBZRLE 0x40 + /* 0x80 is reserved in migration.h start with 0x100 next */ + #define RAM_SAVE_FLAG_COMPRESS_PAGE 0x100 ++#define RAM_SAVE_FLAG_ENCRYPTED_DATA 0x200 ++ ++bool memcrypt_enabled(void) ++{ ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ if(ms->cgs) ++ return ms->cgs->ready; ++ else ++ return false; ++} + + static inline bool is_zero_range(uint8_t *p, uint64_t size) + { +@@ -468,6 +482,8 @@ static QemuCond decomp_done_cond; + + static bool do_compress_ram_page(QEMUFile *f, z_stream *stream, RAMBlock *block, + ram_addr_t offset, uint8_t *source_buf); ++static int ram_save_encrypted_page(RAMState *rs, PageSearchStatus *pss, ++ bool last_stage); + + static void *do_data_compress(void *opaque) + { +@@ -1301,6 +1317,80 @@ static int save_normal_page(RAMState *rs, RAMBlock *block, ram_addr_t offset, + return 1; + } + ++/** ++ * ram_save_encrypted_page - send the given encrypted page to the stream ++ */ ++static int ram_save_encrypted_page(RAMState *rs, PageSearchStatus *pss, ++ bool last_stage) ++{ ++ int ret; ++ uint8_t *p; ++ RAMBlock *block = pss->block; ++ ram_addr_t offset = pss->page << TARGET_PAGE_BITS; ++ uint64_t bytes_xmit; ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ ConfidentialGuestSupportClass *cgs_class = ++ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); ++ struct ConfidentialGuestMemoryEncryptionOps *ops = ++ cgs_class->memory_encryption_ops; ++ ++ p = block->host + offset; ++ ++ ram_counters.transferred += ++ save_page_header(rs, rs->f, block, ++ offset | RAM_SAVE_FLAG_ENCRYPTED_DATA); ++ ++ qemu_put_be32(rs->f, RAM_SAVE_ENCRYPTED_PAGE); ++ ret = ops->save_outgoing_page(rs->f, p, TARGET_PAGE_SIZE, &bytes_xmit); ++ if (ret) { ++ return -1; ++ } ++ ++ ram_counters.transferred += bytes_xmit; ++ ram_counters.normal++; ++ ++ return 1; ++} ++ ++/** ++ * ram_save_shared_region_list: send the shared region list ++ */ ++static int ram_save_shared_region_list(RAMState *rs, QEMUFile *f) ++{ ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ ConfidentialGuestSupportClass *cgs_class = ++ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); ++ struct ConfidentialGuestMemoryEncryptionOps *ops = ++ cgs_class->memory_encryption_ops; ++ ++ save_page_header(rs, rs->f, rs->last_seen_block, ++ RAM_SAVE_FLAG_ENCRYPTED_DATA); ++ qemu_put_be32(rs->f, RAM_SAVE_SHARED_REGIONS_LIST); ++ return ops->save_outgoing_shared_regions_list(rs->f); ++} ++ ++static int load_encrypted_data(QEMUFile *f, uint8_t *ptr) ++{ ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ ConfidentialGuestSupportClass *cgs_class = ++ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); ++ struct ConfidentialGuestMemoryEncryptionOps *ops = ++ cgs_class->memory_encryption_ops; ++ ++ int flag; ++ ++ flag = qemu_get_be32(f); ++ ++ if (flag == RAM_SAVE_ENCRYPTED_PAGE) { ++ return ops->load_incoming_page(f, ptr); ++ } else if (flag == RAM_SAVE_SHARED_REGIONS_LIST) { ++ return ops->load_incoming_shared_regions_list(f); ++ } else { ++ error_report("unknown encrypted flag %x", flag); ++ return 1; ++ } ++} ++ + /** + * ram_save_page: send the given page to the stream + * +@@ -2144,6 +2234,35 @@ static bool save_compress_page(RAMState *rs, RAMBlock *block, ram_addr_t offset) + return false; + } + ++/** ++ * encrypted_test_list: check if the page is encrypted ++ * ++ * Returns a bool indicating whether the page is encrypted. ++ */ ++static bool encrypted_test_list(RAMState *rs, RAMBlock *block, ++ unsigned long page) ++{ ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ ConfidentialGuestSupportClass *cgs_class = ++ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); ++ struct ConfidentialGuestMemoryEncryptionOps *ops = ++ cgs_class->memory_encryption_ops; ++ unsigned long gfn; ++ ++ /* ROM devices contains the unencrypted data */ ++ if (memory_region_is_rom(block->mr)) { ++ return false; ++ } ++ ++ /* ++ * Translate page in ram_addr_t address space to GPA address ++ * space using memory region. ++ */ ++ gfn = page + (block->mr->addr >> TARGET_PAGE_BITS); ++ ++ return ops->is_gfn_in_unshared_region(gfn); ++} ++ + /** + * ram_save_target_page: save one target page + * +@@ -2164,6 +2283,17 @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss, + return res; + } + ++ /* ++ * If memory encryption is enabled then use memory encryption APIs ++ * to write the outgoing buffer to the wire. The encryption APIs ++ * will take care of accessing the guest memory and re-encrypt it ++ * for the transport purposes. ++ */ ++ if (memcrypt_enabled() && ++ encrypted_test_list(rs, pss->block, pss->page)) { ++ return ram_save_encrypted_page(rs, pss, last_stage); ++ } ++ + if (save_compress_page(rs, block, offset)) { + return 1; + } +@@ -2990,6 +3120,18 @@ void qemu_guest_free_page_hint(void *addr, size_t len) + } + } + ++static int ram_encrypted_save_setup(void) ++{ ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ ConfidentialGuestSupportClass *cgs_class = ++ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); ++ struct ConfidentialGuestMemoryEncryptionOps *ops = ++ cgs_class->memory_encryption_ops; ++ MigrationParameters *p = &migrate_get_current()->parameters; ++ ++ return ops->save_setup(p->sev_pdh, p->sev_plat_cert, p->sev_amd_cert); ++} ++ + /* + * Each of ram_save_setup, ram_save_iterate and ram_save_complete has + * long-running RCU critical section. When rcu-reclaims in the code +@@ -3025,6 +3167,13 @@ static int ram_save_setup(QEMUFile *f, void *opaque) + (*rsp)->f = f; + + WITH_RCU_READ_LOCK_GUARD() { ++ ++ if (memcrypt_enabled()) { ++ if (ram_encrypted_save_setup()) { ++ return -1; ++ } ++ } ++ + qemu_put_be64(f, ram_bytes_total_common(true) | RAM_SAVE_FLAG_MEM_SIZE); + + RAMBLOCK_FOREACH_MIGRATABLE(block) { +@@ -3217,6 +3366,11 @@ static int ram_save_complete(QEMUFile *f, void *opaque) + + flush_compressed_data(rs); + ram_control_after_iterate(f, RAM_CONTROL_FINISH); ++ ++ /* send the shared regions list */ ++ if (memcrypt_enabled()) { ++ ret = ram_save_shared_region_list(rs, f); ++ } + } + + if (ret < 0) { +@@ -4038,7 +4192,8 @@ static int ram_load_precopy(QEMUFile *f) + } + + if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE | +- RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) { ++ RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE | ++ RAM_SAVE_FLAG_ENCRYPTED_DATA)) { + RAMBlock *block = ram_block_from_stream(f, flags); + + host = host_from_ram_block_offset(block, addr); +@@ -4167,6 +4322,12 @@ static int ram_load_precopy(QEMUFile *f) + break; + } + break; ++ case RAM_SAVE_FLAG_ENCRYPTED_DATA: ++ if (load_encrypted_data(f, host)) { ++ error_report("Failed to load encrypted data"); ++ ret = -EINVAL; ++ } ++ break; + case RAM_SAVE_FLAG_EOS: + /* normal exit */ + multifd_recv_sync_main(); +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 30cd436ab..cc63a1aef 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -185,6 +185,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { + .save_setup = sev_save_setup, + .save_outgoing_page = sev_save_outgoing_page, + .load_incoming_page = sev_load_incoming_page, ++ .is_gfn_in_unshared_region = sev_is_gfn_in_unshared_region, + .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, + .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, + }; +@@ -1787,6 +1788,19 @@ int sev_load_incoming_shared_regions_list(QEMUFile *f) + return 0; + } + ++bool sev_is_gfn_in_unshared_region(unsigned long gfn) ++{ ++ SevGuestState *s = sev_guest; ++ struct shared_region *pos; ++ ++ QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { ++ if (gfn >= pos->gfn_start && gfn < pos->gfn_end) { ++ return false; ++ } ++ } ++ return true; ++} ++ + static const QemuUUID sev_hash_table_header_guid = { + .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, + 0xd4, 0x11, 0xfd, 0x21) +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 34814b9f2..b8ad84014 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -38,6 +38,9 @@ typedef struct SevKernelLoaderContext { + size_t cmdline_size; + } SevKernelLoaderContext; + ++#define RAM_SAVE_ENCRYPTED_PAGE 0x1 ++#define RAM_SAVE_SHARED_REGIONS_LIST 0x2 ++ + #ifdef CONFIG_SEV + bool sev_enabled(void); + bool sev_es_enabled(void); +@@ -66,6 +69,7 @@ int sev_remove_shared_regions_list(unsigned long gfn_start, + int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end); + int sev_save_outgoing_shared_regions_list(QEMUFile *f); + int sev_load_incoming_shared_regions_list(QEMUFile *f); ++bool sev_is_gfn_in_unshared_region(unsigned long gfn); + + int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); + +-- +2.31.1 + diff --git a/1048-migration-ram-Force-encrypted-status-for-flash0-flas.patch b/1048-migration-ram-Force-encrypted-status-for-flash0-flas.patch new file mode 100644 index 0000000..8202afc --- /dev/null +++ b/1048-migration-ram-Force-encrypted-status-for-flash0-flas.patch @@ -0,0 +1,44 @@ +From aae5a6ae741a985ff74b0ae7540d3c6ce3ef2fd0 Mon Sep 17 00:00:00 2001 +From: Ashish Kalra +Date: Tue, 27 Jul 2021 18:05:25 +0000 +Subject: [PATCH 11/29] migration/ram: Force encrypted status for flash0 & + flash1 devices. + +cherry-picked from https://github.com/AMDESE/qemu/commit/803d6a4c8d. + +Currently OVMF clears the C-bit and marks NonExistent memory space +as decrypted in the page encryption bitmap. By marking the +NonExistent memory space as decrypted it gurantees any future MMIO adds +will work correctly, but this marks flash0 device space as decrypted. +At reset the SEV core will be in forced encrypted state, so this +decrypted marking of flash0 device space will cause VCPU reset to fail +as flash0 device pages will be migrated incorrectly. + +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + migration/ram.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/migration/ram.c b/migration/ram.c +index 57f2c01bf..da7a80994 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -2254,6 +2254,14 @@ static bool encrypted_test_list(RAMState *rs, RAMBlock *block, + return false; + } + ++ if (!strcmp(memory_region_name(block->mr), "system.flash0")) { ++ return true; ++ } ++ ++ if (!strcmp(memory_region_name(block->mr), "system.flash1")) { ++ return false; ++ } ++ + /* + * Translate page in ram_addr_t address space to GPA address + * space using memory region. +-- +2.31.1 + diff --git a/1049-migration-for-SEV-live-migration-bump-downtime-limit.patch b/1049-migration-for-SEV-live-migration-bump-downtime-limit.patch new file mode 100644 index 0000000..70e9213 --- /dev/null +++ b/1049-migration-for-SEV-live-migration-bump-downtime-limit.patch @@ -0,0 +1,64 @@ +From a102d449e9601125c226cf40bc57b705bd1e3c28 Mon Sep 17 00:00:00 2001 +From: Ashish Kalra +Date: Tue, 3 Aug 2021 16:06:27 +0000 +Subject: [PATCH 12/29] migration: for SEV live migration bump downtime limit + to 1s. + +cherry-picked from https://github.com/AMDESE/qemu/commit/b1468803a2200. + +Now, qemu has a default expected downtime of 300 ms and +SEV Live migration has a page-per-second bandwidth of 350-450 pages +( SEV Live migration being generally slow due to guest RAM pages +being migrated after encryption using the security processor ). +With this expected downtime of 300ms and 350-450 pps bandwith, +the threshold size = <1/3 of the PPS bandwidth = ~100 pages. + +Now, this threshold size is the maximum pages/bytes that can be +sent in the final completion phase of Live migration +(where the source VM is stopped) with the expected downtime. +Therefore, with the threshold size computed above, +the migration completion phase which halts the source VM +and then transfers the leftover dirty pages, +is only reached in SEV live migration case when # of dirty pages are ~100. + +The dirty-pages-rate with larger guest RAM configuration like 4G, 8G, etc. +is much higher, typically in the range of 300-400+ pages, hence, +we always remain in the "dirty-sync" phase of migration and never +reach the migration completion phase with above guest RAM configs. + +To summarize, with larger guest RAM configs, +the dirty-pages-rate > threshold_size (with the default qemu expected downtime of 300ms). + +So, the fix is to increase qemu's expected downtime. + +This is a tweakable parameter which can be set using "migrate_set_downtime". + +With a downtime of 1 second, we get a threshold size of ~350-450 pages, +which will handle the "dirty-pages-rate" of 300+ pages and complete +the migration process, so we bump the default downtime to 1s in case +of SEV live migration being active. + +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + migration/migration.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/migration/migration.c b/migration/migration.c +index 6810bcefc..27c875c6c 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -3663,6 +3663,10 @@ static void migration_update_counters(MigrationState *s, + transferred = current_bytes - s->iteration_initial_bytes; + time_spent = current_time - s->iteration_start_time; + bandwidth = (double)transferred / time_spent; ++ if (memcrypt_enabled() && ++ s->parameters.downtime_limit < 1000) { ++ s->parameters.downtime_limit = 1000; ++ } + s->threshold_size = bandwidth * s->parameters.downtime_limit; + + s->mbps = (((double) transferred * 8.0) / +-- +2.31.1 + diff --git a/1050-i386-kvm-Add-support-for-MSR-filtering.patch b/1050-i386-kvm-Add-support-for-MSR-filtering.patch new file mode 100644 index 0000000..c967cf5 --- /dev/null +++ b/1050-i386-kvm-Add-support-for-MSR-filtering.patch @@ -0,0 +1,201 @@ +From b45eabe2febd210065e964b6425f73f1d53af43e Mon Sep 17 00:00:00 2001 +From: Alexander Graf +Date: Wed, 5 Oct 2022 00:56:42 +0200 +Subject: [PATCH 13/29] i386: kvm: Add support for MSR filtering + +commit 860054d8ce4067ef2bc3deb2a98cf93350fc03e4 upstream. + +KVM has grown support to deflect arbitrary MSRs to user space since +Linux 5.10. For now we don't expect to make a lot of use of this +feature, so let's expose it the easiest way possible: With up to 16 +individually maskable MSRs. + +This patch adds a kvm_filter_msr() function that other code can call +to install a hook on KVM MSR reads or writes. + +Signed-off-by: Alexander Graf +Message-Id: <20221004225643.65036-3-agraf@csgraf.de> +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/kvm.c | 123 +++++++++++++++++++++++++++++++++++++ + target/i386/kvm/kvm_i386.h | 11 ++++ + 2 files changed, 134 insertions(+) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 5262806c4..607469fb3 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -135,6 +135,8 @@ static struct kvm_cpuid2 *cpuid_cache; + static struct kvm_cpuid2 *hv_cpuid_cache; + static struct kvm_msr_list *kvm_feature_msrs; + ++static KVMMSRHandlers msr_handlers[KVM_MSR_FILTER_MAX_RANGES]; ++ + #define BUS_LOCK_SLICE_TIME 1000000000ULL /* ns */ + static RateLimit bus_lock_ratelimit_ctrl; + +@@ -2524,6 +2526,15 @@ int kvm_arch_init(MachineState *ms, KVMState *s) + x86ms->bus_lock_ratelimit, BUS_LOCK_SLICE_TIME); + } + } ++ if (kvm_vm_check_extension(s, KVM_CAP_X86_USER_SPACE_MSR)) { ++ ret = kvm_vm_enable_cap(s, KVM_CAP_X86_USER_SPACE_MSR, 0, ++ KVM_MSR_EXIT_REASON_FILTER); ++ if (ret) { ++ error_report("Could not enable user space MSRs: %s", ++ strerror(-ret)); ++ exit(1); ++ } ++ } + + return 0; + } +@@ -4848,6 +4859,108 @@ void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg) + } + } + ++static bool kvm_install_msr_filters(KVMState *s) ++{ ++ uint64_t zero = 0; ++ struct kvm_msr_filter filter = { ++ .flags = KVM_MSR_FILTER_DEFAULT_ALLOW, ++ }; ++ int r, i, j = 0; ++ ++ for (i = 0; i < KVM_MSR_FILTER_MAX_RANGES; i++) { ++ KVMMSRHandlers *handler = &msr_handlers[i]; ++ if (handler->msr) { ++ struct kvm_msr_filter_range *range = &filter.ranges[j++]; ++ ++ *range = (struct kvm_msr_filter_range) { ++ .flags = 0, ++ .nmsrs = 1, ++ .base = handler->msr, ++ .bitmap = (__u8 *)&zero, ++ }; ++ ++ if (handler->rdmsr) { ++ range->flags |= KVM_MSR_FILTER_READ; ++ } ++ ++ if (handler->wrmsr) { ++ range->flags |= KVM_MSR_FILTER_WRITE; ++ } ++ } ++ } ++ ++ r = kvm_vm_ioctl(s, KVM_X86_SET_MSR_FILTER, &filter); ++ if (r) { ++ return false; ++ } ++ ++ return true; ++} ++ ++bool kvm_filter_msr(KVMState *s, uint32_t msr, QEMURDMSRHandler *rdmsr, ++ QEMUWRMSRHandler *wrmsr) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(msr_handlers); i++) { ++ if (!msr_handlers[i].msr) { ++ msr_handlers[i] = (KVMMSRHandlers) { ++ .msr = msr, ++ .rdmsr = rdmsr, ++ .wrmsr = wrmsr, ++ }; ++ ++ if (!kvm_install_msr_filters(s)) { ++ msr_handlers[i] = (KVMMSRHandlers) { }; ++ return false; ++ } ++ ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++static int kvm_handle_rdmsr(X86CPU *cpu, struct kvm_run *run) ++{ ++ int i; ++ bool r; ++ ++ for (i = 0; i < ARRAY_SIZE(msr_handlers); i++) { ++ KVMMSRHandlers *handler = &msr_handlers[i]; ++ if (run->msr.index == handler->msr) { ++ if (handler->rdmsr) { ++ r = handler->rdmsr(cpu, handler->msr, ++ (uint64_t *)&run->msr.data); ++ run->msr.error = r ? 0 : 1; ++ return 0; ++ } ++ } ++ } ++ ++ assert(false); ++} ++ ++static int kvm_handle_wrmsr(X86CPU *cpu, struct kvm_run *run) ++{ ++ int i; ++ bool r; ++ ++ for (i = 0; i < ARRAY_SIZE(msr_handlers); i++) { ++ KVMMSRHandlers *handler = &msr_handlers[i]; ++ if (run->msr.index == handler->msr) { ++ if (handler->wrmsr) { ++ r = handler->wrmsr(cpu, handler->msr, run->msr.data); ++ run->msr.error = r ? 0 : 1; ++ return 0; ++ } ++ } ++ } ++ ++ assert(false); ++} ++ + static bool has_sgx_provisioning; + + static bool __kvm_enable_sgx_provisioning(KVMState *s) +@@ -4947,6 +5060,16 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) + /* already handled in kvm_arch_post_run */ + ret = 0; + break; ++ case KVM_EXIT_X86_RDMSR: ++ /* We only enable MSR filtering, any other exit is bogus */ ++ assert(run->msr.reason == KVM_MSR_EXIT_REASON_FILTER); ++ ret = kvm_handle_rdmsr(cpu, run); ++ break; ++ case KVM_EXIT_X86_WRMSR: ++ /* We only enable MSR filtering, any other exit is bogus */ ++ assert(run->msr.reason == KVM_MSR_EXIT_REASON_FILTER); ++ ret = kvm_handle_wrmsr(cpu, run); ++ break; + case KVM_EXIT_HYPERCALL: + ret = kvm_handle_exit_hypercall(cpu, run); + break; +diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h +index 4124912c2..2ed586c11 100644 +--- a/target/i386/kvm/kvm_i386.h ++++ b/target/i386/kvm/kvm_i386.h +@@ -54,4 +54,15 @@ uint64_t kvm_swizzle_msi_ext_dest_id(uint64_t address); + bool kvm_enable_sgx_provisioning(KVMState *s); + void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask); + ++typedef bool QEMURDMSRHandler(X86CPU *cpu, uint32_t msr, uint64_t *val); ++typedef bool QEMUWRMSRHandler(X86CPU *cpu, uint32_t msr, uint64_t val); ++typedef struct kvm_msr_handlers { ++ uint32_t msr; ++ QEMURDMSRHandler *rdmsr; ++ QEMUWRMSRHandler *wrmsr; ++} KVMMSRHandlers; ++ ++bool kvm_filter_msr(KVMState *s, uint32_t msr, QEMURDMSRHandler *rdmsr, ++ QEMUWRMSRHandler *wrmsr); ++ + #endif +-- +2.31.1 + diff --git a/1051-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch b/1051-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch new file mode 100644 index 0000000..998be40 --- /dev/null +++ b/1051-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch @@ -0,0 +1,118 @@ +From f2f9d5860a3a32431b397f4a643de16423b5e4b3 Mon Sep 17 00:00:00 2001 +From: Ashish Kalra +Date: Tue, 27 Jul 2021 17:59:33 +0000 +Subject: [PATCH 14/29] kvm: Add support for userspace MSR filtering and + handling of MSR_KVM_MIGRATION_CONTROL. + +cherry-picked from https://github.com/AMDESE/qemu/commit/67935c3fd5f. + +Add support for userspace MSR filtering using KVM_X86_SET_MSR_FILTER +ioctl and handling of MSRs in userspace. Currently this is only used +for SEV guests which use MSR_KVM_MIGRATION_CONTROL to indicate if the +guest is enabled and ready for migration. + +KVM arch code calls into SEV guest specific code to delete the +SEV migrate blocker which has been setup at SEV_LAUNCH_FINISH. + +Signed-off-by: Ashish Kalra +Signed-off-by: hanliyang +--- + target/i386/kvm/kvm.c | 37 +++++++++++++++++++++++++++++++++++++ + target/i386/sev.c | 6 ++++++ + target/i386/sev.h | 1 + + 3 files changed, 44 insertions(+) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 607469fb3..a833219d0 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -2330,6 +2330,32 @@ static int kvm_get_supported_msrs(KVMState *s) + return ret; + } + ++/* ++ * Currently this exit is only used by SEV guests for ++ * MSR_KVM_MIGRATION_CONTROL to indicate if the guest ++ * is ready for migration. ++ */ ++static uint64_t msr_kvm_migration_control; ++ ++static bool kvm_rdmsr_kvm_migration_control(X86CPU *cpu, uint32_t msr, ++ uint64_t *val) ++{ ++ *val = msr_kvm_migration_control; ++ ++ return true; ++} ++ ++static bool kvm_wrmsr_kvm_migration_control(X86CPU *cpu, uint32_t msr, ++ uint64_t val) ++{ ++ msr_kvm_migration_control = val; ++ ++ if (val == KVM_MIGRATION_READY) ++ sev_del_migrate_blocker(); ++ ++ return true; ++} ++ + static Notifier smram_machine_done; + static KVMMemoryListener smram_listener; + static AddressSpace smram_address_space; +@@ -2527,6 +2553,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s) + } + } + if (kvm_vm_check_extension(s, KVM_CAP_X86_USER_SPACE_MSR)) { ++ bool r; ++ + ret = kvm_vm_enable_cap(s, KVM_CAP_X86_USER_SPACE_MSR, 0, + KVM_MSR_EXIT_REASON_FILTER); + if (ret) { +@@ -2534,6 +2562,15 @@ int kvm_arch_init(MachineState *ms, KVMState *s) + strerror(-ret)); + exit(1); + } ++ ++ r = kvm_filter_msr(s, MSR_KVM_MIGRATION_CONTROL, ++ kvm_rdmsr_kvm_migration_control, ++ kvm_wrmsr_kvm_migration_control); ++ if (!r) { ++ error_report("Could not install MSR_KVM_MIGRATION_CONTROL handler: %s", ++ strerror(-ret)); ++ exit(1); ++ } + } + + return 0; +diff --git a/target/i386/sev.c b/target/i386/sev.c +index cc63a1aef..b66665021 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -890,6 +890,12 @@ sev_launch_finish(SevGuestState *sev) + migrate_add_blocker(sev_mig_blocker, &error_fatal); + } + ++void ++sev_del_migrate_blocker(void) ++{ ++ migrate_del_blocker(sev_mig_blocker); ++} ++ + static int + sev_receive_finish(SevGuestState *s) + { +diff --git a/target/i386/sev.h b/target/i386/sev.h +index b8ad84014..7e53f8461 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -70,6 +70,7 @@ int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end); + int sev_save_outgoing_shared_regions_list(QEMUFile *f); + int sev_load_incoming_shared_regions_list(QEMUFile *f); + bool sev_is_gfn_in_unshared_region(unsigned long gfn); ++void sev_del_migrate_blocker(void); + + int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); + +-- +2.31.1 + diff --git a/1052-anolis-migration-ram-Force-encrypted-status-for-VGA-.patch b/1052-anolis-migration-ram-Force-encrypted-status-for-VGA-.patch new file mode 100644 index 0000000..b9cfa6e --- /dev/null +++ b/1052-anolis-migration-ram-Force-encrypted-status-for-VGA-.patch @@ -0,0 +1,33 @@ +From 1e332429c9aa4c996191ec703e3ec10a6bd459b3 Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Tue, 8 Dec 2020 22:57:46 -0500 +Subject: [PATCH 15/29] anolis: migration/ram: Force encrypted status for VGA + vram + +The VGA vram memory region act as frame buffer of VM. This memory +is decrypted in the QEMU process. For CSV VM live migration, we +should avoid memory encryption status check on VGA vram. + +Signed-off-by: hanliyang +--- + migration/ram.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/migration/ram.c b/migration/ram.c +index da7a80994..fb05ff44e 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -2262,6 +2262,10 @@ static bool encrypted_test_list(RAMState *rs, RAMBlock *block, + return false; + } + ++ if (!strcmp(memory_region_name(block->mr), "vga.vram")) { ++ return false; ++ } ++ + /* + * Translate page in ram_addr_t address space to GPA address + * space using memory region. +-- +2.31.1 + diff --git a/1053-anolis-target-i386-sev-Clear-shared_regions_list-whe.patch b/1053-anolis-target-i386-sev-Clear-shared_regions_list-whe.patch new file mode 100644 index 0000000..9e00e54 --- /dev/null +++ b/1053-anolis-target-i386-sev-Clear-shared_regions_list-whe.patch @@ -0,0 +1,58 @@ +From 6ff9e3e73b0a756c9a42f2df43178ef52cf5aa26 Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Sun, 16 Jan 2022 19:57:58 -0500 +Subject: [PATCH 16/29] anolis: target/i386: sev: Clear shared_regions_list + when reboot CSV Guest + +Also fix memory leak in sev_remove_shared_regions_list(). + +Signed-off-by: hanliyang +--- + target/i386/kvm/kvm.c | 6 ++++++ + target/i386/sev.c | 5 +++-- + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index a833219d0..f0b61ec3c 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -2143,6 +2143,12 @@ void kvm_arch_reset_vcpu(X86CPU *cpu) + + hyperv_x86_synic_reset(cpu); + } ++ ++ if (cpu_is_bsp(cpu) && ++ sev_enabled() && has_map_gpa_range) { ++ sev_remove_shared_regions_list(0, -1); ++ } ++ + /* enabled by default */ + env->poll_control_msr = 1; + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index b66665021..e3eab4119 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -1661,9 +1661,9 @@ int sev_load_incoming_page(QEMUFile *f, uint8_t *ptr) + int sev_remove_shared_regions_list(unsigned long start, unsigned long end) + { + SevGuestState *s = sev_guest; +- struct shared_region *pos; ++ struct shared_region *pos, *next_pos; + +- QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { ++ QTAILQ_FOREACH_SAFE(pos, &s->shared_regions_list, list, next_pos) { + unsigned long l, r; + unsigned long curr_gfn_end = pos->gfn_end; + +@@ -1677,6 +1677,7 @@ int sev_remove_shared_regions_list(unsigned long start, unsigned long end) + if (l <= r) { + if (pos->gfn_start == l && pos->gfn_end == r) { + QTAILQ_REMOVE(&s->shared_regions_list, pos, list); ++ g_free(pos); + } else if (l == pos->gfn_start) { + pos->gfn_start = r; + } else if (r == pos->gfn_end) { +-- +2.31.1 + diff --git a/1054-anolis-migration-ram-Fix-calculation-of-gfn-correpon.patch b/1054-anolis-migration-ram-Fix-calculation-of-gfn-correpon.patch new file mode 100644 index 0000000..d385706 --- /dev/null +++ b/1054-anolis-migration-ram-Fix-calculation-of-gfn-correpon.patch @@ -0,0 +1,57 @@ +From 7a8e357130982817732272c89a53adbb13408832 Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Sun, 16 Jan 2022 20:05:02 -0500 +Subject: [PATCH 17/29] anolis: migration/ram: Fix calculation of gfn correpond + to a page in ramblock + +A RAMBlock contains a host memory region which may consist of many +discontiguous MemoryRegion in AddressSpace of a Guest, so we cannot +get gpa by MemoryRegion.addr. Since KVM memslot records the relationship +between gpa and hva, so we can pass the hva of page in RAMBlock to +kvm_phisical_memory_addr_from_host() to get the expected gpa. + +Signed-off-by: hanliyang +--- + migration/ram.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/migration/ram.c b/migration/ram.c +index fb05ff44e..33e2c9d5f 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -59,6 +59,7 @@ + + /* Defines RAM_SAVE_ENCRYPTED_PAGE and RAM_SAVE_SHARED_REGION_LIST */ + #include "target/i386/sev.h" ++#include "sysemu/kvm.h" + + #include "hw/boards.h" /* for machine_dump_guest_core() */ + +@@ -2248,6 +2249,8 @@ static bool encrypted_test_list(RAMState *rs, RAMBlock *block, + struct ConfidentialGuestMemoryEncryptionOps *ops = + cgs_class->memory_encryption_ops; + unsigned long gfn; ++ hwaddr paddr = 0; ++ int ret; + + /* ROM devices contains the unencrypted data */ + if (memory_region_is_rom(block->mr)) { +@@ -2270,7 +2273,14 @@ static bool encrypted_test_list(RAMState *rs, RAMBlock *block, + * Translate page in ram_addr_t address space to GPA address + * space using memory region. + */ +- gfn = page + (block->mr->addr >> TARGET_PAGE_BITS); ++ if (kvm_enabled()) { ++ ret = kvm_physical_memory_addr_from_host(kvm_state, ++ block->host + (page << TARGET_PAGE_BITS), &paddr); ++ if (ret == 0) { ++ return false; ++ } ++ } ++ gfn = paddr >> TARGET_PAGE_BITS; + + return ops->is_gfn_in_unshared_region(gfn); + } +-- +2.31.1 + diff --git a/1055-anolis-target-i386-csv-Move-is_hygon_cpu-to-header-f.patch b/1055-anolis-target-i386-csv-Move-is_hygon_cpu-to-header-f.patch new file mode 100644 index 0000000..41c6269 --- /dev/null +++ b/1055-anolis-target-i386-csv-Move-is_hygon_cpu-to-header-f.patch @@ -0,0 +1,85 @@ +From 00e7b439f3c514d8ae20c20d5f18d24d71351c7d Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Wed, 1 Nov 2023 06:00:11 +0000 +Subject: [PATCH 18/29] anolis: target/i386: csv: Move is_hygon_cpu() to header + file csv.h + +The helper function is_hygon_cpu() will be called by functions out of +target/i386/csv.c. Move it to header file csv.h so that it can be a +common helper function. + +Signed-off-by: hanliyang +--- + target/i386/csv.c | 20 -------------------- + target/i386/csv.h | 22 ++++++++++++++++++++++ + 2 files changed, 22 insertions(+), 20 deletions(-) + +diff --git a/target/i386/csv.c b/target/i386/csv.c +index d166d3775..161cad39a 100644 +--- a/target/i386/csv.c ++++ b/target/i386/csv.c +@@ -27,28 +27,8 @@ + + CsvGuestState csv_guest = { 0 }; + +-#define CPUID_VENDOR_HYGON_EBX 0x6f677948 /* "Hygo" */ +-#define CPUID_VENDOR_HYGON_ECX 0x656e6975 /* "uine" */ +-#define CPUID_VENDOR_HYGON_EDX 0x6e65476e /* "nGen" */ +- + #define GUEST_POLICY_CSV_BIT (1 << 6) + +-static bool is_hygon_cpu(void) +-{ +- uint32_t ebx = 0; +- uint32_t ecx = 0; +- uint32_t edx = 0; +- +- host_cpuid(0, 0, NULL, &ebx, &ecx, &edx); +- +- if (ebx == CPUID_VENDOR_HYGON_EBX && +- ecx == CPUID_VENDOR_HYGON_ECX && +- edx == CPUID_VENDOR_HYGON_EDX) +- return true; +- else +- return false; +-} +- + int + csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) + { +diff --git a/target/i386/csv.h b/target/i386/csv.h +index 7dc5c7536..4f5b2773c 100644 +--- a/target/i386/csv.h ++++ b/target/i386/csv.h +@@ -16,6 +16,28 @@ + + #include "qapi/qapi-commands-misc-target.h" + ++#include "cpu.h" ++ ++#define CPUID_VENDOR_HYGON_EBX 0x6f677948 /* "Hygo" */ ++#define CPUID_VENDOR_HYGON_ECX 0x656e6975 /* "uine" */ ++#define CPUID_VENDOR_HYGON_EDX 0x6e65476e /* "nGen" */ ++ ++static __attribute__((unused)) bool is_hygon_cpu(void) ++{ ++ uint32_t ebx = 0; ++ uint32_t ecx = 0; ++ uint32_t edx = 0; ++ ++ host_cpuid(0, 0, NULL, &ebx, &ecx, &edx); ++ ++ if (ebx == CPUID_VENDOR_HYGON_EBX && ++ ecx == CPUID_VENDOR_HYGON_ECX && ++ edx == CPUID_VENDOR_HYGON_EDX) ++ return true; ++ else ++ return false; ++} ++ + #ifdef CONFIG_CSV + bool csv_enabled(void); + #else +-- +2.31.1 + diff --git a/1056-anolis-target-i386-csv-Read-cert-chain-from-file-whe.patch b/1056-anolis-target-i386-csv-Read-cert-chain-from-file-whe.patch new file mode 100644 index 0000000..23a528c --- /dev/null +++ b/1056-anolis-target-i386-csv-Read-cert-chain-from-file-whe.patch @@ -0,0 +1,131 @@ +From 980dff011e266d60f8ce669a1dc14cc23b192c8b Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Mon, 13 Nov 2023 21:55:33 +0000 +Subject: [PATCH 19/29] anolis: target/i386: csv: Read cert chain from file + when prepared for CSV live migration + +The cert chain is too long when encoded with base64, use the filename +of cert chain instead of the encoded string when prepared for CSV live +migration. + +Signed-off-by: hanliyang +--- + qapi/migration.json | 24 +++++++++++++++--------- + target/i386/sev.c | 29 +++++++++++++++++++++++++---- + 2 files changed, 40 insertions(+), 13 deletions(-) + +diff --git a/qapi/migration.json b/qapi/migration.json +index bad53a2f8..8632abb20 100644 +--- a/qapi/migration.json ++++ b/qapi/migration.json +@@ -774,14 +774,16 @@ + # block device name if there is one, and to their node name + # otherwise. (Since 5.2) + # +-# @sev-pdh: The target host platform diffie-hellman key encoded in base64 ++# @sev-pdh: The target host platform diffie-hellman key encoded in base64, or ++# pdh filename for hygon + # (Since 4.2) + # +-# @sev-plat-cert: The target host platform certificate chain encoded in base64 ++# @sev-plat-cert: The target host platform certificate chain encoded in base64, ++# or plat cert filename for hygon + # (Since 4.2) + # + # @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in +-# base64 (Since 4.2) ++# base64, or vendor cert filename for hygon (Since 4.2) + # + # Features: + # @unstable: Member @x-checkpoint-delay is experimental. +@@ -949,14 +951,16 @@ + # block device name if there is one, and to their node name + # otherwise. (Since 5.2) + # +-# @sev-pdh: The target host platform diffie-hellman key encoded in base64 ++# @sev-pdh: The target host platform diffie-hellman key encoded in base64, or ++# pdh filename for hygon + # (Since 4.2) + # +-# @sev-plat-cert: The target host platform certificate chain encoded in base64 ++# @sev-plat-cert: The target host platform certificate chain encoded in base64, ++# or plat cert filename for hygon + # (Since 4.2) + # + # @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in +-# base64 (Since 4.2) ++# base64, or vendor cert filename for hygon (Since 4.2) + # + # Features: + # @unstable: Member @x-checkpoint-delay is experimental. +@@ -1161,14 +1165,16 @@ + # block device name if there is one, and to their node name + # otherwise. (Since 5.2) + # +-# @sev-pdh: The target host platform diffie-hellman key encoded in base64 ++# @sev-pdh: The target host platform diffie-hellman key encoded in base64, or ++# pdh filename for hygon + # (Since 4.2) + # +-# @sev-plat-cert: The target host platform certificate chain encoded in base64 ++# @sev-plat-cert: The target host platform certificate chain encoded in base64, ++# or plat cert filename for hygon + # (Since 4.2) + # + # @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in +-# base64 (Since 4.2) ++# base64, or vendor cert filename for hygon (Since 4.2) + # + # Features: + # @unstable: Member @x-checkpoint-delay is experimental. +diff --git a/target/i386/sev.c b/target/i386/sev.c +index e3eab4119..ebe97799c 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -944,18 +944,39 @@ int sev_save_setup(const char *pdh, const char *plat_cert, + { + SevGuestState *s = sev_guest; + +- s->remote_pdh = g_base64_decode(pdh, &s->remote_pdh_len); ++ if (is_hygon_cpu()) { ++ if (sev_read_file_base64(pdh, &s->remote_pdh, ++ &s->remote_pdh_len) < 0) { ++ goto error; ++ } ++ } else { ++ s->remote_pdh = g_base64_decode(pdh, &s->remote_pdh_len); ++ } + if (!check_blob_length(s->remote_pdh_len)) { + goto error; + } + +- s->remote_plat_cert = g_base64_decode(plat_cert, +- &s->remote_plat_cert_len); ++ if (is_hygon_cpu()) { ++ if (sev_read_file_base64(plat_cert, &s->remote_plat_cert, ++ &s->remote_plat_cert_len) < 0) { ++ goto error; ++ } ++ } else { ++ s->remote_plat_cert = g_base64_decode(plat_cert, ++ &s->remote_plat_cert_len); ++ } + if (!check_blob_length(s->remote_plat_cert_len)) { + goto error; + } + +- s->amd_cert = g_base64_decode(amd_cert, &s->amd_cert_len); ++ if (is_hygon_cpu()) { ++ if (sev_read_file_base64(amd_cert, &s->amd_cert, ++ &s->amd_cert_len) < 0) { ++ goto error; ++ } ++ } else { ++ s->amd_cert = g_base64_decode(amd_cert, &s->amd_cert_len); ++ } + if (!check_blob_length(s->amd_cert_len)) { + goto error; + } +-- +2.31.1 + diff --git a/1057-anolis-target-i386-csv-add-support-to-queue-the-outg.patch b/1057-anolis-target-i386-csv-add-support-to-queue-the-outg.patch new file mode 100644 index 0000000..f6a3b3b --- /dev/null +++ b/1057-anolis-target-i386-csv-add-support-to-queue-the-outg.patch @@ -0,0 +1,270 @@ +From 19941d177378b596a52a7905925525d68d152dea Mon Sep 17 00:00:00 2001 +From: fangbaoshun +Date: Mon, 2 Aug 2021 11:00:07 +0800 +Subject: [PATCH 20/29] anolis: target/i386: csv: add support to queue the + outgoing page into a list + +The csv_queue_outgoing_page() provide the implementation to queue the +guest private pages during transmission. The routines queues the outgoing +pages into a listi, and then issues the KVM_CSV_COMMAND_BATCH command to +encrypt the pages togather before writing them to the socket. + +Signed-off-by: hanliyang +--- + include/exec/confidential-guest-support.h | 3 + + linux-headers/linux/kvm.h | 6 + + target/i386/sev.c | 172 ++++++++++++++++++++++ + target/i386/sev.h | 2 + + 4 files changed, 183 insertions(+) + +diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h +index 343f686fc..1f32519d4 100644 +--- a/include/exec/confidential-guest-support.h ++++ b/include/exec/confidential-guest-support.h +@@ -77,6 +77,9 @@ struct ConfidentialGuestMemoryEncryptionOps { + + /* Load the shared regions list */ + int (*load_incoming_shared_regions_list)(QEMUFile *f); ++ ++ /* Queue the encrypted page and metadata associated with it into a list */ ++ int (*queue_outgoing_page)(uint8_t *ptr, uint32_t size, uint64_t addr); + }; + + typedef struct ConfidentialGuestSupportClass { +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index b640e72c8..8dd8c5e6a 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -1938,6 +1938,12 @@ struct kvm_csv_init_data { + __u64 nodemask; + }; + ++struct kvm_csv_batch_list_node { ++ __u64 cmd_data_addr; ++ __u64 addr; ++ __u64 next_cmd_addr; ++}; ++ + #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) + #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) + #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) +diff --git a/target/i386/sev.c b/target/i386/sev.c +index ebe97799c..e7ff3f4dd 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -50,6 +50,15 @@ struct shared_region { + QTAILQ_ENTRY(shared_region) list; + }; + ++typedef struct CsvBatchCmdList CsvBatchCmdList; ++typedef void (*CsvDestroyCmdNodeFn) (void *data); ++ ++struct CsvBatchCmdList { ++ struct kvm_csv_batch_list_node *head; ++ struct kvm_csv_batch_list_node *tail; ++ CsvDestroyCmdNodeFn destroy_fn; ++}; ++ + extern struct sev_ops sev_ops; + + /** +@@ -96,6 +105,9 @@ struct SevGuestState { + bool reset_data_valid; + + QTAILQ_HEAD(, shared_region) shared_regions_list; ++ ++ /* link list used for HYGON CSV */ ++ CsvBatchCmdList *csv_batch_cmd_list; + }; + + #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */ +@@ -188,6 +200,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { + .is_gfn_in_unshared_region = sev_is_gfn_in_unshared_region, + .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, + .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, ++ .queue_outgoing_page = csv_queue_outgoing_page, + }; + + static int +@@ -1829,6 +1842,165 @@ bool sev_is_gfn_in_unshared_region(unsigned long gfn) + return true; + } + ++#include "csv.h" ++ ++static CsvBatchCmdList * ++csv_batch_cmd_list_create(struct kvm_csv_batch_list_node *head, ++ CsvDestroyCmdNodeFn func) ++{ ++ CsvBatchCmdList *csv_batch_cmd_list = ++ g_malloc0(sizeof(*csv_batch_cmd_list)); ++ ++ if (!csv_batch_cmd_list) { ++ return NULL; ++ } ++ ++ csv_batch_cmd_list->head = head; ++ csv_batch_cmd_list->tail = head; ++ csv_batch_cmd_list->destroy_fn = func; ++ ++ return csv_batch_cmd_list; ++} ++ ++static int ++csv_batch_cmd_list_add_after(CsvBatchCmdList *list, ++ struct kvm_csv_batch_list_node *new_node) ++{ ++ list->tail->next_cmd_addr = (__u64)new_node; ++ list->tail = new_node; ++ ++ return 0; ++} ++ ++static struct kvm_csv_batch_list_node * ++csv_batch_cmd_list_node_create(uint64_t cmd_data_addr, uint64_t addr) ++{ ++ struct kvm_csv_batch_list_node *new_node = ++ g_malloc0(sizeof(struct kvm_csv_batch_list_node)); ++ ++ if (!new_node) { ++ return NULL; ++ } ++ ++ new_node->cmd_data_addr = cmd_data_addr; ++ new_node->addr = addr; ++ new_node->next_cmd_addr = 0; ++ ++ return new_node; ++} ++ ++static int csv_batch_cmd_list_destroy(CsvBatchCmdList *list) ++{ ++ struct kvm_csv_batch_list_node *node = list->head; ++ ++ while (node != NULL) { ++ if (list->destroy_fn != NULL) ++ list->destroy_fn((void *)node->cmd_data_addr); ++ ++ list->head = (struct kvm_csv_batch_list_node *)node->next_cmd_addr; ++ g_free(node); ++ node = list->head; ++ } ++ ++ g_free(list); ++ return 0; ++} ++ ++static void send_update_data_free(void *data) ++{ ++ struct kvm_sev_send_update_data *update = ++ (struct kvm_sev_send_update_data *)data; ++ g_free((guchar *)update->hdr_uaddr); ++ g_free((guchar *)update->trans_uaddr); ++ g_free(update); ++} ++ ++static int ++csv_send_queue_data(SevGuestState *s, uint8_t *ptr, ++ uint32_t size, uint64_t addr) ++{ ++ int ret = 0; ++ int fw_error; ++ guchar *trans; ++ guchar *packet_hdr; ++ struct kvm_sev_send_update_data *update; ++ struct kvm_csv_batch_list_node *new_node = NULL; ++ ++ /* If this is first call then query the packet header bytes and allocate ++ * the packet buffer. ++ */ ++ if (s->send_packet_hdr_len < 1) { ++ s->send_packet_hdr_len = sev_send_get_packet_len(&fw_error); ++ if (s->send_packet_hdr_len < 1) { ++ error_report("%s: SEND_UPDATE fw_error=%d '%s'", ++ __func__, fw_error, fw_error_to_str(fw_error)); ++ return 1; ++ } ++ } ++ ++ packet_hdr = g_new(guchar, s->send_packet_hdr_len); ++ memset(packet_hdr, 0, s->send_packet_hdr_len); ++ ++ update = g_new0(struct kvm_sev_send_update_data, 1); ++ ++ /* allocate transport buffer */ ++ trans = g_new(guchar, size); ++ ++ update->hdr_uaddr = (unsigned long)packet_hdr; ++ update->hdr_len = s->send_packet_hdr_len; ++ update->guest_uaddr = (unsigned long)ptr; ++ update->guest_len = size; ++ update->trans_uaddr = (unsigned long)trans; ++ update->trans_len = size; ++ ++ new_node = csv_batch_cmd_list_node_create((uint64_t)update, addr); ++ if (!new_node) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ if (s->csv_batch_cmd_list == NULL) { ++ s->csv_batch_cmd_list = csv_batch_cmd_list_create(new_node, ++ send_update_data_free); ++ if (s->csv_batch_cmd_list == NULL) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ } else { ++ /* Add new_node's command address to the last_node */ ++ csv_batch_cmd_list_add_after(s->csv_batch_cmd_list, new_node); ++ } ++ ++ trace_kvm_sev_send_update_data(ptr, trans, size); ++ ++ return ret; ++ ++err: ++ g_free(trans); ++ g_free(update); ++ g_free(packet_hdr); ++ g_free(new_node); ++ if (s->csv_batch_cmd_list) { ++ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list); ++ s->csv_batch_cmd_list = NULL; ++ } ++ return ret; ++} ++ ++int ++csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) ++{ ++ SevGuestState *s = sev_guest; ++ ++ /* Only support for HYGON CSV */ ++ if (!is_hygon_cpu()) { ++ error_report("Only support enqueue pages for HYGON CSV"); ++ return -EINVAL; ++ } ++ ++ return csv_send_queue_data(s, ptr, sz, addr); ++} ++ + static const QemuUUID sev_hash_table_header_guid = { + .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, + 0xd4, 0x11, 0xfd, 0x21) +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 7e53f8461..1eba67bcf 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -74,6 +74,8 @@ void sev_del_migrate_blocker(void); + + int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); + ++int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); ++ + struct sev_ops { + int (*sev_ioctl)(int fd, int cmd, void *data, int *error); + const char *(*fw_error_to_str)(int code); +-- +2.31.1 + diff --git a/1058-anolis-target-i386-csv-add-support-to-encrypt-the-ou.patch b/1058-anolis-target-i386-csv-add-support-to-encrypt-the-ou.patch new file mode 100644 index 0000000..393b474 --- /dev/null +++ b/1058-anolis-target-i386-csv-add-support-to-encrypt-the-ou.patch @@ -0,0 +1,204 @@ +From 500646168eb4dc297d01dbc35759e38d0206a3b6 Mon Sep 17 00:00:00 2001 +From: fangbaoshun +Date: Mon, 2 Aug 2021 11:41:58 +0800 +Subject: [PATCH 21/29] anolis: target/i386: csv: add support to encrypt the + outgoing pages in the list queued before. + +The csv_save_queued_outgoing_pages() provide the implementation to encrypt +the guest private pages during transmission. The routines uses SEND_START +command to create the outgoing encryption context on the first call then +uses COMMAND_BATCH command to send the SEND_UPDATE_DATA commands queued +in the list to encrypt the data before writing it to the socket. While +encrypting the data SEND_UPDATE_DATA produces some metadata (e.g MAC, IV). +The metadata is also sent to the target machine. After migration is completed, +we issue the SEND_FINISH command to transition the SEV guest state from sending +to unrunnable state. + +Signed-off-by: hanliyang +--- + include/exec/confidential-guest-support.h | 4 + + linux-headers/linux/kvm.h | 8 ++ + target/i386/sev.c | 89 +++++++++++++++++++++++ + target/i386/sev.h | 4 + + 4 files changed, 105 insertions(+) + +diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h +index 1f32519d4..1ff4823b6 100644 +--- a/include/exec/confidential-guest-support.h ++++ b/include/exec/confidential-guest-support.h +@@ -80,6 +80,10 @@ struct ConfidentialGuestMemoryEncryptionOps { + + /* Queue the encrypted page and metadata associated with it into a list */ + int (*queue_outgoing_page)(uint8_t *ptr, uint32_t size, uint64_t addr); ++ ++ /* Write the list queued with encrypted pages and metadata associated ++ * with them */ ++ int (*save_queued_outgoing_pages)(QEMUFile *f, uint64_t *bytes_sent); + }; + + typedef struct ConfidentialGuestSupportClass { +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 8dd8c5e6a..951afc8b2 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -1823,6 +1823,9 @@ enum sev_cmd_id { + /* Guest Migration Extension */ + KVM_SEV_SEND_CANCEL, + ++ /* Hygon CSV batch command */ ++ KVM_CSV_COMMAND_BATCH = 0x18, ++ + KVM_SEV_NR_MAX, + }; + +@@ -1944,6 +1947,11 @@ struct kvm_csv_batch_list_node { + __u64 next_cmd_addr; + }; + ++struct kvm_csv_command_batch { ++ __u32 command_id; ++ __u64 csv_batch_list_uaddr; ++}; ++ + #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) + #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) + #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) +diff --git a/target/i386/sev.c b/target/i386/sev.c +index e7ff3f4dd..6ff547a23 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -201,6 +201,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { + .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, + .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, + .queue_outgoing_page = csv_queue_outgoing_page, ++ .save_queued_outgoing_pages = csv_save_queued_outgoing_pages, + }; + + static int +@@ -1987,6 +1988,70 @@ err: + return ret; + } + ++static int ++csv_command_batch(uint32_t cmd_id, uint64_t head_uaddr, int *fw_err) ++{ ++ int ret; ++ struct kvm_csv_command_batch command_batch = { }; ++ ++ command_batch.command_id = cmd_id; ++ command_batch.csv_batch_list_uaddr = head_uaddr; ++ ++ ret = sev_ioctl(sev_guest->sev_fd, KVM_CSV_COMMAND_BATCH, ++ &command_batch, fw_err); ++ if (ret) { ++ error_report("%s: COMMAND_BATCH ret=%d fw_err=%d '%s'", ++ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); ++ } ++ ++ return ret; ++} ++ ++static int ++csv_send_update_data_batch(SevGuestState *s, QEMUFile *f, uint64_t *bytes_sent) ++{ ++ int ret, fw_error = 0; ++ struct kvm_sev_send_update_data *update; ++ struct kvm_csv_batch_list_node *node; ++ ++ ret = csv_command_batch(KVM_SEV_SEND_UPDATE_DATA, ++ (uint64_t)s->csv_batch_cmd_list->head, &fw_error); ++ if (ret) { ++ error_report("%s: csv_command_batch ret=%d fw_error=%d '%s'", ++ __func__, ret, fw_error, fw_error_to_str(fw_error)); ++ goto err; ++ } ++ ++ *bytes_sent = 0; ++ for (node = s->csv_batch_cmd_list->head; ++ node != NULL; ++ node = (struct kvm_csv_batch_list_node *)node->next_cmd_addr) { ++ if (node != s->csv_batch_cmd_list->head) { ++ /* head's page header is saved before send_update_data */ ++ qemu_put_be64(f, node->addr); ++ *bytes_sent += 8; ++ if (node->next_cmd_addr != 0) ++ qemu_put_be32(f, RAM_SAVE_ENCRYPTED_PAGE_BATCH); ++ else ++ qemu_put_be32(f, RAM_SAVE_ENCRYPTED_PAGE_BATCH_END); ++ *bytes_sent += 4; ++ } ++ update = (struct kvm_sev_send_update_data *)node->cmd_data_addr; ++ qemu_put_be32(f, update->hdr_len); ++ qemu_put_buffer(f, (uint8_t *)update->hdr_uaddr, update->hdr_len); ++ *bytes_sent += (4 + update->hdr_len); ++ ++ qemu_put_be32(f, update->trans_len); ++ qemu_put_buffer(f, (uint8_t *)update->trans_uaddr, update->trans_len); ++ *bytes_sent += (4 + update->trans_len); ++ } ++ ++err: ++ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list); ++ s->csv_batch_cmd_list = NULL; ++ return ret; ++} ++ + int + csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) + { +@@ -2001,6 +2066,30 @@ csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) + return csv_send_queue_data(s, ptr, sz, addr); + } + ++int ++csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) ++{ ++ SevGuestState *s = sev_guest; ++ ++ /* Only support for HYGON CSV */ ++ if (!is_hygon_cpu()) { ++ error_report("Only support transfer queued pages for HYGON CSV"); ++ return -EINVAL; ++ } ++ ++ /* ++ * If this is a first buffer then create outgoing encryption context ++ * and write our PDH, policy and session data. ++ */ ++ if (!sev_check_state(s, SEV_STATE_SEND_UPDATE) && ++ sev_send_start(s, f, bytes_sent)) { ++ error_report("Failed to create outgoing context"); ++ return 1; ++ } ++ ++ return csv_send_update_data_batch(s, f, bytes_sent); ++} ++ + static const QemuUUID sev_hash_table_header_guid = { + .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, + 0xd4, 0x11, 0xfd, 0x21) +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 1eba67bcf..37ed17f32 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -41,6 +41,9 @@ typedef struct SevKernelLoaderContext { + #define RAM_SAVE_ENCRYPTED_PAGE 0x1 + #define RAM_SAVE_SHARED_REGIONS_LIST 0x2 + ++#define RAM_SAVE_ENCRYPTED_PAGE_BATCH 0x4 ++#define RAM_SAVE_ENCRYPTED_PAGE_BATCH_END 0x5 ++ + #ifdef CONFIG_SEV + bool sev_enabled(void); + bool sev_es_enabled(void); +@@ -75,6 +78,7 @@ void sev_del_migrate_blocker(void); + int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); + + int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); ++int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); + + struct sev_ops { + int (*sev_ioctl)(int fd, int cmd, void *data, int *error); +-- +2.31.1 + diff --git a/1059-anolis-target-i386-csv-add-support-to-queue-the-inco.patch b/1059-anolis-target-i386-csv-add-support-to-queue-the-inco.patch new file mode 100644 index 0000000..cc70aac --- /dev/null +++ b/1059-anolis-target-i386-csv-add-support-to-queue-the-inco.patch @@ -0,0 +1,171 @@ +From 8af625f3b5f4d2eb768b1eee2dc2e7938800d47e Mon Sep 17 00:00:00 2001 +From: fangbaoshun +Date: Mon, 2 Aug 2021 13:49:48 +0800 +Subject: [PATCH 22/29] anolis: target/i386: csv: add support to queue the + incoming page into a list + +The csv_queue_incoming_page() provide the implementation to queue the +guest private pages during transmission. The routines queues the incoming +socket which contains the guest private pages into a list then uses the +COMMAND_BATCH command to load the encrypted pages into the guest memory. + +Signed-off-by: hanliyang +--- + include/exec/confidential-guest-support.h | 3 + + target/i386/sev.c | 92 +++++++++++++++++++++++ + target/i386/sev.h | 1 + + 3 files changed, 96 insertions(+) + +diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h +index 1ff4823b6..530b5057b 100644 +--- a/include/exec/confidential-guest-support.h ++++ b/include/exec/confidential-guest-support.h +@@ -84,6 +84,9 @@ struct ConfidentialGuestMemoryEncryptionOps { + /* Write the list queued with encrypted pages and metadata associated + * with them */ + int (*save_queued_outgoing_pages)(QEMUFile *f, uint64_t *bytes_sent); ++ ++ /* Queue the incoming encrypted page into a list */ ++ int (*queue_incoming_page)(QEMUFile *f, uint8_t *ptr); + }; + + typedef struct ConfidentialGuestSupportClass { +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 6ff547a23..e235fb207 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -202,6 +202,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { + .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, + .queue_outgoing_page = csv_queue_outgoing_page, + .save_queued_outgoing_pages = csv_save_queued_outgoing_pages, ++ .queue_incoming_page = csv_queue_incoming_page, + }; + + static int +@@ -1916,6 +1917,15 @@ static void send_update_data_free(void *data) + g_free(update); + } + ++static void receive_update_data_free(void *data) ++{ ++ struct kvm_sev_receive_update_data *update = ++ (struct kvm_sev_receive_update_data *)data; ++ g_free((guchar *)update->hdr_uaddr); ++ g_free((guchar *)update->trans_uaddr); ++ g_free(update); ++} ++ + static int + csv_send_queue_data(SevGuestState *s, uint8_t *ptr, + uint32_t size, uint64_t addr) +@@ -1988,6 +1998,66 @@ err: + return ret; + } + ++static int ++csv_receive_queue_data(SevGuestState *s, QEMUFile *f, uint8_t *ptr) ++{ ++ int ret = 0; ++ gchar *hdr = NULL, *trans = NULL; ++ struct kvm_sev_receive_update_data *update; ++ struct kvm_csv_batch_list_node *new_node = NULL; ++ ++ update = g_new0(struct kvm_sev_receive_update_data, 1); ++ /* get packet header */ ++ update->hdr_len = qemu_get_be32(f); ++ hdr = g_new(gchar, update->hdr_len); ++ qemu_get_buffer(f, (uint8_t *)hdr, update->hdr_len); ++ update->hdr_uaddr = (unsigned long)hdr; ++ ++ /* get transport buffer */ ++ update->trans_len = qemu_get_be32(f); ++ trans = g_new(gchar, update->trans_len); ++ update->trans_uaddr = (unsigned long)trans; ++ qemu_get_buffer(f, (uint8_t *)update->trans_uaddr, update->trans_len); ++ ++ /* set guest address,guest len is page_size */ ++ update->guest_uaddr = (uint64_t)ptr; ++ update->guest_len = TARGET_PAGE_SIZE; ++ ++ new_node = csv_batch_cmd_list_node_create((uint64_t)update, 0); ++ if (!new_node) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ if (s->csv_batch_cmd_list == NULL) { ++ s->csv_batch_cmd_list = csv_batch_cmd_list_create(new_node, ++ receive_update_data_free); ++ if (s->csv_batch_cmd_list == NULL) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ } else { ++ /* Add new_node's command address to the last_node */ ++ csv_batch_cmd_list_add_after(s->csv_batch_cmd_list, new_node); ++ } ++ ++ trace_kvm_sev_receive_update_data(trans, (void *)ptr, update->guest_len, ++ (void *)hdr, update->hdr_len); ++ ++ return ret; ++ ++err: ++ g_free(trans); ++ g_free(update); ++ g_free(hdr); ++ g_free(new_node); ++ if (s->csv_batch_cmd_list) { ++ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list); ++ s->csv_batch_cmd_list = NULL; ++ } ++ return ret; ++} ++ + static int + csv_command_batch(uint32_t cmd_id, uint64_t head_uaddr, int *fw_err) + { +@@ -2066,6 +2136,28 @@ csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) + return csv_send_queue_data(s, ptr, sz, addr); + } + ++int csv_queue_incoming_page(QEMUFile *f, uint8_t *ptr) ++{ ++ SevGuestState *s = sev_guest; ++ ++ /* Only support for HYGON CSV */ ++ if (!is_hygon_cpu()) { ++ error_report("Only support enqueue received pages for HYGON CSV"); ++ return -EINVAL; ++ } ++ ++ /* ++ * If this is first buffer and SEV is not in recieiving state then ++ * use RECEIVE_START command to create a encryption context. ++ */ ++ if (!sev_check_state(s, SEV_STATE_RECEIVE_UPDATE) && ++ sev_receive_start(s, f)) { ++ return 1; ++ } ++ ++ return csv_receive_queue_data(s, f, ptr); ++} ++ + int + csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) + { +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 37ed17f32..6166be420 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -79,6 +79,7 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); + + int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); + int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); ++int csv_queue_incoming_page(QEMUFile *f, uint8_t *ptr); + + struct sev_ops { + int (*sev_ioctl)(int fd, int cmd, void *data, int *error); +-- +2.31.1 + diff --git a/1060-anolis-target-i386-csv-add-support-to-load-incoming-.patch b/1060-anolis-target-i386-csv-add-support-to-load-incoming-.patch new file mode 100644 index 0000000..f54f872 --- /dev/null +++ b/1060-anolis-target-i386-csv-add-support-to-load-incoming-.patch @@ -0,0 +1,108 @@ +From 8949b2ac9cc6d9a59a482ca76f81a417c9c38e6d Mon Sep 17 00:00:00 2001 +From: fangbaoshun +Date: Mon, 2 Aug 2021 14:11:43 +0800 +Subject: [PATCH 23/29] anolis: target/i386: csv: add support to load incoming + encrypted pages queued in the CMD list + +The csv_load_queued_incoming_pages() provide the implementation to read the +incoming guest private pages from the socket queued in the CMD list and load +them into the guest memory. The routines uses the RECEIVE_START command to +create the incoming encryption context on the first call then uses the +COMMAND_BATCH carried with RECEIEVE_UPDATE_DATA commands to load the encrypted +pages into the guest memory. After migration is completed, we issue the +RECEIVE_FINISH command to transition the SEV guest to the runnable state +so that it can be executed. + +Signed-off-by: hanliyang +--- + include/exec/confidential-guest-support.h | 3 +++ + target/i386/sev.c | 32 +++++++++++++++++++++++ + target/i386/sev.h | 1 + + 3 files changed, 36 insertions(+) + +diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h +index 530b5057b..f6a30fab3 100644 +--- a/include/exec/confidential-guest-support.h ++++ b/include/exec/confidential-guest-support.h +@@ -87,6 +87,9 @@ struct ConfidentialGuestMemoryEncryptionOps { + + /* Queue the incoming encrypted page into a list */ + int (*queue_incoming_page)(QEMUFile *f, uint8_t *ptr); ++ ++ /* Load the incoming encrypted pages queued in list into guest memory */ ++ int (*load_queued_incoming_pages)(QEMUFile *f); + }; + + typedef struct ConfidentialGuestSupportClass { +diff --git a/target/i386/sev.c b/target/i386/sev.c +index e235fb207..2f7d98be6 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -203,6 +203,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { + .queue_outgoing_page = csv_queue_outgoing_page, + .save_queued_outgoing_pages = csv_save_queued_outgoing_pages, + .queue_incoming_page = csv_queue_incoming_page, ++ .load_queued_incoming_pages = csv_load_queued_incoming_pages, + }; + + static int +@@ -2122,6 +2123,24 @@ err: + return ret; + } + ++static int ++csv_receive_update_data_batch(SevGuestState *s) ++{ ++ int ret; ++ int fw_error; ++ ++ ret = csv_command_batch(KVM_SEV_RECEIVE_UPDATE_DATA, ++ (uint64_t)s->csv_batch_cmd_list->head, &fw_error); ++ if (ret) { ++ error_report("%s: csv_command_batch ret=%d fw_error=%d '%s'", ++ __func__, ret, fw_error, fw_error_to_str(fw_error)); ++ } ++ ++ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list); ++ s->csv_batch_cmd_list = NULL; ++ return ret; ++} ++ + int + csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) + { +@@ -2182,6 +2201,19 @@ csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) + return csv_send_update_data_batch(s, f, bytes_sent); + } + ++int csv_load_queued_incoming_pages(QEMUFile *f) ++{ ++ SevGuestState *s = sev_guest; ++ ++ /* Only support for HYGON CSV */ ++ if (!is_hygon_cpu()) { ++ error_report("Only support load queued pages for HYGON CSV"); ++ return -EINVAL; ++ } ++ ++ return csv_receive_update_data_batch(s); ++} ++ + static const QemuUUID sev_hash_table_header_guid = { + .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, + 0xd4, 0x11, 0xfd, 0x21) +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 6166be420..c53f96b04 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -80,6 +80,7 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); + int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); + int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); + int csv_queue_incoming_page(QEMUFile *f, uint8_t *ptr); ++int csv_load_queued_incoming_pages(QEMUFile *f); + + struct sev_ops { + int (*sev_ioctl)(int fd, int cmd, void *data, int *error); +-- +2.31.1 + diff --git a/1061-anolis-migration-ram-Accelerate-the-transmission-of-.patch b/1061-anolis-migration-ram-Accelerate-the-transmission-of-.patch new file mode 100644 index 0000000..a065a0e --- /dev/null +++ b/1061-anolis-migration-ram-Accelerate-the-transmission-of-.patch @@ -0,0 +1,229 @@ +From 379463820571f9ca239e68f2f5f588634b96bbff Mon Sep 17 00:00:00 2001 +From: fangbaoshun +Date: Mon, 2 Aug 2021 14:35:51 +0800 +Subject: [PATCH 24/29] anolis: migration/ram: Accelerate the transmission of + CSV guest's encrypted pages + +When memory encryption is enabled, the guest memory will be encrypted with +the guest specific key. The patch introduces an accelerate solution which +queued the pages into list and send them togather by COMMAND_BATCH. + +Signed-off-by: hanliyang +--- + configs/devices/i386-softmmu/default.mak | 1 + + hw/i386/Kconfig | 5 ++ + migration/ram.c | 106 +++++++++++++++++++++++ + target/i386/csv.h | 11 +++ + target/i386/sev.h | 1 + + 5 files changed, 124 insertions(+) + +diff --git a/configs/devices/i386-softmmu/default.mak b/configs/devices/i386-softmmu/default.mak +index db83ffcab..e948e54e4 100644 +--- a/configs/devices/i386-softmmu/default.mak ++++ b/configs/devices/i386-softmmu/default.mak +@@ -24,6 +24,7 @@ + #CONFIG_VTD=n + #CONFIG_SGX=n + #CONFIG_CSV=n ++#CONFIG_HYGON_CSV_MIG_ACCEL=n + + # Boards: + # +diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig +index ed35d762b..8876b360b 100644 +--- a/hw/i386/Kconfig ++++ b/hw/i386/Kconfig +@@ -4,6 +4,7 @@ config X86_FW_OVMF + config SEV + bool + select X86_FW_OVMF ++ select HYGON_CSV_MIG_ACCEL + depends on KVM + + config SGX +@@ -14,6 +15,10 @@ config CSV + bool + depends on SEV + ++config HYGON_CSV_MIG_ACCEL ++ bool ++ depends on SEV ++ + config PC + bool + imply APPLESMC +diff --git a/migration/ram.c b/migration/ram.c +index 33e2c9d5f..7e2d4e7df 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -59,6 +59,7 @@ + + /* Defines RAM_SAVE_ENCRYPTED_PAGE and RAM_SAVE_SHARED_REGION_LIST */ + #include "target/i386/sev.h" ++#include "target/i386/csv.h" + #include "sysemu/kvm.h" + + #include "hw/boards.h" /* for machine_dump_guest_core() */ +@@ -2348,6 +2349,99 @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss, + return ram_save_page(rs, pss, last_stage); + } + ++#ifdef CONFIG_HYGON_CSV_MIG_ACCEL ++/** ++ * ram_save_encrypted_pages_in_batch - send the given encrypted pages to ++ * the stream. ++ */ ++static int ++ram_save_encrypted_pages_in_batch(RAMState *rs, PageSearchStatus *pss, bool last_stage) ++{ ++ int ret; ++ int tmppages = 0, pages = 0; ++ RAMBlock *block = pss->block; ++ ram_addr_t offset = pss->page << TARGET_PAGE_BITS; ++ ram_addr_t start_offset = 0; ++ uint32_t host_len = 0; ++ uint8_t *p; ++ uint64_t bytes_xmit; ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ ConfidentialGuestSupportClass *cgs_class = ++ (ConfidentialGuestSupportClass *)object_get_class(OBJECT(ms->cgs)); ++ struct ConfidentialGuestMemoryEncryptionOps *ops = ++ cgs_class->memory_encryption_ops; ++ ++ do { ++ /* Check the pages is dirty and if it is send it */ ++ if (!migration_bitmap_clear_dirty(rs, block, pss->page)) { ++ pss->page++; ++ continue; ++ } ++ ++ /* Process the unencrypted page */ ++ if (!encrypted_test_list(rs, block, pss->page)) { ++ tmppages = ram_save_target_page(rs, pss, last_stage); ++ } else { ++ /* Caculate the offset and host virtual address of the page */ ++ offset = pss->page << TARGET_PAGE_BITS; ++ p = block->host + offset; ++ ++ /* Record the offset and host virtual address of the first ++ * page in this loop which will be used below. ++ */ ++ if (host_len == 0) { ++ start_offset = offset | RAM_SAVE_FLAG_ENCRYPTED_DATA; ++ } else { ++ offset |= (RAM_SAVE_FLAG_ENCRYPTED_DATA | RAM_SAVE_FLAG_CONTINUE); ++ } ++ ++ /* Queue the outgoing page if the page is not zero page. ++ * If the queued pages are up to the outgoing page window size, ++ * process them below. ++ */ ++ if (ops->queue_outgoing_page(p, TARGET_PAGE_SIZE, offset)) ++ return -1; ++ ++ tmppages = 1; ++ host_len += TARGET_PAGE_SIZE; ++ ram_counters.normal++; ++ } ++ ++ if (tmppages < 0) { ++ return tmppages; ++ } ++ ++ pages += tmppages; ++ ++ pss->page++; ++ } while (offset_in_ramblock(block, pss->page << TARGET_PAGE_BITS) && ++ host_len < CSV_OUTGOING_PAGE_WINDOW_SIZE); ++ ++ /* Check if there are any queued pages */ ++ if (host_len != 0) { ++ ram_counters.transferred += ++ save_page_header(rs, rs->f, block, start_offset); ++ /* if only one page queued, flag is BATCH_END, else flag is BATCH */ ++ if (host_len > TARGET_PAGE_SIZE) ++ qemu_put_be32(rs->f, RAM_SAVE_ENCRYPTED_PAGE_BATCH); ++ else ++ qemu_put_be32(rs->f, RAM_SAVE_ENCRYPTED_PAGE_BATCH_END); ++ ram_counters.transferred += 4; ++ /* Process the queued pages in batch */ ++ ret = ops->save_queued_outgoing_pages(rs->f, &bytes_xmit); ++ if (ret) { ++ return -1; ++ } ++ ram_counters.transferred += bytes_xmit; ++ } ++ ++ /* The offset we leave with is the last one we looked at */ ++ pss->page--; ++ ++ return pages; ++} ++#endif ++ + /** + * ram_save_host_page: save a whole host page + * +@@ -2382,6 +2476,18 @@ static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss, + return 0; + } + ++#ifdef CONFIG_HYGON_CSV_MIG_ACCEL ++ /* ++ * If command_batch function is enabled and memory encryption is enabled ++ * then use command batch APIs to accelerate the sending process ++ * to write the outgoing buffer to the wire. The encryption APIs ++ * will re-encrypt the data with transport key so that data is prototect ++ * on the wire. ++ */ ++ if (memcrypt_enabled() && is_hygon_cpu() && !migration_in_postcopy()) ++ return ram_save_encrypted_pages_in_batch(rs, pss, last_stage); ++#endif ++ + do { + /* Check the pages is dirty and if it is send it */ + if (migration_bitmap_clear_dirty(rs, pss->block, pss->page)) { +diff --git a/target/i386/csv.h b/target/i386/csv.h +index 4f5b2773c..e51cc8302 100644 +--- a/target/i386/csv.h ++++ b/target/i386/csv.h +@@ -16,6 +16,8 @@ + + #include "qapi/qapi-commands-misc-target.h" + ++#ifdef CONFIG_SEV ++ + #include "cpu.h" + + #define CPUID_VENDOR_HYGON_EBX 0x6f677948 /* "Hygo" */ +@@ -38,6 +40,15 @@ static __attribute__((unused)) bool is_hygon_cpu(void) + return false; + } + ++#else ++ ++static __attribute__((unused)) bool is_hygon_cpu(void) ++{ ++ return false; ++} ++ ++#endif ++ + #ifdef CONFIG_CSV + bool csv_enabled(void); + #else +diff --git a/target/i386/sev.h b/target/i386/sev.h +index c53f96b04..345dffac5 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -43,6 +43,7 @@ typedef struct SevKernelLoaderContext { + + #define RAM_SAVE_ENCRYPTED_PAGE_BATCH 0x4 + #define RAM_SAVE_ENCRYPTED_PAGE_BATCH_END 0x5 ++#define CSV_OUTGOING_PAGE_WINDOW_SIZE (4094 * TARGET_PAGE_SIZE) + + #ifdef CONFIG_SEV + bool sev_enabled(void); +-- +2.31.1 + diff --git a/1062-anolis-migration-ram-Accelerate-the-loading-of-CSV-g.patch b/1062-anolis-migration-ram-Accelerate-the-loading-of-CSV-g.patch new file mode 100644 index 0000000..56c11eb --- /dev/null +++ b/1062-anolis-migration-ram-Accelerate-the-loading-of-CSV-g.patch @@ -0,0 +1,37 @@ +From e9b70bcaf165cb163304ba68a1b1db078489d9e0 Mon Sep 17 00:00:00 2001 +From: fangbaoshun +Date: Mon, 2 Aug 2021 14:49:45 +0800 +Subject: [PATCH 25/29] anolis: migration/ram: Accelerate the loading of CSV + guest's encrypted pages + +When memory encryption is enabled, the guest memory will be encrypted with +the guest specific key. The patch introduces an accelerate solution which +queued the pages into list and load them togather by COMMAND_BATCH. + +Signed-off-by: hanliyang +--- + migration/ram.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/migration/ram.c b/migration/ram.c +index 7e2d4e7df..90f1bda83 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -1387,6 +1387,14 @@ static int load_encrypted_data(QEMUFile *f, uint8_t *ptr) + return ops->load_incoming_page(f, ptr); + } else if (flag == RAM_SAVE_SHARED_REGIONS_LIST) { + return ops->load_incoming_shared_regions_list(f); ++ } else if (flag == RAM_SAVE_ENCRYPTED_PAGE_BATCH) { ++ return ops->queue_incoming_page(f, ptr); ++ } else if (flag == RAM_SAVE_ENCRYPTED_PAGE_BATCH_END) { ++ if (ops->queue_incoming_page(f, ptr)) { ++ error_report("Failed to queue incoming data"); ++ return -EINVAL; ++ } ++ return ops->load_queued_incoming_pages(f); + } else { + error_report("unknown encrypted flag %x", flag); + return 1; +-- +2.31.1 + diff --git a/1063-anolis-target-i386-csv-Add-support-for-migrate-VMSA-.patch b/1063-anolis-target-i386-csv-Add-support-for-migrate-VMSA-.patch new file mode 100644 index 0000000..166fb58 --- /dev/null +++ b/1063-anolis-target-i386-csv-Add-support-for-migrate-VMSA-.patch @@ -0,0 +1,416 @@ +From 133fe2e6a250623ccc9305fdacc1e8d990878fb4 Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Tue, 7 Jun 2022 15:19:32 +0800 +Subject: [PATCH 26/29] anolis: target/i386/csv: Add support for migrate VMSA + for CSV2 guest + +CSV2 can protect guest's cpu state through memory encryption. Each +vcpu has its corresponding memory, which is also called VMSA, and +is encrypted by guest's specific encrytion key. + +When CSV2 guest exit to host, the vcpu's state will be encrypted +and saved to VMSA, and the VMSA will be decrypted and loaded to cpu +when the guest's vcpu running at next time. + +If user wants to migrate one CSV2 guest to target machine, the VMSA +of the vcpus also should be migrated to target. CSV firmware provides +SEND_UPDATE_VMSA/RECEIVE_UPDATE_VMSA API through which VMSA can be +converted into secure data and transmitted to the remote end (for +example, network transmission). + +The migration of cpu state is identified by CPUState.cpu_index which +may not equals to vcpu id from KVM's perspective. + +When migrate the VMSA, the source QEMU will invoke SEND_UPDATE_VMSA to +generate data correspond to VMSA, after target QEMU received the data, +it will calc target vcpu id in the KVM by CPUState.cpu_index, and then +invoke RECEIVE_UPDATE_VMSA to restore VMSA correspond to vcpu. + +Signed-off-by: hanliyang +--- + include/exec/confidential-guest-support.h | 6 + + linux-headers/linux/kvm.h | 16 ++ + migration/ram.c | 30 ++++ + target/i386/sev.c | 196 ++++++++++++++++++++++ + target/i386/sev.h | 3 + + target/i386/trace-events | 2 + + 6 files changed, 253 insertions(+) + +diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h +index f6a30fab3..a069bad9d 100644 +--- a/include/exec/confidential-guest-support.h ++++ b/include/exec/confidential-guest-support.h +@@ -90,6 +90,12 @@ struct ConfidentialGuestMemoryEncryptionOps { + + /* Load the incoming encrypted pages queued in list into guest memory */ + int (*load_queued_incoming_pages)(QEMUFile *f); ++ ++ /* Write the encrypted cpu state */ ++ int (*save_outgoing_cpu_state)(QEMUFile *f); ++ ++ /* Load the encrypted cpu state */ ++ int (*load_incoming_cpu_state)(QEMUFile *f); + }; + + typedef struct ConfidentialGuestSupportClass { +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 951afc8b2..e5d282c75 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -1904,6 +1904,14 @@ struct kvm_sev_send_update_data { + __u32 trans_len; + }; + ++struct kvm_sev_send_update_vmsa { ++ __u32 vcpu_id; ++ __u64 hdr_uaddr; ++ __u32 hdr_len; ++ __u64 trans_uaddr; ++ __u32 trans_len; ++}; ++ + struct kvm_sev_receive_start { + __u32 handle; + __u32 policy; +@@ -1922,6 +1930,14 @@ struct kvm_sev_receive_update_data { + __u32 trans_len; + }; + ++struct kvm_sev_receive_update_vmsa { ++ __u32 vcpu_id; ++ __u64 hdr_uaddr; ++ __u32 hdr_len; ++ __u64 trans_uaddr; ++ __u32 trans_len; ++}; ++ + /* CSV command */ + enum csv_cmd_id { + KVM_CSV_NR_MIN = 0xc0, +diff --git a/migration/ram.c b/migration/ram.c +index 90f1bda83..8c61eecb9 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -1371,6 +1371,23 @@ static int ram_save_shared_region_list(RAMState *rs, QEMUFile *f) + return ops->save_outgoing_shared_regions_list(rs->f); + } + ++/** ++ * ram_save_encrypted_cpu_state: send the encrypted cpu state ++ */ ++static int ram_save_encrypted_cpu_state(RAMState *rs, QEMUFile *f) ++{ ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ ConfidentialGuestSupportClass *cgs_class = ++ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); ++ struct ConfidentialGuestMemoryEncryptionOps *ops = ++ cgs_class->memory_encryption_ops; ++ ++ save_page_header(rs, rs->f, rs->last_seen_block, ++ RAM_SAVE_FLAG_ENCRYPTED_DATA); ++ qemu_put_be32(rs->f, RAM_SAVE_ENCRYPTED_CPU_STATE); ++ return ops->save_outgoing_cpu_state(rs->f); ++} ++ + static int load_encrypted_data(QEMUFile *f, uint8_t *ptr) + { + MachineState *ms = MACHINE(qdev_get_machine()); +@@ -1395,6 +1412,8 @@ static int load_encrypted_data(QEMUFile *f, uint8_t *ptr) + return -EINVAL; + } + return ops->load_queued_incoming_pages(f); ++ } else if (flag == RAM_SAVE_ENCRYPTED_CPU_STATE) { ++ return ops->load_incoming_cpu_state(f); + } else { + error_report("unknown encrypted flag %x", flag); + return 1; +@@ -3507,6 +3526,17 @@ static int ram_save_complete(QEMUFile *f, void *opaque) + if (memcrypt_enabled()) { + ret = ram_save_shared_region_list(rs, f); + } ++ ++ /* ++ * send the encrypted cpu state, for example, CSV2 guest's ++ * vmsa for each vcpu. ++ */ ++ if (!ret && memcrypt_enabled() && is_hygon_cpu()) { ++ ret = ram_save_encrypted_cpu_state(rs, f); ++ if (ret) { ++ error_report("Failed to save encrypted cpu state"); ++ } ++ } + } + + if (ret < 0) { +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 2f7d98be6..9cdf3e6bf 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -100,6 +100,10 @@ struct SevGuestState { + gchar *send_packet_hdr; + size_t send_packet_hdr_len; + ++ /* needed by live migration of HYGON CSV2 guest */ ++ gchar *send_vmsa_packet_hdr; ++ size_t send_vmsa_packet_hdr_len; ++ + uint32_t reset_cs; + uint32_t reset_ip; + bool reset_data_valid; +@@ -193,6 +197,9 @@ static const char *const sev_fw_errlist[] = { + #define SHARED_REGION_LIST_CONT 0x1 + #define SHARED_REGION_LIST_END 0x2 + ++#define ENCRYPTED_CPU_STATE_CONT 0x1 ++#define ENCRYPTED_CPU_STATE_END 0x2 ++ + static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { + .save_setup = sev_save_setup, + .save_outgoing_page = sev_save_outgoing_page, +@@ -204,6 +211,8 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { + .save_queued_outgoing_pages = csv_save_queued_outgoing_pages, + .queue_incoming_page = csv_queue_incoming_page, + .load_queued_incoming_pages = csv_load_queued_incoming_pages, ++ .save_outgoing_cpu_state = csv_save_outgoing_cpu_state, ++ .load_incoming_cpu_state = csv_load_incoming_cpu_state, + }; + + static int +@@ -1020,6 +1029,9 @@ sev_send_finish(void) + } + + g_free(sev_guest->send_packet_hdr); ++ if (sev_es_enabled() && is_hygon_cpu()) { ++ g_free(sev_guest->send_vmsa_packet_hdr); ++ } + sev_set_guest_state(sev_guest, SEV_STATE_RUNNING); + } + +@@ -2214,6 +2226,190 @@ int csv_load_queued_incoming_pages(QEMUFile *f) + return csv_receive_update_data_batch(s); + } + ++static int ++sev_send_vmsa_get_packet_len(int *fw_err) ++{ ++ int ret; ++ struct kvm_sev_send_update_vmsa update = { 0, }; ++ ++ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_UPDATE_VMSA, ++ &update, fw_err); ++ if (*fw_err != SEV_RET_INVALID_LEN) { ++ ret = -1; ++ error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", ++ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); ++ goto err; ++ } ++ ++ ret = update.hdr_len; ++ ++err: ++ return ret; ++} ++ ++static int ++sev_send_update_vmsa(SevGuestState *s, QEMUFile *f, uint32_t cpu_id, ++ uint32_t cpu_index, uint32_t size) ++{ ++ int ret, fw_error; ++ guchar *trans = NULL; ++ struct kvm_sev_send_update_vmsa update = {}; ++ ++ /* ++ * If this is first call then query the packet header bytes and allocate ++ * the packet buffer. ++ */ ++ if (!s->send_vmsa_packet_hdr) { ++ s->send_vmsa_packet_hdr_len = sev_send_vmsa_get_packet_len(&fw_error); ++ if (s->send_vmsa_packet_hdr_len < 1) { ++ error_report("%s: SEND_UPDATE_VMSA fw_error=%d '%s'", ++ __func__, fw_error, fw_error_to_str(fw_error)); ++ return 1; ++ } ++ ++ s->send_vmsa_packet_hdr = g_new(gchar, s->send_vmsa_packet_hdr_len); ++ } ++ ++ /* allocate transport buffer */ ++ trans = g_new(guchar, size); ++ ++ update.vcpu_id = cpu_id; ++ update.hdr_uaddr = (uintptr_t)s->send_vmsa_packet_hdr; ++ update.hdr_len = s->send_vmsa_packet_hdr_len; ++ update.trans_uaddr = (uintptr_t)trans; ++ update.trans_len = size; ++ ++ trace_kvm_sev_send_update_vmsa(cpu_id, cpu_index, trans, size); ++ ++ ret = sev_ioctl(s->sev_fd, KVM_SEV_SEND_UPDATE_VMSA, &update, &fw_error); ++ if (ret) { ++ error_report("%s: SEND_UPDATE_VMSA ret=%d fw_error=%d '%s'", ++ __func__, ret, fw_error, fw_error_to_str(fw_error)); ++ goto err; ++ } ++ ++ /* ++ * Migration of vCPU's VMState according to the instance_id ++ * (i.e. CPUState.cpu_index) ++ */ ++ qemu_put_be32(f, sizeof(uint32_t)); ++ qemu_put_buffer(f, (uint8_t *)&cpu_index, sizeof(uint32_t)); ++ ++ qemu_put_be32(f, update.hdr_len); ++ qemu_put_buffer(f, (uint8_t *)update.hdr_uaddr, update.hdr_len); ++ ++ qemu_put_be32(f, update.trans_len); ++ qemu_put_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); ++ ++err: ++ g_free(trans); ++ return ret; ++} ++ ++int csv_save_outgoing_cpu_state(QEMUFile *f) ++{ ++ SevGuestState *s = sev_guest; ++ CPUState *cpu; ++ int ret = 0; ++ ++ /* Only support migrate VMSAs for HYGON CSV2 guest */ ++ if (!sev_es_enabled() || !is_hygon_cpu()) { ++ return 0; ++ } ++ ++ CPU_FOREACH(cpu) { ++ qemu_put_be32(f, ENCRYPTED_CPU_STATE_CONT); ++ ret = sev_send_update_vmsa(s, f, kvm_arch_vcpu_id(cpu), ++ cpu->cpu_index, TARGET_PAGE_SIZE); ++ if (ret) { ++ goto err; ++ } ++ } ++ ++ qemu_put_be32(f, ENCRYPTED_CPU_STATE_END); ++ ++err: ++ return ret; ++} ++ ++static int sev_receive_update_vmsa(QEMUFile *f) ++{ ++ int ret = 1, fw_error = 0; ++ CPUState *cpu; ++ uint32_t cpu_index, cpu_id = 0; ++ gchar *hdr = NULL, *trans = NULL; ++ struct kvm_sev_receive_update_vmsa update = {}; ++ ++ /* get cpu index buffer */ ++ assert(qemu_get_be32(f) == sizeof(uint32_t)); ++ qemu_get_buffer(f, (uint8_t *)&cpu_index, sizeof(uint32_t)); ++ ++ CPU_FOREACH(cpu) { ++ if (cpu->cpu_index == cpu_index) { ++ cpu_id = kvm_arch_vcpu_id(cpu); ++ break; ++ } ++ } ++ update.vcpu_id = cpu_id; ++ ++ /* get packet header */ ++ update.hdr_len = qemu_get_be32(f); ++ if (!check_blob_length(update.hdr_len)) { ++ return 1; ++ } ++ ++ hdr = g_new(gchar, update.hdr_len); ++ qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len); ++ update.hdr_uaddr = (uintptr_t)hdr; ++ ++ /* get transport buffer */ ++ update.trans_len = qemu_get_be32(f); ++ if (!check_blob_length(update.trans_len)) { ++ goto err; ++ } ++ ++ trans = g_new(gchar, update.trans_len); ++ update.trans_uaddr = (uintptr_t)trans; ++ qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); ++ ++ trace_kvm_sev_receive_update_vmsa(cpu_id, cpu_index, ++ trans, update.trans_len, hdr, update.hdr_len); ++ ++ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_RECEIVE_UPDATE_VMSA, ++ &update, &fw_error); ++ if (ret) { ++ error_report("Error RECEIVE_UPDATE_VMSA ret=%d fw_error=%d '%s'", ++ ret, fw_error, fw_error_to_str(fw_error)); ++ } ++ ++err: ++ g_free(trans); ++ g_free(hdr); ++ return ret; ++} ++ ++int csv_load_incoming_cpu_state(QEMUFile *f) ++{ ++ int status, ret = 0; ++ ++ /* Only support migrate VMSAs for HYGON CSV2 guest */ ++ if (!sev_es_enabled() || !is_hygon_cpu()) { ++ return 0; ++ } ++ ++ status = qemu_get_be32(f); ++ while (status == ENCRYPTED_CPU_STATE_CONT) { ++ ret = sev_receive_update_vmsa(f); ++ if (ret) { ++ break; ++ } ++ ++ status = qemu_get_be32(f); ++ } ++ ++ return ret; ++} ++ + static const QemuUUID sev_hash_table_header_guid = { + .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, + 0xd4, 0x11, 0xfd, 0x21) +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 345dffac5..8b38567c3 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -44,6 +44,7 @@ typedef struct SevKernelLoaderContext { + #define RAM_SAVE_ENCRYPTED_PAGE_BATCH 0x4 + #define RAM_SAVE_ENCRYPTED_PAGE_BATCH_END 0x5 + #define CSV_OUTGOING_PAGE_WINDOW_SIZE (4094 * TARGET_PAGE_SIZE) ++#define RAM_SAVE_ENCRYPTED_CPU_STATE 0x6 + + #ifdef CONFIG_SEV + bool sev_enabled(void); +@@ -82,6 +83,8 @@ int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); + int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); + int csv_queue_incoming_page(QEMUFile *f, uint8_t *ptr); + int csv_load_queued_incoming_pages(QEMUFile *f); ++int csv_save_outgoing_cpu_state(QEMUFile *f); ++int csv_load_incoming_cpu_state(QEMUFile *f); + + struct sev_ops { + int (*sev_ioctl)(int fd, int cmd, void *data, int *error); +diff --git a/target/i386/trace-events b/target/i386/trace-events +index e32b0319b..60a4609c0 100644 +--- a/target/i386/trace-events ++++ b/target/i386/trace-events +@@ -17,6 +17,8 @@ kvm_sev_send_finish(void) "" + kvm_sev_receive_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p" + kvm_sev_receive_update_data(void *src, void *dst, int len, void *hdr, int hdr_len) "guest %p trans %p len %d hdr %p hdr_len %d" + kvm_sev_receive_finish(void) "" ++kvm_sev_send_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *dst, int len) "cpu_id %d cpu_index %d trans %p len %d" ++kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int len, void *hdr, int hdr_len) "cpu_id %d cpu_index %d trans %p len %d hdr %p hdr_len %d" + + # csv.c + kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 +-- +2.31.1 + diff --git a/1064-anolis-target-i386-get-set-migrate-GHCB-state.patch b/1064-anolis-target-i386-get-set-migrate-GHCB-state.patch new file mode 100644 index 0000000..a58e394 --- /dev/null +++ b/1064-anolis-target-i386-get-set-migrate-GHCB-state.patch @@ -0,0 +1,175 @@ +From a95faafa015e094f7252ef35afb74933d07a9334 Mon Sep 17 00:00:00 2001 +From: panpingsheng +Date: Sat, 12 Jun 2021 15:15:29 +0800 +Subject: [PATCH 27/29] anolis: target/i386: get/set/migrate GHCB state + +GHCB state is necessary to CSV2 guest when migrating to target. + +Add GHCB related definition, it also adds corresponding part +to kvm_get/put, and vmstate. + +Signed-off-by: hanliyang +--- + include/sysemu/kvm.h | 1 + + linux-headers/linux/kvm.h | 1 + + target/i386/cpu.h | 4 ++++ + target/i386/kvm/kvm.c | 11 +++++++++++ + target/i386/machine.c | 24 ++++++++++++++++++++++++ + target/i386/sev.c | 10 ++++++++++ + 6 files changed, 51 insertions(+) + +diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h +index 7b22aeb6a..9f8099f48 100644 +--- a/include/sysemu/kvm.h ++++ b/include/sysemu/kvm.h +@@ -46,6 +46,7 @@ extern bool kvm_readonly_mem_allowed; + extern bool kvm_direct_msi_allowed; + extern bool kvm_ioeventfd_any_length_allowed; + extern bool kvm_msi_use_devid; ++extern bool kvm_has_msr_ghcb; + + #define kvm_enabled() (kvm_allowed) + /** +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index e5d282c75..4a177f81d 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -1154,6 +1154,7 @@ struct kvm_ppc_resize_hpt { + #define KVM_CAP_S390_PROTECTED_DUMP 217 + #define KVM_CAP_S390_ZPCI_OP 221 + #define KVM_CAP_S390_CPU_TOPOLOGY 222 ++#define KVM_CAP_SEV_ES_GHCB 500 + + #define KVM_EXIT_HYPERCALL_VALID_MASK (1 << KVM_HC_MAP_GPA_RANGE) + +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 5d2ddd81b..5c476a029 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -505,6 +505,8 @@ typedef enum X86Seg { + + #define MSR_VM_HSAVE_PA 0xc0010117 + ++#define MSR_AMD64_SEV_ES_GHCB 0xc0010130 ++ + #define MSR_IA32_XFD 0x000001c4 + #define MSR_IA32_XFD_ERR 0x000001c5 + +@@ -1732,6 +1734,8 @@ typedef struct CPUX86State { + TPRAccess tpr_access_type; + + unsigned nr_dies; ++ ++ uint64_t ghcb_gpa; + } CPUX86State; + + struct kvm_msrs; +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index f0b61ec3c..fb85cc698 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -3346,6 +3346,10 @@ static int kvm_put_msrs(X86CPU *cpu, int level) + } + } + ++ if (kvm_has_msr_ghcb) { ++ kvm_msr_entry_add(cpu, MSR_AMD64_SEV_ES_GHCB, env->ghcb_gpa); ++ } ++ + return kvm_buf_set_msrs(cpu); + } + +@@ -3686,6 +3690,10 @@ static int kvm_get_msrs(X86CPU *cpu) + kvm_msr_entry_add(cpu, MSR_IA32_XFD_ERR, 0); + } + ++ if (kvm_has_msr_ghcb) { ++ kvm_msr_entry_add(cpu, MSR_AMD64_SEV_ES_GHCB, 0); ++ } ++ + ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, cpu->kvm_msr_buf); + if (ret < 0) { + return ret; +@@ -3991,6 +3999,9 @@ static int kvm_get_msrs(X86CPU *cpu) + case MSR_IA32_XFD_ERR: + env->msr_xfd_err = msrs[i].data; + break; ++ case MSR_AMD64_SEV_ES_GHCB: ++ env->ghcb_gpa = msrs[i].data; ++ break; + } + } + +diff --git a/target/i386/machine.c b/target/i386/machine.c +index 3977e9d8f..8aa54432d 100644 +--- a/target/i386/machine.c ++++ b/target/i386/machine.c +@@ -1497,6 +1497,27 @@ static const VMStateDescription vmstate_amx_xtile = { + }; + #endif + ++#if defined(CONFIG_KVM) && defined(TARGET_X86_64) ++static bool msr_ghcb_gpa_needed(void *opaque) ++{ ++ X86CPU *cpu = opaque; ++ CPUX86State *env = &cpu->env; ++ ++ return env->ghcb_gpa != 0; ++} ++ ++static const VMStateDescription vmstate_msr_ghcb_gpa = { ++ .name = "cpu/svm_msr_ghcb_gpa", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .needed = msr_ghcb_gpa_needed, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT64(env.ghcb_gpa, X86CPU), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++#endif ++ + const VMStateDescription vmstate_x86_cpu = { + .name = "cpu", + .version_id = 12, +@@ -1638,6 +1659,9 @@ const VMStateDescription vmstate_x86_cpu = { + &vmstate_msr_xfd, + #ifdef TARGET_X86_64 + &vmstate_amx_xtile, ++#endif ++#if defined(CONFIG_KVM) && defined(TARGET_X86_64) ++ &vmstate_msr_ghcb_gpa, + #endif + NULL + } +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 9cdf3e6bf..26b6e84d3 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -215,6 +215,8 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { + .load_incoming_cpu_state = csv_load_incoming_cpu_state, + }; + ++bool kvm_has_msr_ghcb; ++ + static int + sev_ioctl(int fd, int cmd, void *data, int *error) + { +@@ -1174,6 +1176,14 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; + QTAILQ_INIT(&sev->shared_regions_list); + ++ /* Determine whether support MSR_AMD64_SEV_ES_GHCB */ ++ if (sev_es_enabled()) { ++ kvm_has_msr_ghcb = ++ kvm_vm_check_extension(kvm_state, KVM_CAP_SEV_ES_GHCB); ++ } else { ++ kvm_has_msr_ghcb = false; ++ } ++ + cgs->ready = true; + + return 0; +-- +2.31.1 + diff --git a/1065-anolis-target-i386-kvm-Return-resettable-when-emulat.patch b/1065-anolis-target-i386-kvm-Return-resettable-when-emulat.patch new file mode 100644 index 0000000..966d6ff --- /dev/null +++ b/1065-anolis-target-i386-kvm-Return-resettable-when-emulat.patch @@ -0,0 +1,39 @@ +From 84ea1a98ae7cb888eba8f9be9f51955a4402355c Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Sun, 19 Jun 2022 16:49:45 +0800 +Subject: [PATCH 28/29] anolis: target/i386/kvm: Return resettable when emulate + HYGON CSV2 guest + +SEV-ES guest will be terminated by QEMU when receive reboot request. +In order to support reboot for CSV2 guest, report resettable in +kvm_arch_cpu_check_are_resettable(). + +Signed-off-by: hanliyang +--- + target/i386/kvm/kvm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index fb85cc698..19c622bb0 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -30,6 +30,7 @@ + #include "sysemu/runstate.h" + #include "kvm_i386.h" + #include "sev.h" ++#include "csv.h" + #include "hyperv.h" + #include "hyperv-proto.h" + +@@ -5363,7 +5364,7 @@ bool kvm_has_waitpkg(void) + + bool kvm_arch_cpu_check_are_resettable(void) + { +- return !sev_es_enabled(); ++ return !(sev_es_enabled() && !is_hygon_cpu()) && !csv_enabled(); + } + + #define ARCH_REQ_XCOMP_GUEST_PERM 0x1025 +-- +2.31.1 + diff --git a/1066-anolis-kvm-Add-support-for-CSV2-reboot.patch b/1066-anolis-kvm-Add-support-for-CSV2-reboot.patch new file mode 100644 index 0000000..3c246b0 --- /dev/null +++ b/1066-anolis-kvm-Add-support-for-CSV2-reboot.patch @@ -0,0 +1,170 @@ +From a165dedbb9121f948738e5265198410487aa7acf Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Thu, 15 Apr 2021 08:32:24 -0400 +Subject: [PATCH 29/29] anolis: kvm: Add support for CSV2 reboot + +Linux will set vcpu.arch.guest_state_protected to true after execute +LAUNCH_UPDATE_VMSA successfully, and then KVM will prevent any changes +to VMCB State Save Area. + +In order to support CSV2 guest reboot, calls cpus_control_pre_system_reset() +to set vcpu.arch.guest_state_protected to false, and calls +cpus_control_post_system_reset() to restore VMSA of guest's vcpu with +data generated by LAUNCH_UPDATE_VMSA. + +In addition, for memory encrypted guest, additional works may be +required during system reset, such as flushing the cache. The function +cpus_control_post_system_reset() hints linux to flush caches of guest +memory. + +Signed-off-by: hanliyang +--- + accel/kvm/kvm-accel-ops.c | 3 +++ + accel/kvm/kvm-all.c | 10 ++++++++++ + accel/kvm/kvm-cpus.h | 3 +++ + include/sysemu/accel-ops.h | 3 +++ + include/sysemu/cpus.h | 2 ++ + linux-headers/linux/kvm.h | 4 ++++ + softmmu/cpus.c | 14 ++++++++++++++ + softmmu/runstate.c | 4 ++++ + 8 files changed, 43 insertions(+) + +diff --git a/accel/kvm/kvm-accel-ops.c b/accel/kvm/kvm-accel-ops.c +index 7516c67a3..9602f9609 100644 +--- a/accel/kvm/kvm-accel-ops.c ++++ b/accel/kvm/kvm-accel-ops.c +@@ -83,6 +83,9 @@ static void kvm_accel_ops_class_init(ObjectClass *oc, void *data) + ops->synchronize_post_init = kvm_cpu_synchronize_post_init; + ops->synchronize_state = kvm_cpu_synchronize_state; + ops->synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm; ++ ++ ops->control_pre_system_reset = kvm_cpus_control_pre_system_reset; ++ ops->control_post_system_reset = kvm_cpus_control_post_system_reset; + } + + static const TypeInfo kvm_accel_ops_type = { +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index 6d63f0ab0..10af4170d 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -2848,6 +2848,16 @@ void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu) + run_on_cpu(cpu, do_kvm_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL); + } + ++void kvm_cpus_control_pre_system_reset(void) ++{ ++ kvm_vm_ioctl(kvm_state, KVM_CONTROL_VCPU_PRE_SYSTEM_RESET, NULL); ++} ++ ++void kvm_cpus_control_post_system_reset(void) ++{ ++ kvm_vm_ioctl(kvm_state, KVM_CONTROL_VCPU_POST_SYSTEM_RESET, NULL); ++} ++ + #ifdef KVM_HAVE_MCE_INJECTION + static __thread void *pending_sigbus_addr; + static __thread int pending_sigbus_code; +diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h +index bf0bd1bee..8ba363e0b 100644 +--- a/accel/kvm/kvm-cpus.h ++++ b/accel/kvm/kvm-cpus.h +@@ -19,4 +19,7 @@ void kvm_cpu_synchronize_post_reset(CPUState *cpu); + void kvm_cpu_synchronize_post_init(CPUState *cpu); + void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu); + ++void kvm_cpus_control_pre_system_reset(void); ++void kvm_cpus_control_post_system_reset(void); ++ + #endif /* KVM_CPUS_H */ +diff --git a/include/sysemu/accel-ops.h b/include/sysemu/accel-ops.h +index 032f6979d..43893c1a4 100644 +--- a/include/sysemu/accel-ops.h ++++ b/include/sysemu/accel-ops.h +@@ -40,6 +40,9 @@ struct AccelOpsClass { + + int64_t (*get_virtual_clock)(void); + int64_t (*get_elapsed_ticks)(void); ++ ++ void (*control_pre_system_reset)(void); ++ void (*control_post_system_reset)(void); + }; + + #endif /* ACCEL_OPS_H */ +diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h +index 868f1192d..70d6e8ad3 100644 +--- a/include/sysemu/cpus.h ++++ b/include/sysemu/cpus.h +@@ -42,6 +42,8 @@ extern int icount_align_option; + void qemu_cpu_kick_self(void); + + bool cpus_are_resettable(void); ++void cpus_control_pre_system_reset(void); ++void cpus_control_post_system_reset(void); + + void cpu_synchronize_all_states(void); + void cpu_synchronize_all_post_reset(void); +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 4a177f81d..d5278df1c 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -1528,6 +1528,10 @@ struct kvm_s390_ucas_mapping { + #define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr) + #define KVM_HAS_DEVICE_ATTR _IOW(KVMIO, 0xe3, struct kvm_device_attr) + ++/* ioctls for control vcpu setup during system reset */ ++#define KVM_CONTROL_VCPU_PRE_SYSTEM_RESET _IO(KVMIO, 0xe8) ++#define KVM_CONTROL_VCPU_POST_SYSTEM_RESET _IO(KVMIO, 0xe9) ++ + /* + * ioctls for vcpu fds + */ +diff --git a/softmmu/cpus.c b/softmmu/cpus.c +index 071085f84..319a72d92 100644 +--- a/softmmu/cpus.c ++++ b/softmmu/cpus.c +@@ -200,6 +200,20 @@ bool cpus_are_resettable(void) + return cpu_check_are_resettable(); + } + ++void cpus_control_pre_system_reset(void) ++{ ++ if (cpus_accel->control_pre_system_reset) { ++ cpus_accel->control_pre_system_reset(); ++ } ++} ++ ++void cpus_control_post_system_reset(void) ++{ ++ if (cpus_accel->control_post_system_reset) { ++ cpus_accel->control_post_system_reset(); ++ } ++} ++ + int64_t cpus_get_virtual_clock(void) + { + /* +diff --git a/softmmu/runstate.c b/softmmu/runstate.c +index 10d9b7365..4b9c9f9e0 100644 +--- a/softmmu/runstate.c ++++ b/softmmu/runstate.c +@@ -437,6 +437,8 @@ void qemu_system_reset(ShutdownCause reason) + + mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL; + ++ cpus_control_pre_system_reset(); ++ + cpu_synchronize_all_states(); + + if (mc && mc->reset) { +@@ -448,6 +450,8 @@ void qemu_system_reset(ShutdownCause reason) + qapi_event_send_reset(shutdown_caused_by_guest(reason), reason); + } + cpu_synchronize_all_post_reset(); ++ ++ cpus_control_post_system_reset(); + } + + /* +-- +2.31.1 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index ca1c0ec..d46b318 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -943,6 +943,35 @@ Patch1034: 0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch Patch1035: 0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch Patch1036: 0007-anolis-target-i386-csv-load-initial-image-to-private.patch Patch1037: 0008-anolis-vga-force-full-update-for-CSV-guest.patch +Patch1038: 1038-doc-update-AMD-SEV-to-include-Live-migration-flow.patch +Patch1039: 1039-migration.json-add-AMD-SEV-specific-migration-parame.patch +Patch1040: 1040-confidential-guest-support-introduce-ConfidentialGue.patch +Patch1041: 1041-target-i386-sev-provide-callback-to-setup-outgoing-c.patch +Patch1042: 1042-target-i386-sev-do-not-create-launch-context-for-an-.patch +Patch1043: 1043-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch +Patch1044: 1044-target-i386-sev-add-support-to-load-incoming-encrypt.patch +Patch1045: 1045-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch +Patch1046: 1046-migration-add-support-to-migrate-shared-regions-list.patch +Patch1047: 1047-migration-ram-add-support-to-send-encrypted-pages.patch +Patch1048: 1048-migration-ram-Force-encrypted-status-for-flash0-flas.patch +Patch1049: 1049-migration-for-SEV-live-migration-bump-downtime-limit.patch +Patch1050: 1050-i386-kvm-Add-support-for-MSR-filtering.patch +Patch1051: 1051-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch +Patch1052: 1052-anolis-migration-ram-Force-encrypted-status-for-VGA-.patch +Patch1053: 1053-anolis-target-i386-sev-Clear-shared_regions_list-whe.patch +Patch1054: 1054-anolis-migration-ram-Fix-calculation-of-gfn-correpon.patch +Patch1055: 1055-anolis-target-i386-csv-Move-is_hygon_cpu-to-header-f.patch +Patch1056: 1056-anolis-target-i386-csv-Read-cert-chain-from-file-whe.patch +Patch1057: 1057-anolis-target-i386-csv-add-support-to-queue-the-outg.patch +Patch1058: 1058-anolis-target-i386-csv-add-support-to-encrypt-the-ou.patch +Patch1059: 1059-anolis-target-i386-csv-add-support-to-queue-the-inco.patch +Patch1060: 1060-anolis-target-i386-csv-add-support-to-load-incoming-.patch +Patch1061: 1061-anolis-migration-ram-Accelerate-the-transmission-of-.patch +Patch1062: 1062-anolis-migration-ram-Accelerate-the-loading-of-CSV-g.patch +Patch1063: 1063-anolis-target-i386-csv-Add-support-for-migrate-VMSA-.patch +Patch1064: 1064-anolis-target-i386-get-set-migrate-GHCB-state.patch +Patch1065: 1065-anolis-target-i386-kvm-Return-resettable-when-emulat.patch +Patch1066: 1066-anolis-kvm-Add-support-for-CSV2-reboot.patch BuildRequires: wget BuildRequires: rpm-build @@ -2213,6 +2242,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : - 0007-anolis-target-i386-csv-load-initial-image-to-private.patch (jiangxin@hygon.cn) - 0008-anolis-vga-force-full-update-for-CSV-guest.patch (jiangxin@hygon.cn) (Hygon CSV3 feature) +- Support Hygon CSV/CSV2 live migration, CSV2 reboot (hanliyang@hygon.cn) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] -- Gitee From b777dc5db17c75fc6a8dbf150c64d73e718a9aac Mon Sep 17 00:00:00 2001 From: Xin Jiang Date: Fri, 8 Dec 2023 17:29:28 +0800 Subject: [PATCH 11/17] Support Hygon CSV3 live migration Like CSV/CSV2 live migration, four new migration commands are added to support CSV3 migration. KVM_CSV_{SEND, RECEIVE}_ENCRYPT_DATA cmds are used to migrate guest's pages. KVM_CSV_{SEND, RECEIVE}_ENCRYPT_CONTEXT cmds are used to migration guest's runtime context. Signed-off-by: Xin Jiang --- ...-map-shared-region-for-CSV-virtual-m.patch | 384 +++++++++++++++ ...ders-update-kernel-headers-to-includ.patch | 79 +++ ...add-support-to-migrate-the-outgoing-.patch | 453 ++++++++++++++++++ ...add-support-to-migrate-the-incoming-.patch | 204 ++++++++ ...add-support-to-migrate-the-outgoing-.patch | 137 ++++++ ...add-support-to-migrate-the-incoming-.patch | 109 +++++ qemu-kvm.spec | 7 + 7 files changed, 1373 insertions(+) create mode 100644 1067-anolis-vfio-only-map-shared-region-for-CSV-virtual-m.patch create mode 100644 1068-anolis-linux-headers-update-kernel-headers-to-includ.patch create mode 100644 1069-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch create mode 100644 1070-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch create mode 100644 1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch create mode 100644 1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch diff --git a/1067-anolis-vfio-only-map-shared-region-for-CSV-virtual-m.patch b/1067-anolis-vfio-only-map-shared-region-for-CSV-virtual-m.patch new file mode 100644 index 0000000..6e1d418 --- /dev/null +++ b/1067-anolis-vfio-only-map-shared-region-for-CSV-virtual-m.patch @@ -0,0 +1,384 @@ +From 3b532188e4eac7fd291cf66970126a18af024364 Mon Sep 17 00:00:00 2001 +From: liuyafei +Date: Mon, 22 May 2023 20:37:40 +0800 +Subject: [PATCH 1067/1072] anolis: vfio: only map shared region for CSV + virtual machine + +qemu vfio listener map/unmap all of the virtual machine's memory. +It does not work for CSV virtual machine, as only shared memory +should be accessed by device. + +Change-Id: I3f281c28166a36f2bed8ea193523715af9ff3271 +--- + hw/vfio/common.c | 40 +++++++++- + include/exec/memory.h | 11 +++ + softmmu/memory.c | 18 +++++ + target/i386/csv-sysemu-stub.c | 10 +++ + target/i386/csv.c | 134 ++++++++++++++++++++++++++++++++++ + target/i386/csv.h | 12 +++ + target/i386/kvm/kvm.c | 2 + + 7 files changed, 225 insertions(+), 2 deletions(-) + +diff --git a/hw/vfio/common.c b/hw/vfio/common.c +index 080046e3f5..7cc03a7ef9 100644 +--- a/hw/vfio/common.c ++++ b/hw/vfio/common.c +@@ -41,6 +41,9 @@ + #include "qapi/error.h" + #include "migration/migration.h" + ++#include "target/i386/sev.h" ++#include "target/i386/csv.h" ++ + VFIOGroupList vfio_group_list = + QLIST_HEAD_INITIALIZER(vfio_group_list); + static QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces = +@@ -1251,6 +1254,30 @@ static void vfio_listener_log_global_stop(MemoryListener *listener) + vfio_set_dirty_page_tracking(container, false); + } + ++static SharedRegionListener *g_shl; ++static void shared_memory_listener_register(MemoryListener *listener, AddressSpace *as) ++{ ++ SharedRegionListener *shl; ++ ++ shl = g_new0(SharedRegionListener, 1); ++ ++ shl->listener = listener; ++ shl->as = as; ++ ++ shared_region_register_listener(shl); ++ g_shl = shl; ++} ++ ++static void shared_memory_listener_unregister(void) ++{ ++ SharedRegionListener *shl = g_shl; ++ ++ shared_region_unregister_listener(shl); ++ ++ g_free(shl); ++ g_shl = NULL; ++} ++ + static int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, + uint64_t size, ram_addr_t ram_addr) + { +@@ -1453,7 +1480,12 @@ static const MemoryListener vfio_memory_listener = { + + static void vfio_listener_release(VFIOContainer *container) + { +- memory_listener_unregister(&container->listener); ++ if (csv_enabled()) { ++ shared_memory_listener_unregister(); ++ } else { ++ memory_listener_unregister(&container->listener); ++ } ++ + if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) { + memory_listener_unregister(&container->prereg_listener); + } +@@ -2183,7 +2215,11 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, + + container->listener = vfio_memory_listener; + +- memory_listener_register(&container->listener, container->space->as); ++ if (csv_enabled()) { ++ shared_memory_listener_register(&container->listener, container->space->as); ++ } else { ++ memory_listener_register(&container->listener, container->space->as); ++ } + + if (container->error) { + ret = -1; +diff --git a/include/exec/memory.h b/include/exec/memory.h +index 20f1b27377..d4bd90dfcc 100644 +--- a/include/exec/memory.h ++++ b/include/exec/memory.h +@@ -710,6 +710,17 @@ void ram_discard_manager_register_listener(RamDiscardManager *rdm, + void ram_discard_manager_unregister_listener(RamDiscardManager *rdm, + RamDiscardListener *rdl); + ++typedef struct SharedRegionListener SharedRegionListener; ++struct SharedRegionListener { ++ MemoryListener *listener; ++ AddressSpace *as; ++ QTAILQ_ENTRY(SharedRegionListener) next; ++}; ++ ++void shared_region_register_listener(SharedRegionListener *shl); ++void shared_region_unregister_listener(SharedRegionListener *shl); ++void *shared_region_listeners_get(void); ++ + typedef struct CoalescedMemoryRange CoalescedMemoryRange; + typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd; + +diff --git a/softmmu/memory.c b/softmmu/memory.c +index 7340e19ff5..b435bb4aa3 100644 +--- a/softmmu/memory.c ++++ b/softmmu/memory.c +@@ -47,6 +47,9 @@ static QTAILQ_HEAD(, MemoryListener) memory_listeners + static QTAILQ_HEAD(, AddressSpace) address_spaces + = QTAILQ_HEAD_INITIALIZER(address_spaces); + ++static QTAILQ_HEAD(, SharedRegionListener) shared_region_listeners ++ = QTAILQ_HEAD_INITIALIZER(shared_region_listeners); ++ + static GHashTable *flat_views; + + typedef struct AddrRange AddrRange; +@@ -2111,6 +2114,21 @@ void ram_discard_manager_unregister_listener(RamDiscardManager *rdm, + rdmc->unregister_listener(rdm, rdl); + } + ++void shared_region_register_listener(SharedRegionListener *shl) ++{ ++ QTAILQ_INSERT_TAIL(&shared_region_listeners, shl, next); ++} ++ ++void shared_region_unregister_listener(SharedRegionListener *shl) ++{ ++ QTAILQ_REMOVE(&shared_region_listeners, shl, next); ++} ++ ++void *shared_region_listeners_get(void) ++{ ++ return &shared_region_listeners; ++} ++ + void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client) + { + uint8_t mask = 1 << client; +diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c +index a5ce986e3c..96ca055270 100644 +--- a/target/i386/csv-sysemu-stub.c ++++ b/target/i386/csv-sysemu-stub.c +@@ -29,3 +29,13 @@ int csv_launch_encrypt_vmcb(void) + { + g_assert_not_reached(); + } ++ ++int csv_shared_region_dma_map(uint64_t start, uint64_t end) ++{ ++ return 0; ++} ++ ++void csv_shared_region_dma_unmap(uint64_t start, uint64_t end) ++{ ++ ++} +diff --git a/target/i386/csv.c b/target/i386/csv.c +index 161cad39ae..6d05382fb2 100644 +--- a/target/i386/csv.c ++++ b/target/i386/csv.c +@@ -24,6 +24,7 @@ + #include "cpu.h" + #include "sev.h" + #include "csv.h" ++#include "exec/address-spaces.h" + + CsvGuestState csv_guest = { 0 }; + +@@ -63,6 +64,8 @@ csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) + csv_guest.state = state; + csv_guest.sev_ioctl = ops->sev_ioctl; + csv_guest.fw_error_to_str = ops->fw_error_to_str; ++ QTAILQ_INIT(&csv_guest.dma_map_regions_list); ++ qemu_mutex_init(&csv_guest.dma_map_regions_list_mutex); + } + return 0; + } +@@ -163,3 +166,134 @@ csv_launch_encrypt_vmcb(void) + err: + return ret; + } ++ ++int csv_shared_region_dma_map(uint64_t start, uint64_t end) ++{ ++ MemoryRegionSection section; ++ AddressSpace *as; ++ QTAILQ_HEAD(, SharedRegionListener) *shared_region_listeners; ++ SharedRegionListener *shl; ++ MemoryListener *listener; ++ uint64_t size; ++ CsvGuestState *s = &csv_guest; ++ struct dma_map_region *region, *pos; ++ int ret = 0; ++ ++ if (!csv_enabled()) ++ return 0; ++ ++ if (end <= start) ++ return 0; ++ ++ shared_region_listeners = shared_region_listeners_get(); ++ if (QTAILQ_EMPTY(shared_region_listeners)) ++ return 0; ++ ++ size = end - start; ++ ++ qemu_mutex_lock(&s->dma_map_regions_list_mutex); ++ QTAILQ_FOREACH(pos, &s->dma_map_regions_list, list) { ++ if (start >= (pos->start + pos->size)) { ++ continue; ++ } else if ((start + size) <= pos->start) { ++ break; ++ } else { ++ goto end; ++ } ++ } ++ QTAILQ_FOREACH(shl, shared_region_listeners, next) { ++ listener = shl->listener; ++ as = shl->as; ++ section = memory_region_find(as->root, start, size); ++ if (!section.mr) { ++ goto end; ++ } ++ ++ if (!memory_region_is_ram(section.mr)) { ++ memory_region_unref(section.mr); ++ goto end; ++ } ++ ++ if (listener->region_add) { ++ listener->region_add(listener, §ion); ++ } ++ memory_region_unref(section.mr); ++ } ++ ++ region = g_malloc0(sizeof(*region)); ++ if (!region) { ++ ret = -1; ++ goto end; ++ } ++ region->start = start; ++ region->size = size; ++ ++ if (pos) { ++ QTAILQ_INSERT_BEFORE(pos, region, list); ++ } else { ++ QTAILQ_INSERT_TAIL(&s->dma_map_regions_list, region, list); ++ } ++ ++end: ++ qemu_mutex_unlock(&s->dma_map_regions_list_mutex); ++ return ret; ++} ++ ++void csv_shared_region_dma_unmap(uint64_t start, uint64_t end) ++{ ++ MemoryRegionSection section; ++ AddressSpace *as; ++ QTAILQ_HEAD(, SharedRegionListener) *shared_region_listeners; ++ SharedRegionListener *shl; ++ MemoryListener *listener; ++ uint64_t size; ++ CsvGuestState *s = &csv_guest; ++ struct dma_map_region *pos, *next_pos; ++ ++ if (!csv_enabled()) ++ return; ++ ++ if (end <= start) ++ return; ++ ++ shared_region_listeners = shared_region_listeners_get(); ++ if (QTAILQ_EMPTY(shared_region_listeners)) ++ return; ++ ++ size = end - start; ++ ++ qemu_mutex_lock(&s->dma_map_regions_list_mutex); ++ QTAILQ_FOREACH_SAFE(pos, &s->dma_map_regions_list, list, next_pos) { ++ uint64_t l, r; ++ uint64_t curr_end = pos->start + pos->size; ++ ++ l = MAX(start, pos->start); ++ r = MIN(start + size, pos->start + pos->size); ++ if (l < r) { ++ if ((start <= pos->start) && (start + size >= pos->start + pos->size)) { ++ QTAILQ_FOREACH(shl, shared_region_listeners, next) { ++ listener = shl->listener; ++ as = shl->as; ++ section = memory_region_find(as->root, pos->start, pos->size); ++ if (!section.mr) { ++ goto end; ++ } ++ if (listener->region_del) { ++ listener->region_del(listener, §ion); ++ } ++ memory_region_unref(section.mr); ++ } ++ ++ QTAILQ_REMOVE(&s->dma_map_regions_list, pos, list); ++ g_free(pos); ++ } ++ break; ++ } ++ if ((start + size) <= curr_end) { ++ break; ++ } ++ } ++end: ++ qemu_mutex_unlock(&s->dma_map_regions_list_mutex); ++ return; ++} +diff --git a/target/i386/csv.h b/target/i386/csv.h +index e51cc83022..6412c0c70b 100644 +--- a/target/i386/csv.h ++++ b/target/i386/csv.h +@@ -15,6 +15,8 @@ + #define QEMU_CSV_H + + #include "qapi/qapi-commands-misc-target.h" ++#include "qemu/thread.h" ++#include "qemu/queue.h" + + #ifdef CONFIG_SEV + +@@ -55,12 +57,19 @@ bool csv_enabled(void); + #define csv_enabled() 0 + #endif + ++struct dma_map_region { ++ uint64_t start, size; ++ QTAILQ_ENTRY(dma_map_region) list; ++}; ++ + struct CsvGuestState { + uint32_t policy; + int sev_fd; + void *state; + int (*sev_ioctl)(int fd, int cmd, void *data, int *error); + const char *(*fw_error_to_str)(int code); ++ QTAILQ_HEAD(, dma_map_region) dma_map_regions_list; ++ QemuMutex dma_map_regions_list_mutex; + }; + + typedef struct CsvGuestState CsvGuestState; +@@ -71,4 +80,7 @@ extern int csv_launch_encrypt_vmcb(void); + + int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); + ++int csv_shared_region_dma_map(uint64_t start, uint64_t end); ++void csv_shared_region_dma_unmap(uint64_t start, uint64_t end); ++ + #endif +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 6192bcd36e..090800257f 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -4626,8 +4626,10 @@ static int kvm_handle_exit_hypercall(X86CPU *cpu, struct kvm_run *run) + + if (enc) { + sev_remove_shared_regions_list(gfn_start, gfn_end); ++ csv_shared_region_dma_unmap(gpa, gfn_end << TARGET_PAGE_BITS); + } else { + sev_add_shared_regions_list(gfn_start, gfn_end); ++ csv_shared_region_dma_map(gpa, gfn_end << TARGET_PAGE_BITS); + } + } + return 0; +-- +2.17.1 + diff --git a/1068-anolis-linux-headers-update-kernel-headers-to-includ.patch b/1068-anolis-linux-headers-update-kernel-headers-to-includ.patch new file mode 100644 index 0000000..209ebd9 --- /dev/null +++ b/1068-anolis-linux-headers-update-kernel-headers-to-includ.patch @@ -0,0 +1,79 @@ +From 69976084e81798c275286b5bd3641d4b58896b72 Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Fri, 17 Jun 2022 09:25:19 +0800 +Subject: [PATCH 1068/1072] anolis: linux-headers: update kernel headers to + include CSV migration cmds + +Four new migration commands are added to support CSV migration. + +KVM_CSV_SEND_ENCRYPT_DATA/KVM_CSV_RECEIVE_ENCRYPT_DATA cmds are +used to migrate guest's pages. + +KVM_CSV_SEND_ENCRYPT_CONTEXT/KVM_CSV_RECEIVE_ENCRYPT_CONTEXT cmds +are used to migration guest's runtime context. + +Change-Id: Ib3b733c7b5713aa6a6648c65e03cf8c9618ff1af +Signed-off-by: Xin Jiang +--- + linux-headers/linux/kvm.h | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 1a2c3ea87d..cbf4fe4ecb 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -1842,6 +1842,12 @@ enum csv_cmd_id { + KVM_CSV_INIT = KVM_CSV_NR_MIN, + KVM_CSV_LAUNCH_ENCRYPT_DATA, + KVM_CSV_LAUNCH_ENCRYPT_VMCB, ++ KVM_CSV_SEND_ENCRYPT_DATA, ++ KVM_CSV_SEND_ENCRYPT_CONTEXT, ++ KVM_CSV_RECEIVE_ENCRYPT_DATA, ++ KVM_CSV_RECEIVE_ENCRYPT_CONTEXT, ++ ++ KVM_CSV_NR_MAX, + }; + + struct kvm_csv_launch_encrypt_data { +@@ -1865,6 +1871,38 @@ struct kvm_csv_command_batch { + __u64 csv_batch_list_uaddr; + }; + ++struct kvm_csv_send_encrypt_data { ++ __u64 hdr_uaddr; ++ __u32 hdr_len; ++ __u64 guest_addr_data; ++ __u32 guest_addr_len; ++ __u64 trans_uaddr; ++ __u32 trans_len; ++}; ++ ++struct kvm_csv_send_encrypt_context { ++ __u64 hdr_uaddr; ++ __u32 hdr_len; ++ __u64 trans_uaddr; ++ __u32 trans_len; ++}; ++ ++struct kvm_csv_receive_encrypt_data { ++ __u64 hdr_uaddr; ++ __u32 hdr_len; ++ __u64 guest_addr_data; ++ __u32 guest_addr_len; ++ __u64 trans_uaddr; ++ __u32 trans_len; ++}; ++ ++struct kvm_csv_receive_encrypt_context { ++ __u64 hdr_uaddr; ++ __u32 hdr_len; ++ __u64 trans_uaddr; ++ __u32 trans_len; ++}; ++ + #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) + #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) + #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) +-- +2.17.1 + diff --git a/1069-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch b/1069-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch new file mode 100644 index 0000000..1d941ca --- /dev/null +++ b/1069-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch @@ -0,0 +1,453 @@ +From 967c7ad199c55223cc03d0217c6f256d3d418be2 Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Fri, 17 Jun 2022 09:37:56 +0800 +Subject: [PATCH 1069/1072] anolis: csv/i386: add support to migrate the + outgoing page + +The csv_send_encrypt_data() provides the method to encrypt the +guest's private pages during migration. The routine is similar to +CSV2's. Usually, it starts with a SEND_START command to create the +migration context. Then SEND_ENCRYPT_DATA command is performed to +encrypt guest pages. After migration is completed, a SEND_FINISH +command is performed to the firmware. + +Change-Id: I6781119890036636d8f5c0a19c6647fa8a33a37d +--- + migration/ram.c | 83 ++++++++++++++++++ + target/i386/csv.c | 185 +++++++++++++++++++++++++++++++++++++++ + target/i386/csv.h | 22 +++++ + target/i386/sev.c | 13 ++- + target/i386/sev.h | 1 + + target/i386/trace-events | 1 + + 6 files changed, 304 insertions(+), 1 deletion(-) + +diff --git a/migration/ram.c b/migration/ram.c +index 1dcd5c8553..c962496684 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -2452,6 +2452,86 @@ ram_save_encrypted_pages_in_batch(RAMState *rs, PageSearchStatus *pss, bool last + } + #endif + ++/** ++ * ram_save_csv_pages - send the given csv VM pages to the stream ++ */ ++static int ram_save_csv_pages(RAMState *rs, PageSearchStatus *pss, ++ bool last_stage) ++{ ++ int ret; ++ int tmppages = 0, pages = 0; ++ RAMBlock *block = pss->block; ++ ram_addr_t offset = 0; ++ hwaddr paddr = RAM_ADDR_INVALID; ++ uint32_t host_len = 0; ++ uint8_t *p; ++ uint64_t bytes_xmit; ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ ConfidentialGuestSupportClass *cgs_class = ++ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); ++ struct ConfidentialGuestMemoryEncryptionOps *ops = ++ cgs_class->memory_encryption_ops; ++ ++ if (!csv_enabled()) ++ return 0; ++ ++ do { ++ /* Check the pages is dirty and if it is send it */ ++ if (!migration_bitmap_clear_dirty(rs, block, pss->page)) { ++ pss->page++; ++ continue; ++ } ++ ++ ret = kvm_physical_memory_addr_from_host(kvm_state, ++ block->host + (pss->page << TARGET_PAGE_BITS), &paddr); ++ /* Process ROM or MMIO */ ++ if (paddr == RAM_ADDR_INVALID || memory_region_is_rom(block->mr)) ++ tmppages = ram_save_target_page(rs, pss, last_stage); ++ else { ++ /* Caculate the offset and host virtual address of the page */ ++ offset = pss->page << TARGET_PAGE_BITS; ++ p = block->host + offset; ++ ++ if (ops->queue_outgoing_page(p, TARGET_PAGE_SIZE, offset)) ++ return -1; ++ ++ tmppages = 1; ++ host_len += TARGET_PAGE_SIZE; ++ ram_counters.normal++; ++ } ++ ++ if (tmppages < 0) { ++ return tmppages; ++ } ++ ++ pages += tmppages; ++ ++ pss->page++; ++ } while (offset_in_ramblock(block, pss->page << TARGET_PAGE_BITS) && ++ host_len < CSV3_OUTGOING_PAGE_WINDOW_SIZE); ++ ++ /* Check if there are any queued pages */ ++ if (host_len != 0) { ++ /* Always set offset as 0 for csv. */ ++ ram_counters.transferred += ++ save_page_header(rs, rs->f, block, 0 | RAM_SAVE_FLAG_ENCRYPTED_DATA); ++ ++ qemu_put_be32(rs->f, RAM_SAVE_ENCRYPTED_PAGE); ++ ram_counters.transferred += 4; ++ /* Process the queued pages in batch */ ++ ret = ops->save_queued_outgoing_pages(rs->f, &bytes_xmit); ++ if (ret) { ++ return -1; ++ } ++ ram_counters.transferred += bytes_xmit; ++ } ++ ++ /* The offset we leave with is the last one we looked at */ ++ pss->page--; ++ ++ return pages; ++} ++ + /** + * ram_save_host_page: save a whole host page + * +@@ -2486,6 +2566,9 @@ static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss, + return 0; + } + ++ if (csv_enabled()) ++ return ram_save_csv_pages(rs, pss, last_stage); ++ + #ifdef CONFIG_HYGON_CSV_MIG_ACCEL + /* + * If command_batch function is enabled and memory encryption is enabled +diff --git a/target/i386/csv.c b/target/i386/csv.c +index 6d05382fb2..c5a2bc9924 100644 +--- a/target/i386/csv.c ++++ b/target/i386/csv.c +@@ -13,6 +13,7 @@ + + #include "qemu/osdep.h" + ++#include + #include + #include "qapi/error.h" + +@@ -20,12 +21,30 @@ + #include + #endif + ++#include "migration/blocker.h" ++#include "migration/qemu-file.h" ++#include "migration/misc.h" ++#include "monitor/monitor.h" ++#include "sysemu/kvm.h" ++ + #include "trace.h" + #include "cpu.h" + #include "sev.h" + #include "csv.h" + #include "exec/address-spaces.h" + ++struct ConfidentialGuestMemoryEncryptionOps csv_memory_encryption_ops = { ++ .save_setup = sev_save_setup, ++ .save_outgoing_page = NULL, ++ .is_gfn_in_unshared_region = NULL, ++ .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, ++ .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, ++ .queue_outgoing_page = csv3_queue_outgoing_page, ++ .save_queued_outgoing_pages = csv3_save_queued_outgoing_pages, ++}; ++ ++#define CSV_OUTGOING_PAGE_NUM (CSV3_OUTGOING_PAGE_WINDOW_SIZE/TARGET_PAGE_SIZE) ++ + CsvGuestState csv_guest = { 0 }; + + #define GUEST_POLICY_CSV_BIT (1 << 6) +@@ -66,6 +85,7 @@ csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) + csv_guest.fw_error_to_str = ops->fw_error_to_str; + QTAILQ_INIT(&csv_guest.dma_map_regions_list); + qemu_mutex_init(&csv_guest.dma_map_regions_list_mutex); ++ csv_guest.sev_send_start = ops->sev_send_start; + } + return 0; + } +@@ -297,3 +317,168 @@ end: + qemu_mutex_unlock(&s->dma_map_regions_list_mutex); + return; + } ++ ++static inline hwaddr csv_hva_to_gfn(uint8_t *ptr) ++{ ++ ram_addr_t offset = RAM_ADDR_INVALID; ++ ++ kvm_physical_memory_addr_from_host(kvm_state, ptr, &offset); ++ ++ return offset >> TARGET_PAGE_BITS; ++} ++ ++static int ++csv_send_start(QEMUFile *f, uint64_t *bytes_sent) ++{ ++ if (csv_guest.sev_send_start) ++ return csv_guest.sev_send_start(f, bytes_sent); ++ else ++ return -1; ++} ++ ++static int ++csv_send_get_packet_len(int *fw_err) ++{ ++ int ret; ++ struct kvm_csv_send_encrypt_data update = {0}; ++ ++ update.hdr_len = 0; ++ update.trans_len = 0; ++ ret = csv_ioctl(KVM_CSV_SEND_ENCRYPT_DATA, &update, fw_err); ++ if (*fw_err != SEV_RET_INVALID_LEN) { ++ error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", ++ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); ++ ret = 0; ++ goto err; ++ } ++ ++ if (update.hdr_len <= INT_MAX) ++ ret = update.hdr_len; ++ else ++ ret = 0; ++ ++err: ++ return ret; ++} ++ ++static int ++csv_send_encrypt_data(CsvGuestState *s, QEMUFile *f, uint8_t *ptr, uint32_t size, ++ uint64_t *bytes_sent) ++{ ++ int ret, fw_error = 0; ++ guchar *trans; ++ uint32_t guest_addr_entry_num; ++ uint32_t i; ++ struct kvm_csv_send_encrypt_data update = { }; ++ ++ /* ++ * If this is first call then query the packet header bytes and allocate ++ * the packet buffer. ++ */ ++ if (!s->send_packet_hdr) { ++ s->send_packet_hdr_len = csv_send_get_packet_len(&fw_error); ++ if (s->send_packet_hdr_len < 1) { ++ error_report("%s: SEND_UPDATE fw_error=%d '%s'", ++ __func__, fw_error, fw_error_to_str(fw_error)); ++ return 1; ++ } ++ ++ s->send_packet_hdr = g_new(gchar, s->send_packet_hdr_len); ++ } ++ ++ if (!s->guest_addr_len || !s->guest_addr_data) { ++ error_report("%s: invalid host address or size", __func__); ++ return 1; ++ } else { ++ guest_addr_entry_num = s->guest_addr_len / sizeof(struct guest_addr_entry); ++ } ++ ++ /* allocate transport buffer */ ++ trans = g_new(guchar, guest_addr_entry_num * TARGET_PAGE_SIZE); ++ ++ update.hdr_uaddr = (uintptr_t)s->send_packet_hdr; ++ update.hdr_len = s->send_packet_hdr_len; ++ update.guest_addr_data = (uintptr_t)s->guest_addr_data; ++ update.guest_addr_len = s->guest_addr_len; ++ update.trans_uaddr = (uintptr_t)trans; ++ update.trans_len = guest_addr_entry_num * TARGET_PAGE_SIZE; ++ ++ trace_kvm_csv_send_encrypt_data(trans, update.trans_len); ++ ++ ret = csv_ioctl(KVM_CSV_SEND_ENCRYPT_DATA, &update, &fw_error); ++ if (ret) { ++ error_report("%s: SEND_ENCRYPT_DATA ret=%d fw_error=%d '%s'", ++ __func__, ret, fw_error, fw_error_to_str(fw_error)); ++ goto err; ++ } ++ ++ for (i = 0; i < guest_addr_entry_num; i++) { ++ if (s->guest_addr_data[i].share) ++ memcpy(trans + i * TARGET_PAGE_SIZE, (guchar *)s->guest_hva_data[i].hva, ++ TARGET_PAGE_SIZE); ++ } ++ ++ qemu_put_be32(f, update.hdr_len); ++ qemu_put_buffer(f, (uint8_t *)update.hdr_uaddr, update.hdr_len); ++ *bytes_sent = 4 + update.hdr_len; ++ ++ qemu_put_be32(f, update.guest_addr_len); ++ qemu_put_buffer(f, (uint8_t *)update.guest_addr_data, update.guest_addr_len); ++ *bytes_sent = 4 + update.guest_addr_len; ++ ++ qemu_put_be32(f, update.trans_len); ++ qemu_put_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); ++ *bytes_sent += (4 + update.trans_len); ++ ++err: ++ s->guest_addr_len = 0; ++ g_free(trans); ++ return ret; ++} ++ ++int ++csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) ++{ ++ CsvGuestState *s = &csv_guest; ++ uint32_t i = 0; ++ ++ (void) addr; ++ ++ if (!s->guest_addr_data) { ++ s->guest_hva_data = g_new0(struct guest_hva_entry, CSV_OUTGOING_PAGE_NUM); ++ s->guest_addr_data = g_new0(struct guest_addr_entry, CSV_OUTGOING_PAGE_NUM); ++ s->guest_addr_len = 0; ++ } ++ ++ if (s->guest_addr_len >= sizeof(struct guest_addr_entry) * CSV_OUTGOING_PAGE_NUM) { ++ error_report("Failed to queue outgoing page"); ++ return 1; ++ } ++ ++ i = s->guest_addr_len / sizeof(struct guest_addr_entry); ++ s->guest_hva_data[i].hva = (uintptr_t)ptr; ++ s->guest_addr_data[i].share = 0; ++ s->guest_addr_data[i].reserved = 0; ++ s->guest_addr_data[i].gfn = csv_hva_to_gfn(ptr); ++ s->guest_addr_len += sizeof(struct guest_addr_entry); ++ ++ return 0; ++} ++ ++int ++csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) ++{ ++ CsvGuestState *s = &csv_guest; ++ ++ /* ++ * If this is a first buffer then create outgoing encryption context ++ * and write our PDH, policy and session data. ++ */ ++ if (!csv_check_state(SEV_STATE_SEND_UPDATE) && ++ csv_send_start(f, bytes_sent)) { ++ error_report("Failed to create outgoing context"); ++ return 1; ++ } ++ ++ return csv_send_encrypt_data(s, f, NULL, 0, bytes_sent); ++} +diff --git a/target/i386/csv.h b/target/i386/csv.h +index 6412c0c70b..273d69d12c 100644 +--- a/target/i386/csv.h ++++ b/target/i386/csv.h +@@ -62,6 +62,18 @@ struct dma_map_region { + QTAILQ_ENTRY(dma_map_region) list; + }; + ++#define CSV3_OUTGOING_PAGE_WINDOW_SIZE (512 * TARGET_PAGE_SIZE) ++ ++struct guest_addr_entry { ++ uint64_t share: 1; ++ uint64_t reserved: 11; ++ uint64_t gfn: 52; ++}; ++ ++struct guest_hva_entry { ++ uint64_t hva; ++}; ++ + struct CsvGuestState { + uint32_t policy; + int sev_fd; +@@ -70,6 +82,13 @@ struct CsvGuestState { + const char *(*fw_error_to_str)(int code); + QTAILQ_HEAD(, dma_map_region) dma_map_regions_list; + QemuMutex dma_map_regions_list_mutex; ++ gchar *send_packet_hdr; ++ size_t send_packet_hdr_len; ++ struct guest_hva_entry *guest_hva_data; ++ struct guest_addr_entry *guest_addr_data; ++ size_t guest_addr_len; ++ ++ int (*sev_send_start)(QEMUFile *f, uint64_t *bytes_sent); + }; + + typedef struct CsvGuestState CsvGuestState; +@@ -77,10 +96,13 @@ typedef struct CsvGuestState CsvGuestState; + extern struct CsvGuestState csv_guest; + extern int csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops); + extern int csv_launch_encrypt_vmcb(void); ++extern struct ConfidentialGuestMemoryEncryptionOps csv_memory_encryption_ops; + + int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); + + int csv_shared_region_dma_map(uint64_t start, uint64_t end); + void csv_shared_region_dma_unmap(uint64_t start, uint64_t end); ++int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); ++int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); + + #endif +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 26b6e84d3f..31af1ecdf3 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -1173,7 +1173,10 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + qemu_add_vm_change_state_handler(sev_vm_state_change, sev); + add_migration_state_change_notifier(&sev_migration_state_notify); + +- cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; ++ if (csv_enabled()) ++ cgs_class->memory_encryption_ops = &csv_memory_encryption_ops; ++ else ++ cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; + QTAILQ_INIT(&sev->shared_regions_list); + + /* Determine whether support MSR_AMD64_SEV_ES_GHCB */ +@@ -2552,9 +2555,17 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) + return ret; + } + ++static int _sev_send_start(QEMUFile *f, uint64_t *bytes_sent) ++{ ++ SevGuestState *s = sev_guest; ++ ++ return sev_send_start(s, f, bytes_sent); ++} ++ + struct sev_ops sev_ops = { + .sev_ioctl = sev_ioctl, + .fw_error_to_str = fw_error_to_str, ++ .sev_send_start = _sev_send_start, + }; + + static void +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 8b38567c3d..6d1a918413 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -89,6 +89,7 @@ int csv_load_incoming_cpu_state(QEMUFile *f); + struct sev_ops { + int (*sev_ioctl)(int fd, int cmd, void *data, int *error); + const char *(*fw_error_to_str)(int code); ++ int (*sev_send_start)(QEMUFile *f, uint64_t *bytes_sent); + }; + + #endif +diff --git a/target/i386/trace-events b/target/i386/trace-events +index 60a4609c0f..8db3e36385 100644 +--- a/target/i386/trace-events ++++ b/target/i386/trace-events +@@ -22,3 +22,4 @@ kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int + + # csv.c + kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 ++kvm_csv_send_encrypt_data(void *dst, int len) "trans %p len %d" +-- +2.17.1 + diff --git a/1070-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch b/1070-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch new file mode 100644 index 0000000..39a15d4 --- /dev/null +++ b/1070-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch @@ -0,0 +1,204 @@ +From e6b96ff4918864bfb3ace811d46cdee74b7a7d91 Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Fri, 17 Jun 2022 09:45:45 +0800 +Subject: [PATCH 1070/1072] anolis: csv/i386: add support to migrate the + incoming page + +The csv_receive_encrypt_data() provides the method to read incoming +guest private pages from socket and load them into guest memory. +The routine is similar to CSV2's. Usually, it starts with a RECEIVE +START command to create the migration context. Then RECEIVE ENCRYPT +DATA command is performed to let the firmware load incoming pages +into guest memory. After migration is completed, a RECEIVE FINISH +command is performed to the firmware. + +Change-Id: I53bc350e379fa747c7b3c3b3be9f2fef0bf1af9f +--- + target/i386/csv.c | 87 ++++++++++++++++++++++++++++++++++++++++ + target/i386/csv.h | 2 + + target/i386/sev.c | 8 ++++ + target/i386/sev.h | 1 + + target/i386/trace-events | 1 + + 5 files changed, 99 insertions(+) + +diff --git a/target/i386/csv.c b/target/i386/csv.c +index c5a2bc9924..00ff7d20a5 100644 +--- a/target/i386/csv.c ++++ b/target/i386/csv.c +@@ -36,11 +36,14 @@ + struct ConfidentialGuestMemoryEncryptionOps csv_memory_encryption_ops = { + .save_setup = sev_save_setup, + .save_outgoing_page = NULL, ++ .load_incoming_page = csv3_load_incoming_page, + .is_gfn_in_unshared_region = NULL, + .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, + .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, + .queue_outgoing_page = csv3_queue_outgoing_page, + .save_queued_outgoing_pages = csv3_save_queued_outgoing_pages, ++ .queue_incoming_page = NULL, ++ .load_queued_incoming_pages = NULL, + }; + + #define CSV_OUTGOING_PAGE_NUM (CSV3_OUTGOING_PAGE_WINDOW_SIZE/TARGET_PAGE_SIZE) +@@ -86,6 +89,7 @@ csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) + QTAILQ_INIT(&csv_guest.dma_map_regions_list); + qemu_mutex_init(&csv_guest.dma_map_regions_list_mutex); + csv_guest.sev_send_start = ops->sev_send_start; ++ csv_guest.sev_receive_start = ops->sev_receive_start; + } + return 0; + } +@@ -482,3 +486,86 @@ csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) + + return csv_send_encrypt_data(s, f, NULL, 0, bytes_sent); + } ++ ++static int ++csv_receive_start(QEMUFile *f) ++{ ++ if (csv_guest.sev_receive_start) ++ return csv_guest.sev_receive_start(f); ++ else ++ return -1; ++} ++ ++static int csv_receive_encrypt_data(QEMUFile *f, uint8_t *ptr) ++{ ++ int ret = 1, fw_error = 0; ++ uint32_t i, guest_addr_entry_num; ++ gchar *hdr = NULL, *trans = NULL; ++ struct guest_addr_entry *guest_addr_data; ++ struct kvm_csv_receive_encrypt_data update = {}; ++ void *hva = NULL; ++ MemoryRegion *mr = NULL; ++ ++ /* get packet header */ ++ update.hdr_len = qemu_get_be32(f); ++ ++ hdr = g_new(gchar, update.hdr_len); ++ qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len); ++ update.hdr_uaddr = (uintptr_t)hdr; ++ ++ /* get guest addr data */ ++ update.guest_addr_len = qemu_get_be32(f); ++ ++ guest_addr_data = (struct guest_addr_entry *)g_new(gchar, update.guest_addr_len); ++ qemu_get_buffer(f, (uint8_t *)guest_addr_data, update.guest_addr_len); ++ update.guest_addr_data = (uintptr_t)guest_addr_data; ++ ++ /* get transport buffer */ ++ update.trans_len = qemu_get_be32(f); ++ ++ trans = g_new(gchar, update.trans_len); ++ update.trans_uaddr = (uintptr_t)trans; ++ qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); ++ ++ /* update share memory. */ ++ guest_addr_entry_num = update.guest_addr_len / sizeof(struct guest_addr_entry); ++ for (i = 0; i < guest_addr_entry_num; i++) { ++ if (guest_addr_data[i].share) { ++ hva = gpa2hva(&mr, ++ ((uint64_t)guest_addr_data[i].gfn << TARGET_PAGE_BITS), ++ TARGET_PAGE_SIZE, ++ NULL); ++ if (hva) ++ memcpy(hva, trans + i * TARGET_PAGE_SIZE, TARGET_PAGE_SIZE); ++ } ++ } ++ ++ trace_kvm_csv_receive_encrypt_data(trans, update.trans_len, hdr, update.hdr_len); ++ ++ ret = csv_ioctl(KVM_CSV_RECEIVE_ENCRYPT_DATA, &update, &fw_error); ++ if (ret) { ++ error_report("Error RECEIVE_ENCRYPT_DATA ret=%d fw_error=%d '%s'", ++ ret, fw_error, fw_error_to_str(fw_error)); ++ goto err; ++ } ++ ++err: ++ g_free(trans); ++ g_free(guest_addr_data); ++ g_free(hdr); ++ return ret; ++} ++ ++int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr) ++{ ++ /* ++ * If this is first buffer and SEV is not in recieiving state then ++ * use RECEIVE_START command to create a encryption context. ++ */ ++ if (!csv_check_state(SEV_STATE_RECEIVE_UPDATE) && ++ csv_receive_start(f)) { ++ return 1; ++ } ++ ++ return csv_receive_encrypt_data(f, ptr); ++} +diff --git a/target/i386/csv.h b/target/i386/csv.h +index 273d69d12c..c8639cfa9a 100644 +--- a/target/i386/csv.h ++++ b/target/i386/csv.h +@@ -89,6 +89,7 @@ struct CsvGuestState { + size_t guest_addr_len; + + int (*sev_send_start)(QEMUFile *f, uint64_t *bytes_sent); ++ int (*sev_receive_start)(QEMUFile *f); + }; + + typedef struct CsvGuestState CsvGuestState; +@@ -102,6 +103,7 @@ int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); + + int csv_shared_region_dma_map(uint64_t start, uint64_t end); + void csv_shared_region_dma_unmap(uint64_t start, uint64_t end); ++int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr); + int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); + int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 31af1ecdf3..40e52985ac 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -2562,10 +2562,18 @@ static int _sev_send_start(QEMUFile *f, uint64_t *bytes_sent) + return sev_send_start(s, f, bytes_sent); + } + ++static int _sev_receive_start(QEMUFile *f) ++{ ++ SevGuestState *s = sev_guest; ++ ++ return sev_receive_start(s, f); ++} ++ + struct sev_ops sev_ops = { + .sev_ioctl = sev_ioctl, + .fw_error_to_str = fw_error_to_str, + .sev_send_start = _sev_send_start, ++ .sev_receive_start = _sev_receive_start, + }; + + static void +diff --git a/target/i386/sev.h b/target/i386/sev.h +index 6d1a918413..9e5c6506c8 100644 +--- a/target/i386/sev.h ++++ b/target/i386/sev.h +@@ -90,6 +90,7 @@ struct sev_ops { + int (*sev_ioctl)(int fd, int cmd, void *data, int *error); + const char *(*fw_error_to_str)(int code); + int (*sev_send_start)(QEMUFile *f, uint64_t *bytes_sent); ++ int (*sev_receive_start)(QEMUFile *f); + }; + + #endif +diff --git a/target/i386/trace-events b/target/i386/trace-events +index 8db3e36385..1854356fc5 100644 +--- a/target/i386/trace-events ++++ b/target/i386/trace-events +@@ -23,3 +23,4 @@ kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int + # csv.c + kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 + kvm_csv_send_encrypt_data(void *dst, int len) "trans %p len %d" ++kvm_csv_receive_encrypt_data(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" +-- +2.17.1 + diff --git a/1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch b/1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch new file mode 100644 index 0000000..629f713 --- /dev/null +++ b/1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch @@ -0,0 +1,137 @@ +From cd3f19da06a1691a790221a06a2899427e2140cd Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Fri, 17 Jun 2022 09:52:31 +0800 +Subject: [PATCH 1071/1072] anolis: csv/i386: add support to migrate the + outgoing context + +CSV needs to migrate guest cpu's context pages. Prior to migration +of the context, it should query transfer buffer length and header +data length by SEND ENCRYPT CONTEXT command. New migration flag +RAM_SAVE_ENCRYPTED_CSV_CONTEXT is defined for CSV. + +Change-Id: I1989e76bd5c91c78074fb31eff075deacfa16078 +--- + target/i386/csv.c | 79 ++++++++++++++++++++++++++++++++++++++++ + target/i386/csv.h | 1 + + target/i386/trace-events | 1 + + 3 files changed, 81 insertions(+) + +diff --git a/target/i386/csv.c b/target/i386/csv.c +index 00ff7d20a5..271c48867e 100644 +--- a/target/i386/csv.c ++++ b/target/i386/csv.c +@@ -44,6 +44,7 @@ struct ConfidentialGuestMemoryEncryptionOps csv_memory_encryption_ops = { + .save_queued_outgoing_pages = csv3_save_queued_outgoing_pages, + .queue_incoming_page = NULL, + .load_queued_incoming_pages = NULL, ++ .save_outgoing_cpu_state = csv3_save_outgoing_context, + }; + + #define CSV_OUTGOING_PAGE_NUM (CSV3_OUTGOING_PAGE_WINDOW_SIZE/TARGET_PAGE_SIZE) +@@ -569,3 +570,81 @@ int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr) + + return csv_receive_encrypt_data(f, ptr); + } ++ ++static int ++csv_send_get_context_len(int *fw_err, int *context_len, int *hdr_len) ++{ ++ int ret = 0; ++ struct kvm_csv_send_encrypt_context update = {}; ++ ++ ret = csv_ioctl(KVM_CSV_SEND_ENCRYPT_CONTEXT, &update, fw_err); ++ if (*fw_err != SEV_RET_INVALID_LEN) { ++ error_report("%s: failed to get context length ret=%d fw_error=%d '%s'", ++ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); ++ ret = -1; ++ goto err; ++ } ++ ++ if (update.trans_len <= INT_MAX && update.hdr_len <= INT_MAX) { ++ *context_len = update.trans_len; ++ *hdr_len = update.hdr_len; ++ } ++ ret = 0; ++err: ++ return ret; ++} ++ ++static int ++csv_send_encrypt_context(CsvGuestState *s, QEMUFile *f) ++{ ++ int ret, fw_error = 0; ++ int context_len = 0; ++ int hdr_len = 0; ++ guchar *trans; ++ guchar *hdr; ++ struct kvm_csv_send_encrypt_context update = { }; ++ ++ ret = csv_send_get_context_len(&fw_error, &context_len, &hdr_len); ++ if (context_len < 1 || hdr_len < 1) { ++ error_report("%s: fail to get context length fw_error=%d '%s'", ++ __func__, fw_error, fw_error_to_str(fw_error)); ++ return 1; ++ } ++ ++ /* allocate transport buffer */ ++ trans = g_new(guchar, context_len); ++ hdr = g_new(guchar, hdr_len); ++ ++ update.hdr_uaddr = (uintptr_t)hdr; ++ update.hdr_len = hdr_len; ++ update.trans_uaddr = (uintptr_t)trans; ++ update.trans_len = context_len; ++ ++ trace_kvm_csv_send_encrypt_context(trans, update.trans_len); ++ ++ ret = csv_ioctl(KVM_CSV_SEND_ENCRYPT_CONTEXT, &update, &fw_error); ++ if (ret) { ++ error_report("%s: SEND_ENCRYPT_CONTEXT ret=%d fw_error=%d '%s'", ++ __func__, ret, fw_error, fw_error_to_str(fw_error)); ++ goto err; ++ } ++ ++ qemu_put_be32(f, update.hdr_len); ++ qemu_put_buffer(f, (uint8_t *)update.hdr_uaddr, update.hdr_len); ++ ++ qemu_put_be32(f, update.trans_len); ++ qemu_put_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); ++ ++err: ++ g_free(trans); ++ g_free(hdr); ++ return ret; ++} ++ ++int csv3_save_outgoing_context(QEMUFile *f) ++{ ++ CsvGuestState *s = &csv_guest; ++ ++ /* send csv context. */ ++ return csv_send_encrypt_context(s, f); ++} +diff --git a/target/i386/csv.h b/target/i386/csv.h +index c8639cfa9a..9def1611d8 100644 +--- a/target/i386/csv.h ++++ b/target/i386/csv.h +@@ -103,6 +103,7 @@ int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); + + int csv_shared_region_dma_map(uint64_t start, uint64_t end); + void csv_shared_region_dma_unmap(uint64_t start, uint64_t end); ++int csv3_save_outgoing_context(QEMUFile *f); + int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr); + int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); + int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); +diff --git a/target/i386/trace-events b/target/i386/trace-events +index 1854356fc5..08a782ce15 100644 +--- a/target/i386/trace-events ++++ b/target/i386/trace-events +@@ -23,4 +23,5 @@ kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int + # csv.c + kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 + kvm_csv_send_encrypt_data(void *dst, int len) "trans %p len %d" ++kvm_csv_send_encrypt_context(void *dst, int len) "trans %p len %d" + kvm_csv_receive_encrypt_data(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" +-- +2.17.1 + diff --git a/1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch b/1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch new file mode 100644 index 0000000..1c6084b --- /dev/null +++ b/1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch @@ -0,0 +1,109 @@ +From 40741ce0d0bb68d789d84407c77d2282ecd4f67f Mon Sep 17 00:00:00 2001 +From: jiangxin +Date: Fri, 17 Jun 2022 10:00:46 +0800 +Subject: [PATCH 1072/1072] anolis: csv/i386: add support to migrate the + incoming context + +The csv_load_incoming_context() provides the method to read incoming +guest's context from socket. It loads them into guest private memory. +This is the last step during migration and RECEIVE FINISH command is +performed by then to complete the whole migration. + +Change-Id: I7290e0e9527bb819eee5813038110d981908a880 +--- + target/i386/csv.c | 45 ++++++++++++++++++++++++++++++++++++++++ + target/i386/csv.h | 1 + + target/i386/trace-events | 1 + + 3 files changed, 47 insertions(+) + +diff --git a/target/i386/csv.c b/target/i386/csv.c +index 271c48867e..b0ca16980d 100644 +--- a/target/i386/csv.c ++++ b/target/i386/csv.c +@@ -45,6 +45,7 @@ struct ConfidentialGuestMemoryEncryptionOps csv_memory_encryption_ops = { + .queue_incoming_page = NULL, + .load_queued_incoming_pages = NULL, + .save_outgoing_cpu_state = csv3_save_outgoing_context, ++ .load_incoming_cpu_state = csv3_load_incoming_context, + }; + + #define CSV_OUTGOING_PAGE_NUM (CSV3_OUTGOING_PAGE_WINDOW_SIZE/TARGET_PAGE_SIZE) +@@ -641,6 +642,42 @@ err: + return ret; + } + ++static int ++csv_receive_encrypt_context(CsvGuestState *s, QEMUFile *f) ++{ ++ int ret = 1, fw_error = 0; ++ gchar *hdr = NULL, *trans = NULL; ++ struct kvm_csv_receive_encrypt_context update = {}; ++ ++ /* get packet header */ ++ update.hdr_len = qemu_get_be32(f); ++ ++ hdr = g_new(gchar, update.hdr_len); ++ qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len); ++ update.hdr_uaddr = (uintptr_t)hdr; ++ ++ /* get transport buffer */ ++ update.trans_len = qemu_get_be32(f); ++ ++ trans = g_new(gchar, update.trans_len); ++ update.trans_uaddr = (uintptr_t)trans; ++ qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); ++ ++ trace_kvm_csv_receive_encrypt_context(trans, update.trans_len, hdr, update.hdr_len); ++ ++ ret = csv_ioctl(KVM_CSV_RECEIVE_ENCRYPT_CONTEXT, &update, &fw_error); ++ if (ret) { ++ error_report("Error RECEIVE_ENCRYPT_CONTEXT ret=%d fw_error=%d '%s'", ++ ret, fw_error, fw_error_to_str(fw_error)); ++ goto err; ++ } ++ ++err: ++ g_free(trans); ++ g_free(hdr); ++ return ret; ++} ++ + int csv3_save_outgoing_context(QEMUFile *f) + { + CsvGuestState *s = &csv_guest; +@@ -648,3 +685,11 @@ int csv3_save_outgoing_context(QEMUFile *f) + /* send csv context. */ + return csv_send_encrypt_context(s, f); + } ++ ++int csv3_load_incoming_context(QEMUFile *f) ++{ ++ CsvGuestState *s = &csv_guest; ++ ++ /* receive csv context. */ ++ return csv_receive_encrypt_context(s, f); ++} +diff --git a/target/i386/csv.h b/target/i386/csv.h +index 9def1611d8..2e0506313d 100644 +--- a/target/i386/csv.h ++++ b/target/i386/csv.h +@@ -104,6 +104,7 @@ int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); + int csv_shared_region_dma_map(uint64_t start, uint64_t end); + void csv_shared_region_dma_unmap(uint64_t start, uint64_t end); + int csv3_save_outgoing_context(QEMUFile *f); ++int csv3_load_incoming_context(QEMUFile *f); + int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr); + int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); + int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); +diff --git a/target/i386/trace-events b/target/i386/trace-events +index 08a782ce15..47ab390de6 100644 +--- a/target/i386/trace-events ++++ b/target/i386/trace-events +@@ -25,3 +25,4 @@ kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PR + kvm_csv_send_encrypt_data(void *dst, int len) "trans %p len %d" + kvm_csv_send_encrypt_context(void *dst, int len) "trans %p len %d" + kvm_csv_receive_encrypt_data(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" ++kvm_csv_receive_encrypt_context(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" +-- +2.17.1 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index d46b318..2ed533a 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -972,6 +972,12 @@ Patch1063: 1063-anolis-target-i386-csv-Add-support-for-migrate-VMSA-.patch Patch1064: 1064-anolis-target-i386-get-set-migrate-GHCB-state.patch Patch1065: 1065-anolis-target-i386-kvm-Return-resettable-when-emulat.patch Patch1066: 1066-anolis-kvm-Add-support-for-CSV2-reboot.patch +Patch1067: 1067-anolis-vfio-only-map-shared-region-for-CSV-virtual-m.patch +Patch1068: 1068-anolis-linux-headers-update-kernel-headers-to-includ.patch +Patch1069: 1069-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch +Patch1070: 1070-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch +Patch1071: 1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch +Patch1072: 1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch BuildRequires: wget BuildRequires: rpm-build @@ -2243,6 +2249,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : - 0008-anolis-vga-force-full-update-for-CSV-guest.patch (jiangxin@hygon.cn) (Hygon CSV3 feature) - Support Hygon CSV/CSV2 live migration, CSV2 reboot (hanliyang@hygon.cn) +- Support CSV3 live migration (jiangxin@hygon.cn) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] -- Gitee From e58c1821b0421ce61e4864a10efc446334dddeef Mon Sep 17 00:00:00 2001 From: hanliyang Date: Wed, 3 Jan 2024 07:41:12 +0000 Subject: [PATCH 12/17] Support reuse ASID for CSV guests In you want to reuse one ASID for many CSV guests, you should provide a label (i.e. userid) and the length of the label when launch CSV guest. The CSV guests which were provided the same userid will share the same ASID. Signed-off-by: hanliyang --- ...86-sev-Add-support-for-reuse-ASID-fo.patch | 192 ++++++++++++++++++ qemu-kvm.spec | 2 + 2 files changed, 194 insertions(+) create mode 100644 1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch diff --git a/1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch b/1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch new file mode 100644 index 0000000..7e6f98e --- /dev/null +++ b/1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch @@ -0,0 +1,192 @@ +From 9cd331388ce95e3d7365fceab30016756eae2483 Mon Sep 17 00:00:00 2001 +From: appleLin +Date: Wed, 3 Aug 2022 21:02:41 +0800 +Subject: [PATCH] anolis: target/i386/sev: Add support for reuse ASID for + different CSV guests + +In you want to reuse one ASID for many CSV guests, you should provide a +label (i.e. userid) and the length of the label when launch CSV guest. +The CSV guests which were provided the same userid will share the same +ASID. + +Signed-off-by: hanliyang +--- + linux-headers/linux/kvm.h | 5 +++++ + qapi/qom.json | 5 ++++- + qemu-options.hx | 5 ++++- + target/i386/csv.c | 2 -- + target/i386/csv.h | 3 +++ + target/i386/sev.c | 47 ++++++++++++++++++++++++++++++++++++++- + 6 files changed, 62 insertions(+), 5 deletions(-) + +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 5fe2f8d04..3875127a3 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -2011,6 +2011,11 @@ struct kvm_csv_receive_encrypt_context { + __u32 trans_len; + }; + ++struct kvm_csv_init { ++ __u64 userid_addr; ++ __u32 len; ++}; ++ + #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) + #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) + #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) +diff --git a/qapi/qom.json b/qapi/qom.json +index eeb5395ff..387c0a142 100644 +--- a/qapi/qom.json ++++ b/qapi/qom.json +@@ -773,6 +773,8 @@ + # designated guest firmware page for measured boot + # with -kernel (default: false) (since 6.2) + # ++# @user-id: the user id of the guest owner, only support on Hygon CPUs ++# + # Since: 2.12 + ## + { 'struct': 'SevGuestProperties', +@@ -783,7 +785,8 @@ + '*handle': 'uint32', + '*cbitpos': 'uint32', + 'reduced-phys-bits': 'uint32', +- '*kernel-hashes': 'bool' } } ++ '*kernel-hashes': 'bool', ++ '*user-id': 'str' } } + + ## + # @ObjectType: +diff --git a/qemu-options.hx b/qemu-options.hx +index 8997969d5..115e1835f 100644 +--- a/qemu-options.hx ++++ b/qemu-options.hx +@@ -5189,7 +5189,7 @@ SRST + -object secret,id=sec0,keyid=secmaster0,format=base64,\\ + data=$SECRET,iv=$(dh_cert_file = g_strdup(value); + } + ++static char * ++sev_guest_get_user_id(Object *obj, Error **errp) ++{ ++ SevGuestState *s = SEV_GUEST(obj); ++ ++ return g_strdup(s->user_id); ++} ++ ++static void ++sev_guest_set_user_id(Object *obj, const char *value, Error **errp) ++{ ++ SevGuestState *s = SEV_GUEST(obj); ++ ++ s->user_id = g_strdup(value); ++} ++ + static char * + sev_guest_get_sev_device(Object *obj, Error **errp) + { +@@ -436,6 +453,11 @@ sev_guest_class_init(ObjectClass *oc, void *data) + sev_guest_set_kernel_hashes); + object_class_property_set_description(oc, "kernel-hashes", + "add kernel hashes to guest firmware for measured Linux boot"); ++ object_class_property_add_str(oc, "user-id", ++ sev_guest_get_user_id, ++ sev_guest_set_user_id); ++ object_class_property_set_description(oc, "user-id", ++ "user id of the guest owner"); + } + + static void +@@ -1137,7 +1159,30 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + } + + trace_kvm_sev_init(); +- ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); ++ ++ /* Only support reuse asid for CSV/CSV2 guest */ ++ if (is_hygon_cpu() && ++ (sev_guest->policy & GUEST_POLICY_REUSE_ASID) && ++ !(sev_guest->policy & GUEST_POLICY_CSV_BIT)) { ++ char *user_id = NULL; ++ struct kvm_csv_init *init_cmd_buf = NULL; ++ ++ user_id = object_property_get_str(OBJECT(sev), "user-id", NULL); ++ if (user_id && strlen(user_id)) { ++ init_cmd_buf = g_new0(struct kvm_csv_init, 1); ++ init_cmd_buf->len = strlen(user_id); ++ init_cmd_buf->userid_addr = (__u64)user_id; ++ } ++ ret = sev_ioctl(sev->sev_fd, cmd, init_cmd_buf, &fw_error); ++ ++ if (user_id) { ++ g_free(user_id); ++ g_free(init_cmd_buf); ++ } ++ } else { ++ ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); ++ } ++ + if (ret) { + error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'", + __func__, ret, fw_error, fw_error_to_str(fw_error)); +-- +2.31.1 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 2ed533a..ea5d05e 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -978,6 +978,7 @@ Patch1069: 1069-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch Patch1070: 1070-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch Patch1071: 1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch Patch1072: 1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch +Patch1073: 1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch BuildRequires: wget BuildRequires: rpm-build @@ -2250,6 +2251,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : (Hygon CSV3 feature) - Support Hygon CSV/CSV2 live migration, CSV2 reboot (hanliyang@hygon.cn) - Support CSV3 live migration (jiangxin@hygon.cn) +- Support reuse ASID for CSV guests (hanliyang@hygon.cn) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] -- Gitee From d78d8ba93da5c34cb8d9d3706fc1531d2295f711 Mon Sep 17 00:00:00 2001 From: xiongmengbiao Date: Wed, 6 Mar 2024 16:25:22 +0800 Subject: [PATCH 13/17] Support tkm key isolation Signed-off-by: xiongmengbiao --- 1074-newfeature-support-vpsp.patch | 190 +++++++++++++++++++++++++++++ qemu-kvm.spec | 2 + 2 files changed, 192 insertions(+) create mode 100644 1074-newfeature-support-vpsp.patch diff --git a/1074-newfeature-support-vpsp.patch b/1074-newfeature-support-vpsp.patch new file mode 100644 index 0000000..2efaa12 --- /dev/null +++ b/1074-newfeature-support-vpsp.patch @@ -0,0 +1,190 @@ +From fd593b7516631ed0dce757cdce4d10b28971c553 Mon Sep 17 00:00:00 2001 +From: xiongmengbiao +Date: Wed, 6 Mar 2024 17:43:57 +0800 +Subject: [PATCH] [newfeature]: support vpsp + +simulate a psp misc device for support tkm's key isolation + +Signed-off-by: xiongmengbiao +--- + hw/misc/Kconfig | 4 ++ + hw/misc/meson.build | 1 + + hw/misc/psp.c | 141 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 146 insertions(+) + create mode 100644 hw/misc/psp.c + +diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig +index 507058d8b..d1d05442d 100644 +--- a/hw/misc/Kconfig ++++ b/hw/misc/Kconfig +@@ -171,4 +171,8 @@ config SIFIVE_U_PRCI + config VIRT_CTRL + bool + ++config PSP_DEV ++ bool ++ default y ++ + source macio/Kconfig +diff --git a/hw/misc/meson.build b/hw/misc/meson.build +index 3f41a3a5b..39e583631 100644 +--- a/hw/misc/meson.build ++++ b/hw/misc/meson.build +@@ -10,6 +10,7 @@ softmmu_ss.add(when: 'CONFIG_UNIMP', if_true: files('unimp.c')) + softmmu_ss.add(when: 'CONFIG_EMPTY_SLOT', if_true: files('empty_slot.c')) + softmmu_ss.add(when: 'CONFIG_LED', if_true: files('led.c')) + softmmu_ss.add(when: 'CONFIG_PVPANIC_COMMON', if_true: files('pvpanic.c')) ++softmmu_ss.add(when: 'CONFIG_PSP_DEV', if_true: files('psp.c')) + + # ARM devices + softmmu_ss.add(when: 'CONFIG_PL310', if_true: files('arm_l2x0.c')) +diff --git a/hw/misc/psp.c b/hw/misc/psp.c +new file mode 100644 +index 000000000..1cfbab859 +--- /dev/null ++++ b/hw/misc/psp.c +@@ -0,0 +1,141 @@ ++/* ++ * hygon psp device emulation ++ * ++ * Copyright 2024 HYGON Corp. ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or (at ++ * your option) any later version. See the COPYING file in the top-level ++ * directory. ++ */ ++ ++#include "qemu/osdep.h" ++#include "qemu/compiler.h" ++#include "qemu/error-report.h" ++#include "qapi/error.h" ++#include "migration/vmstate.h" ++#include "hw/qdev-properties.h" ++#include "sysemu/runstate.h" ++#include ++ ++#define TYPE_PSP_DEV "psp" ++OBJECT_DECLARE_SIMPLE_TYPE(PSPDevState, PSP_DEV) ++ ++struct PSPDevState { ++ /* Private */ ++ DeviceState pdev; ++ ++ /* Public */ ++ Notifier shutdown_notifier; ++ int dev_fd; ++ uint8_t enabled; ++ ++ /** ++ * vid is used to identify a virtual machine in qemu. ++ * When a virtual machine accesses a tkm key, ++ * the TKM module uses different key spaces based on different vids. ++ */ ++ uint32_t vid; ++}; ++ ++#define PSP_DEV_PATH "/dev/hygon_psp_config" ++#define HYGON_PSP_IOC_TYPE 'H' ++#define PSP_IOC_MUTEX_ENABLE _IOWR(HYGON_PSP_IOC_TYPE, 1, NULL) ++#define PSP_IOC_MUTEX_DISABLE _IOWR(HYGON_PSP_IOC_TYPE, 2, NULL) ++#define PSP_IOC_VPSP_OPT _IOWR(HYGON_PSP_IOC_TYPE, 3, NULL) ++ ++enum VPSP_DEV_CTRL_OPCODE { ++ VPSP_OP_VID_ADD, ++ VPSP_OP_VID_DEL, ++}; ++ ++struct psp_dev_ctrl { ++ unsigned char op; ++ union { ++ unsigned int vid; ++ unsigned char reserved[128]; ++ } data; ++}; ++ ++static void psp_dev_destroy(PSPDevState *state) ++{ ++ struct psp_dev_ctrl ctrl = { 0 }; ++ if (state && state->dev_fd) { ++ if (state->enabled) { ++ ctrl.op = VPSP_OP_VID_DEL; ++ if (ioctl(state->dev_fd, PSP_IOC_VPSP_OPT, &ctrl) < 0) { ++ error_report("VPSP_OP_VID_DEL: %d", -errno); ++ } else { ++ state->enabled = false; ++ } ++ } ++ qemu_close(state->dev_fd); ++ state->dev_fd = 0; ++ } ++} ++ ++/** ++ * Guest OS performs shut down operations through 'shutdown' and 'powerdown' event. ++ * The 'powerdown' event will also trigger 'shutdown' in the end, ++ * so only attention to the 'shutdown' event. ++ * ++ * When Guest OS trigger 'reboot' or 'reset' event, to do nothing. ++*/ ++static void psp_dev_shutdown_notify(Notifier *notifier, void *data) ++{ ++ PSPDevState *state = container_of(notifier, PSPDevState, shutdown_notifier); ++ psp_dev_destroy(state); ++} ++ ++static void psp_dev_realize(DeviceState *dev, Error **errp) ++{ ++ struct psp_dev_ctrl ctrl = { 0 }; ++ PSPDevState *state = PSP_DEV(dev); ++ ++ state->dev_fd = qemu_open_old(PSP_DEV_PATH, O_RDWR); ++ if (state->dev_fd < 0) { ++ error_setg(errp, "fail to open %s, errno %d.", PSP_DEV_PATH, errno); ++ goto end; ++ } ++ ++ ctrl.op = VPSP_OP_VID_ADD; ++ ctrl.data.vid = state->vid; ++ if (ioctl(state->dev_fd, PSP_IOC_VPSP_OPT, &ctrl) < 0) { ++ error_setg(errp, "psp_dev_realize VPSP_OP_VID_ADD vid %d, return %d", ctrl.data.vid, -errno); ++ goto end; ++ } ++ ++ state->enabled = true; ++ state->shutdown_notifier.notify = psp_dev_shutdown_notify; ++ qemu_register_shutdown_notifier(&state->shutdown_notifier); ++end: ++ return; ++} ++ ++static struct Property psp_dev_properties[] = { ++ DEFINE_PROP_UINT32("vid", PSPDevState, vid, 0), ++ DEFINE_PROP_END_OF_LIST(), ++}; ++ ++static void psp_dev_class_init(ObjectClass *klass, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(klass); ++ ++ dc->desc = "PSP Device"; ++ dc->realize = psp_dev_realize; ++ set_bit(DEVICE_CATEGORY_MISC, dc->categories); ++ device_class_set_props(dc, psp_dev_properties); ++} ++ ++static const TypeInfo psp_dev_info = { ++ .name = TYPE_PSP_DEV, ++ .parent = TYPE_DEVICE, ++ .instance_size = sizeof(PSPDevState), ++ .class_init = psp_dev_class_init, ++}; ++ ++static void psp_dev_register_types(void) ++{ ++ type_register_static(&psp_dev_info); ++} ++ ++type_init(psp_dev_register_types) +-- +2.36.6 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index ea5d05e..c31287d 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -979,6 +979,7 @@ Patch1070: 1070-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch Patch1071: 1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch Patch1072: 1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch Patch1073: 1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch +Patch1074: 1074-newfeature-support-vpsp.patch BuildRequires: wget BuildRequires: rpm-build @@ -2252,6 +2253,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : - Support Hygon CSV/CSV2 live migration, CSV2 reboot (hanliyang@hygon.cn) - Support CSV3 live migration (jiangxin@hygon.cn) - Support reuse ASID for CSV guests (hanliyang@hygon.cn) +- Support tkm key isolation (xiongmengbiao@hygon.cn) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] -- Gitee From c80adcb3fc1531d4a7b61e96093ff85a19d7cd52 Mon Sep 17 00:00:00 2001 From: Yanjing Zhou Date: Tue, 18 Jun 2024 10:12:09 +0800 Subject: [PATCH 14/17] target/i386: Add Hygon Dhyana-v3 and Dharma CPU model Add the following feature bits for Dhyana-v3 CPU model: perfctr-core, clzero, xsaveerptr, aes, pclmulqdq, sha-ni Disable xsaves feature bit for Erratum 1386 Add the following feature bits for Dharma CPU model compare to Dhyana: stibp, ibrs, umip, ssbd Signed-off-by: Yanjing Zhou --- ...t-i386-Add-Hygon-Dhyana-v3-CPU-model.patch | 43 ++++++ ...-i386-Add-new-Hygon-Dharma-CPU-model.patch | 133 ++++++++++++++++++ qemu-kvm.spec | 3 + 3 files changed, 179 insertions(+) create mode 100644 1075-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch create mode 100644 1076-target-i386-Add-new-Hygon-Dharma-CPU-model.patch diff --git a/1075-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch b/1075-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch new file mode 100644 index 0000000..abbf1da --- /dev/null +++ b/1075-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch @@ -0,0 +1,43 @@ +From 858884a2a18df9bcb07176fc14a6ea5ee872f8dc Mon Sep 17 00:00:00 2001 +From: Yanjing Zhou +Date: Tue, 11 Jun 2024 14:28:12 +0800 +Subject: [PATCH 1/2] target/i386: Add Hygon Dhyana-v3 CPU model + +Add the following feature bits for Dhyana CPU model: +perfctr-core, clzero, xsaveerptr, aes, pclmulqdq, sha-ni + +Disable xsaves feature bit for Erratum 1386 + +Signed-off-by: Yanjing Zhou +--- + target/i386/cpu.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index aa9e63680..43a57be0b 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -4057,6 +4057,20 @@ static const X86CPUDefinition builtin_x86_defs[] = { + { /* end of list */ } + }, + }, ++ { .version = 3, ++ .props = (PropValue[]) { ++ { "xsaves", "off" }, ++ { "perfctr-core", "on" }, ++ { "clzero", "on" }, ++ { "xsaveerptr", "on" }, ++ { "aes", "on" }, ++ { "pclmulqdq", "on" }, ++ { "sha-ni", "on" }, ++ { "model-id", ++ "Hygon Dhyana-v3 processor" }, ++ { /* end of list */ } ++ }, ++ }, + { /* end of list */ } + } + }, +-- +2.39.3 + diff --git a/1076-target-i386-Add-new-Hygon-Dharma-CPU-model.patch b/1076-target-i386-Add-new-Hygon-Dharma-CPU-model.patch new file mode 100644 index 0000000..d12c1a5 --- /dev/null +++ b/1076-target-i386-Add-new-Hygon-Dharma-CPU-model.patch @@ -0,0 +1,133 @@ +From b3dfdd0e3cf7795fb66b094ffd821e193b9a773a Mon Sep 17 00:00:00 2001 +From: Yanjing Zhou +Date: Tue, 11 Jun 2024 14:29:34 +0800 +Subject: [PATCH 2/2] target/i386: Add new Hygon 'Dharma' CPU model + +Add the following feature bits compare to Dhyana CPU model: +stibp, ibrs, umip, ssbd + +Signed-off-by: Yanjing Zhou +--- + target/i386/cpu.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 99 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 43a57be0b..07b65da92 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1731,6 +1731,56 @@ static const CPUCaches epyc_milan_cache_info = { + }, + }; + ++static const CPUCaches dharma_cache_info = { ++ .l1d_cache = &(CPUCacheInfo) { ++ .type = DATA_CACHE, ++ .level = 1, ++ .size = 32 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 64, ++ .lines_per_tag = 1, ++ .self_init = 1, ++ .no_invd_sharing = true, ++ }, ++ .l1i_cache = &(CPUCacheInfo) { ++ .type = INSTRUCTION_CACHE, ++ .level = 1, ++ .size = 32 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 64, ++ .lines_per_tag = 1, ++ .self_init = 1, ++ .no_invd_sharing = true, ++ }, ++ .l2_cache = &(CPUCacheInfo) { ++ .type = UNIFIED_CACHE, ++ .level = 2, ++ .size = 512 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 1024, ++ .lines_per_tag = 1, ++ }, ++ .l3_cache = &(CPUCacheInfo) { ++ .type = UNIFIED_CACHE, ++ .level = 3, ++ .size = 16 * MiB, ++ .line_size = 64, ++ .associativity = 16, ++ .partitions = 1, ++ .sets = 16384, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .inclusive = true, ++ .complex_indexing = true, ++ }, ++}; ++ + /* The following VMX features are not supported by KVM and are left out in the + * CPU definitions: + * +@@ -4191,6 +4241,55 @@ static const X86CPUDefinition builtin_x86_defs[] = { + .model_id = "AMD EPYC-Milan Processor", + .cache_info = &epyc_milan_cache_info, + }, ++ { ++ .name = "Dharma", ++ .level = 0xd, ++ .vendor = CPUID_VENDOR_HYGON, ++ .family = 24, ++ .model = 4, ++ .stepping = 0, ++ .features[FEAT_1_EDX] = ++ CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH | ++ CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE | ++ CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE | ++ CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE | ++ CPUID_VME | CPUID_FP87, ++ .features[FEAT_1_ECX] = ++ CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX | ++ CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT | ++ CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | ++ CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 | ++ CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3, ++ .features[FEAT_8000_0001_EDX] = ++ CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB | ++ CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX | ++ CPUID_EXT2_SYSCALL, ++ .features[FEAT_8000_0001_ECX] = ++ CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH | ++ CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | ++ CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM | ++ CPUID_EXT3_TOPOEXT | CPUID_EXT3_PERFCORE, ++ .features[FEAT_8000_0008_EBX] = ++ CPUID_8000_0008_EBX_CLZERO | CPUID_8000_0008_EBX_XSAVEERPTR | ++ CPUID_8000_0008_EBX_IBPB | CPUID_8000_0008_EBX_IBRS | ++ CPUID_8000_0008_EBX_STIBP | CPUID_8000_0008_EBX_AMD_SSBD, ++ .features[FEAT_7_0_EBX] = ++ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 | ++ CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED | ++ CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT | ++ CPUID_7_0_EBX_SHA_NI, ++ .features[FEAT_7_0_ECX] = CPUID_7_0_ECX_UMIP, ++ .features[FEAT_XSAVE] = ++ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | ++ CPUID_XSAVE_XGETBV1, ++ .features[FEAT_6_EAX] = ++ CPUID_6_EAX_ARAT, ++ .features[FEAT_SVM] = ++ CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE, ++ .xlevel = 0x8000001E, ++ .model_id = "Hygon Dharma Processor", ++ .cache_info = &dharma_cache_info, ++ }, + }; + + /* +-- +2.39.3 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index c31287d..a2ed1ec 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -980,6 +980,8 @@ Patch1071: 1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch Patch1072: 1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch Patch1073: 1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch Patch1074: 1074-newfeature-support-vpsp.patch +Patch1075: 1075-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch +Patch1076: 1076-target-i386-Add-new-Hygon-Dharma-CPU-model.patch BuildRequires: wget BuildRequires: rpm-build @@ -2254,6 +2256,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : - Support CSV3 live migration (jiangxin@hygon.cn) - Support reuse ASID for CSV guests (hanliyang@hygon.cn) - Support tkm key isolation (xiongmengbiao@hygon.cn) +- Add Hygon Dhyana-v3 and Dharma CPU model (zhouyanjing@hygon.cn) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] -- Gitee From 56570a2ecaa97ed0a64cd288413b492b7d99955a Mon Sep 17 00:00:00 2001 From: Quanxian Wang Date: Fri, 19 Jul 2024 09:17:13 +0800 Subject: [PATCH 15/17] Intel-SIG: Supprt Intel SPR/GNR/SRF new ISAs and cpu models Backporting commit list: 41bdd98128,target/i386: Export RFDS bit to guests,2024-03-13 07:53:23,Pawan Gupta 6e82d3b622,target/i386: Add new CPU model SierraForest,2024-03-20 10:10:44,Tao Su 3e76bafb28,target/i386: Add support for AMX-COMPLEX in CPUID enumeration,2023-08-30 15:43:24,Tao Su 6d5e9694ef,target/i386: Add new CPU model GraniteRapids,2023-07-06 13:49:49,Tao Su 6c43ec3b20,target/i386: Add new bit definitions of MSR_IA32_ARCH_CAPABILITIES,2023-07-06 13:49:47,Tao Su 9dd8b71091,target/i386: Add support for MCDT_NO in CPUID enumeration,2023-07-06 13:49:45,Tao Su 8731336e90,target/i386: Adjust feature level according to FEAT_7_1_EDX,2023-07-06 13:49:44,Tao Su d1a1111514,target/i386: Add support for PREFETCHIT0/1 in CPUID enumeration,2023-03-03 14:59:13,Jiaxi Chen ecd2e6ca03,target/i386: Add support for AVX-NE-CONVERT in CPUID enumeration,2023-03-03 14:59:12,Jiaxi Chen eaaa197d5b,target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration,2023-03-03 14:59:11,Jiaxi Chen a957a88416,target/i386: Add support for AVX-IFMA in CPUID enumeration,2023-03-03 14:59:10,Jiaxi Chen 99ed8445ea,target/i386: Add support for AMX-FP16 in CPUID enumeration,2023-03-03 14:59:09,Jiaxi Chen a9ce107fd0,target/i386: Add support for CMPCCXADD in CPUID enumeration,2023-03-03 14:59:08,Jiaxi Chen 7eb061b06e,i386: Add new CPU model SapphireRapids,2022-08-11 22:57:51,Wang, Lei 58794f644e,target/i386: add FZRM, FSRS, FSRC,2023-02-27 10:55:46,Paolo Bonzini c0728d4e3d,target/i386: add FSRM to TCG,2023-02-27 10:57:09,Paolo Bonzini Signed-off-by: Quanxian Wang --- 1077-target-i386-add-FSRM-to-TCG.patch | 35 +++ 1078-target-i386-add-FZRM-FSRS-FSRC.patch | 67 ++++++ ...386-Add-new-CPU-model-SapphireRapids.patch | 226 ++++++++++++++++++ ...support-for-CMPCCXADD-in-CPUID-enume.patch | 59 +++++ ...support-for-AMX-FP16-in-CPUID-enumer.patch | 60 +++++ ...support-for-AVX-IFMA-in-CPUID-enumer.patch | 58 +++++ ...support-for-AVX-VNNI-INT8-in-CPUID-e.patch | 108 +++++++++ ...support-for-AVX-NE-CONVERT-in-CPUID-.patch | 59 +++++ ...support-for-PREFETCHIT0-1-in-CPUID-e.patch | 58 +++++ ...st-feature-level-according-to-FEAT_7.patch | 43 ++++ ...new-bit-definitions-of-MSR_IA32_ARCH.patch | 40 ++++ ...support-for-MCDT_NO-in-CPUID-enumera.patch | 110 +++++++++ ...i386-Add-new-CPU-model-GraniteRapids.patch | 181 ++++++++++++++ ...support-for-AMX-COMPLEX-in-CPUID-enu.patch | 57 +++++ ...-i386-Add-new-CPU-model-SierraForest.patch | 207 ++++++++++++++++ ...arget-i386-Export-RFDS-bit-to-guests.patch | 45 ++++ qemu-kvm.spec | 17 ++ 17 files changed, 1430 insertions(+) create mode 100644 1077-target-i386-add-FSRM-to-TCG.patch create mode 100644 1078-target-i386-add-FZRM-FSRS-FSRC.patch create mode 100644 1079-i386-Add-new-CPU-model-SapphireRapids.patch create mode 100644 1080-target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch create mode 100644 1081-target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch create mode 100644 1082-target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch create mode 100644 1083-target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch create mode 100644 1084-target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch create mode 100644 1085-target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch create mode 100644 1086-target-i386-Adjust-feature-level-according-to-FEAT_7.patch create mode 100644 1087-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch create mode 100644 1088-target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch create mode 100644 1089-target-i386-Add-new-CPU-model-GraniteRapids.patch create mode 100644 1090-target-i386-Add-support-for-AMX-COMPLEX-in-CPUID-enu.patch create mode 100644 1091-target-i386-Add-new-CPU-model-SierraForest.patch create mode 100644 1092-target-i386-Export-RFDS-bit-to-guests.patch diff --git a/1077-target-i386-add-FSRM-to-TCG.patch b/1077-target-i386-add-FSRM-to-TCG.patch new file mode 100644 index 0000000..bf309ac --- /dev/null +++ b/1077-target-i386-add-FSRM-to-TCG.patch @@ -0,0 +1,35 @@ +From: Paolo Bonzini +Date: Mon, 27 Feb 2023 10:57:09 +0100 +Subject: [PATCH] target/i386: add FSRM to TCG + +commit c0728d4e3d23356691e4182eac54c67e1ca26618 upstream. + +Fast short REP MOVS can be added to TCG, since a trivial translation +of string operation is a good option for short lengths. + +Intel-SIG: commit c0728d4e3d23 target/i386: add FSRM to TCG. +Add SPR/GNR/SRA new ISAs backporting + +Reviewed-by: Xiaoyao Li +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 7d779c6a8..e54a60d3c 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -661,7 +661,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, + #define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | \ + /* CPUID_7_0_ECX_OSPKE is dynamic */ \ + CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS) +-#define TCG_7_0_EDX_FEATURES 0 ++#define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM + #define TCG_7_1_EAX_FEATURES 0 + #define TCG_APM_FEATURES 0 + #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT +-- +2.25.1 diff --git a/1078-target-i386-add-FZRM-FSRS-FSRC.patch b/1078-target-i386-add-FZRM-FSRS-FSRC.patch new file mode 100644 index 0000000..5b872b3 --- /dev/null +++ b/1078-target-i386-add-FZRM-FSRS-FSRC.patch @@ -0,0 +1,67 @@ +From: Paolo Bonzini +Date: Mon, 27 Feb 2023 10:55:46 +0100 +Subject: [PATCH] target/i386: add FZRM, FSRS, FSRC + +commit 58794f644e43ef8e60ed05395c58099311c1fcd1 upstream. + +These are three more markers for string operation optimizations. +They can all be added to TCG, whose string operations are more or +less as fast as they can be for short lengths. + +Intel-SIG: commit 58794f644e43 target/i386: add FZRM, FSRS, FSRC. +Add SPR/GNR/SRA new ISAs backporting + +Reviewed-by: Xiaoyao Li +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 7 ++++--- + target/i386/cpu.h | 7 +++++++ + 2 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index e54a60d3c..04cb9292b 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -662,7 +662,8 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, + /* CPUID_7_0_ECX_OSPKE is dynamic */ \ + CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS) + #define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM +-#define TCG_7_1_EAX_FEATURES 0 ++#define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \ ++ CPUID_7_1_EAX_FSRC) + #define TCG_APM_FEATURES 0 + #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT + #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1) +@@ -872,8 +873,8 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + .feat_names = { + NULL, NULL, NULL, NULL, + "avx-vnni", "avx512-bf16", NULL, NULL, +- NULL, NULL, NULL, NULL, +- NULL, NULL, NULL, NULL, ++ NULL, NULL, "fzrm", "fsrs", ++ "fsrc", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 1415a33fb..98f885ace 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -879,6 +879,13 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + #define CPUID_7_1_EAX_AVX_VNNI (1U << 4) + /* AVX512 BFloat16 Instruction */ + #define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) ++/* Fast Zero REP MOVS */ ++#define CPUID_7_1_EAX_FZRM (1U << 10) ++/* Fast Short REP STOS */ ++#define CPUID_7_1_EAX_FSRS (1U << 11) ++/* Fast Short REP CMPS/SCAS */ ++#define CPUID_7_1_EAX_FSRC (1U << 12) ++ + /* XFD Extend Feature Disabled */ + #define CPUID_D_1_EAX_XFD (1U << 4) + +-- +2.25.1 diff --git a/1079-i386-Add-new-CPU-model-SapphireRapids.patch b/1079-i386-Add-new-CPU-model-SapphireRapids.patch new file mode 100644 index 0000000..6176a1a --- /dev/null +++ b/1079-i386-Add-new-CPU-model-SapphireRapids.patch @@ -0,0 +1,226 @@ +From: "Wang, Lei" +Date: Thu, 11 Aug 2022 22:57:51 -0700 +Subject: [PATCH] i386: Add new CPU model SapphireRapids + +commit 7eb061b06e97af9a8da7f31b839d78997ae737fc upstream. + +The new CPU model mostly inherits features from Icelake-Server, while +adding new features: + - AMX (Advance Matrix eXtensions) + - Bus Lock Debug Exception +and new instructions: + - AVX VNNI (Vector Neural Network Instruction): + - VPDPBUS: Multiply and Add Unsigned and Signed Bytes + - VPDPBUSDS: Multiply and Add Unsigned and Signed Bytes with Saturation + - VPDPWSSD: Multiply and Add Signed Word Integers + - VPDPWSSDS: Multiply and Add Signed Integers with Saturation + - FP16: Replicates existing AVX512 computational SP (FP32) instructions + using FP16 instead of FP32 for ~2X performance gain + - SERIALIZE: Provide software with a simple way to force the processor to + complete all modifications, faster, allowed in all privilege levels and + not causing an unconditional VM exit + - TSX Suspend Load Address Tracking: Allows programmers to choose which + memory accesses do not need to be tracked in the TSX read set + - AVX512_BF16: Vector Neural Network Instructions supporting BFLOAT16 + inputs and conversion instructions from IEEE single precision + - fast zero-length MOVSB (KVM doesn't support yet) + - fast short STOSB (KVM doesn't support yet) + - fast short CMPSB, SCASB (KVM doesn't support yet) + +Features that may be added in future versions: + - CET (virtualization support hasn't been merged) + +Intel-SIG: commit 7eb061b06e97 i386: Add new CPU model SapphireRapids. +Add SPR/GNR/SRA new ISAs backporting + +Signed-off-by: Wang, Lei +Reviewed-by: Robert Hoo +Message-Id: <20220812055751.14553-1-lei4.wang@intel.com> +Reviewed-by: Xiaoyao Li +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 133 +++++++++++++++++++++++++++++++++++++++++++++- + target/i386/cpu.h | 4 ++ + 2 files changed, 135 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 04cb9292b..30d19b794 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -3546,6 +3546,135 @@ static const X86CPUDefinition builtin_x86_defs[] = { + { /* end of list */ } + } + }, ++ { ++ .name = "SapphireRapids", ++ .level = 0x20, ++ .vendor = CPUID_VENDOR_INTEL, ++ .family = 6, ++ .model = 143, ++ .stepping = 4, ++ /* ++ * please keep the ascending order so that we can have a clear view of ++ * bit position of each feature. ++ */ ++ .features[FEAT_1_EDX] = ++ CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | ++ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | ++ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | ++ CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR | ++ CPUID_SSE | CPUID_SSE2, ++ .features[FEAT_1_ECX] = ++ CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 | ++ CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | CPUID_EXT_SSE41 | ++ CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE | ++ CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES | ++ CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND, ++ .features[FEAT_8000_0001_EDX] = ++ CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB | ++ CPUID_EXT2_RDTSCP | CPUID_EXT2_LM, ++ .features[FEAT_8000_0001_ECX] = ++ CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH, ++ .features[FEAT_8000_0008_EBX] = ++ CPUID_8000_0008_EBX_WBNOINVD, ++ .features[FEAT_7_0_EBX] = ++ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_HLE | ++ CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | ++ CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RTM | ++ CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ | ++ CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | ++ CPUID_7_0_EBX_AVX512IFMA | CPUID_7_0_EBX_CLFLUSHOPT | ++ CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_AVX512CD | CPUID_7_0_EBX_SHA_NI | ++ CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL, ++ .features[FEAT_7_0_ECX] = ++ CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | ++ CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI | ++ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ | ++ CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG | ++ CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57 | ++ CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT, ++ .features[FEAT_7_0_EDX] = ++ CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_SERIALIZE | ++ CPUID_7_0_EDX_TSX_LDTRK | CPUID_7_0_EDX_AMX_BF16 | ++ CPUID_7_0_EDX_AVX512_FP16 | CPUID_7_0_EDX_AMX_TILE | ++ CPUID_7_0_EDX_AMX_INT8 | CPUID_7_0_EDX_SPEC_CTRL | ++ CPUID_7_0_EDX_ARCH_CAPABILITIES | CPUID_7_0_EDX_SPEC_CTRL_SSBD, ++ .features[FEAT_ARCH_CAPABILITIES] = ++ MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL | ++ MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO | ++ MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_TAA_NO, ++ .features[FEAT_XSAVE] = ++ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | ++ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES | CPUID_D_1_EAX_XFD, ++ .features[FEAT_6_EAX] = ++ CPUID_6_EAX_ARAT, ++ .features[FEAT_7_1_EAX] = ++ CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_AVX512_BF16 | ++ CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_FSRC, ++ .features[FEAT_VMX_BASIC] = ++ MSR_VMX_BASIC_INS_OUTS | MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_ENTRY_LOAD_IA32_PAT | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = ++ MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_PAGE_WALK_LENGTH_5 | ++ MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB | ++ MSR_VMX_EPT_INVEPT | MSR_VMX_EPT_AD_BITS | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | ++ MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_IA32_PAT | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_LOAD_IA32_EFER | VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = ++ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_VMWRITE_VMEXIT, ++ .features[FEAT_VMX_PINBASED_CTLS] = ++ VMX_PIN_BASED_EXT_INTR_MASK | VMX_PIN_BASED_NMI_EXITING | ++ VMX_PIN_BASED_VIRTUAL_NMIS | VMX_PIN_BASED_VMX_PREEMPTION_TIMER | ++ VMX_PIN_BASED_POSTED_INTR, ++ .features[FEAT_VMX_PROCBASED_CTLS] = ++ VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_VIRTUAL_NMI_PENDING | ++ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING | ++ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_USE_MSR_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING | ++ VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_ENABLE_EPT | VMX_SECONDARY_EXEC_DESC | ++ VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_WBINVD_EXITING | ++ VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | ++ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING | ++ VMX_SECONDARY_EXEC_ENABLE_INVPCID | ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | ++ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML | ++ VMX_SECONDARY_EXEC_XSAVES, ++ .features[FEAT_VMX_VMFUNC] = ++ MSR_VMX_VMFUNC_EPT_SWITCHING, ++ .xlevel = 0x80000008, ++ .model_id = "Intel Xeon Processor (SapphireRapids)", ++ .versions = (X86CPUVersionDefinition[]) { ++ { .version = 1 }, ++ { /* end of list */ }, ++ }, ++ }, + { + .name = "Denverton", + .level = 21, +@@ -5616,7 +5745,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + break; + } + case 0x1D: { +- /* AMX TILE */ ++ /* AMX TILE, for now hardcoded for Sapphire Rapids*/ + *eax = 0; + *ebx = 0; + *ecx = 0; +@@ -5637,7 +5766,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + break; + } + case 0x1E: { +- /* AMX TMUL */ ++ /* AMX TMUL, for now hardcoded for Sapphire Rapids */ + *eax = 0; + *ebx = 0; + *ecx = 0; +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 98f885ace..d156ccd17 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -858,10 +858,14 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + #define CPUID_7_0_EDX_SERIALIZE (1U << 14) + /* TSX Suspend Load Address Tracking instruction */ + #define CPUID_7_0_EDX_TSX_LDTRK (1U << 16) ++/* AMX_BF16 instruction */ ++#define CPUID_7_0_EDX_AMX_BF16 (1U << 22) + /* AVX512_FP16 instruction */ + #define CPUID_7_0_EDX_AVX512_FP16 (1U << 23) + /* AMX tile (two-dimensional register) */ + #define CPUID_7_0_EDX_AMX_TILE (1U << 24) ++/* AMX_INT8 instruction */ ++#define CPUID_7_0_EDX_AMX_INT8 (1U << 25) + /* Speculation Control */ + #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) + /* Single Thread Indirect Branch Predictors */ +-- +2.25.1 diff --git a/1080-target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch b/1080-target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch new file mode 100644 index 0000000..de83c11 --- /dev/null +++ b/1080-target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch @@ -0,0 +1,59 @@ +From: Jiaxi Chen +Date: Fri, 3 Mar 2023 14:59:08 +0800 +Subject: [PATCH] target/i386: Add support for CMPCCXADD in CPUID enumeration + +commit a9ce107fd0f2017af84255a9cf6542fa3eb3e214 upstream. + +CMPccXADD is a new set of instructions in the latest Intel platform +Sierra Forest. This new instruction set includes a semaphore operation +that can compare and add the operands if condition is met, which can +improve database performance. + +The bit definition: +CPUID.(EAX=7,ECX=1):EAX[bit 7] + +Add CPUID definition for CMPCCXADD. + +Intel-SIG: commit a9ce107fd0f2 target/i386: Add support for CMPCCXADD in CPUID enumeration. +Add SPR/GNR/SRA new ISAs backporting + +Signed-off-by: Jiaxi Chen +Signed-off-by: Tao Su +Reviewed-by: Xiaoyao Li +Message-Id: <20230303065913.1246327-2-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 2 +- + target/i386/cpu.h | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 30d19b794..6a8e07904 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -872,7 +872,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + .type = CPUID_FEATURE_WORD, + .feat_names = { + NULL, NULL, NULL, NULL, +- "avx-vnni", "avx512-bf16", NULL, NULL, ++ "avx-vnni", "avx512-bf16", NULL, "cmpccxadd", + NULL, NULL, "fzrm", "fsrs", + "fsrc", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index d156ccd17..f8f5c1d85 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -883,6 +883,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + #define CPUID_7_1_EAX_AVX_VNNI (1U << 4) + /* AVX512 BFloat16 Instruction */ + #define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) ++/* CMPCCXADD Instructions */ ++#define CPUID_7_1_EAX_CMPCCXADD (1U << 7) + /* Fast Zero REP MOVS */ + #define CPUID_7_1_EAX_FZRM (1U << 10) + /* Fast Short REP STOS */ +-- +2.25.1 diff --git a/1081-target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch b/1081-target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch new file mode 100644 index 0000000..b4d6ebc --- /dev/null +++ b/1081-target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch @@ -0,0 +1,60 @@ +From: Jiaxi Chen +Date: Fri, 3 Mar 2023 14:59:09 +0800 +Subject: [PATCH] target/i386: Add support for AMX-FP16 in CPUID enumeration + +commit 99ed8445ea27742a4df40f51a3a5fbd6f8e76fa5 upstream. + +Latest Intel platform Granite Rapids has introduced a new instruction - +AMX-FP16, which performs dot-products of two FP16 tiles and accumulates +the results into a packed single precision tile. AMX-FP16 adds FP16 +capability and allows a FP16 GPU trained model to run faster without +loss of accuracy or added SW overhead. + +The bit definition: +CPUID.(EAX=7,ECX=1):EAX[bit 21] + +Add CPUID definition for AMX-FP16. + +Intel-SIG: commit 99ed8445ea27 target/i386: Add support for AMX-FP16 in CPUID enumeration. +Add SPR/GNR/SRA new ISAs backporting + +Signed-off-by: Jiaxi Chen +Signed-off-by: Tao Su +Reviewed-by: Xiaoyao Li +Message-Id: <20230303065913.1246327-3-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 2 +- + target/i386/cpu.h | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 6a8e07904..074dcb573 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -876,7 +876,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + NULL, NULL, "fzrm", "fsrs", + "fsrc", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +- NULL, NULL, NULL, NULL, ++ NULL, "amx-fp16", NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + }, +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index f8f5c1d85..62f61cefb 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -891,6 +891,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + #define CPUID_7_1_EAX_FSRS (1U << 11) + /* Fast Short REP CMPS/SCAS */ + #define CPUID_7_1_EAX_FSRC (1U << 12) ++/* Support Tile Computational Operations on FP16 Numbers */ ++#define CPUID_7_1_EAX_AMX_FP16 (1U << 21) + + /* XFD Extend Feature Disabled */ + #define CPUID_D_1_EAX_XFD (1U << 4) +-- +2.25.1 diff --git a/1082-target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch b/1082-target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch new file mode 100644 index 0000000..1234f5d --- /dev/null +++ b/1082-target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch @@ -0,0 +1,58 @@ +From: Jiaxi Chen +Date: Fri, 3 Mar 2023 14:59:10 +0800 +Subject: [PATCH] target/i386: Add support for AVX-IFMA in CPUID enumeration + +commit a957a88416ecbec51e147cba9fe89b93f6646b3b upstream. + +AVX-IFMA is a new instruction in the latest Intel platform Sierra +Forest. This instruction packed multiplies unsigned 52-bit integers and +adds the low/high 52-bit products to Qword Accumulators. + +The bit definition: +CPUID.(EAX=7,ECX=1):EAX[bit 23] + +Add CPUID definition for AVX-IFMA. + +Intel-SIG: commit a957a88416ec target/i386: Add support for AVX-IFMA in CPUID enumeration. +Add SPR/GNR/SRA new ISAs backporting + +Signed-off-by: Jiaxi Chen +Signed-off-by: Tao Su +Reviewed-by: Xiaoyao Li +Message-Id: <20230303065913.1246327-4-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 2 +- + target/i386/cpu.h | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 074dcb573..556810da8 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -876,7 +876,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + NULL, NULL, "fzrm", "fsrs", + "fsrc", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +- NULL, "amx-fp16", NULL, NULL, ++ NULL, "amx-fp16", NULL, "avx-ifma", + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + }, +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 62f61cefb..4f5e1f35d 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -893,6 +893,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + #define CPUID_7_1_EAX_FSRC (1U << 12) + /* Support Tile Computational Operations on FP16 Numbers */ + #define CPUID_7_1_EAX_AMX_FP16 (1U << 21) ++/* Support for VPMADD52[H,L]UQ */ ++#define CPUID_7_1_EAX_AVX_IFMA (1U << 23) + + /* XFD Extend Feature Disabled */ + #define CPUID_D_1_EAX_XFD (1U << 4) +-- +2.25.1 diff --git a/1083-target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch b/1083-target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch new file mode 100644 index 0000000..066813d --- /dev/null +++ b/1083-target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch @@ -0,0 +1,108 @@ +From: Jiaxi Chen +Date: Fri, 3 Mar 2023 14:59:11 +0800 +Subject: [PATCH] target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration + +commit eaaa197d5b112ea2758b54df58881a2626de3af5 upstream. + +AVX-VNNI-INT8 is a new set of instructions in the latest Intel platform +Sierra Forest, aims for the platform to have superior AI capabilities. +This instruction multiplies the individual bytes of two unsigned or +unsigned source operands, then adds and accumulates the results into the +destination dword element size operand. + +The bit definition: +CPUID.(EAX=7,ECX=1):EDX[bit 4] + +AVX-VNNI-INT8 is on a new feature bits leaf. Add a CPUID feature word +FEAT_7_1_EDX for this leaf. + +Add CPUID definition for AVX-VNNI-INT8. + +Intel-SIG: commit eaaa197d5b11 target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration. +Add SPR/GNR/SRA new ISAs backporting + +Signed-off-by: Jiaxi Chen +Signed-off-by: Tao Su +Reviewed-by: Xiaoyao Li +Message-Id: <20230303065913.1246327-5-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 22 +++++++++++++++++++++- + target/i386/cpu.h | 4 ++++ + 2 files changed, 25 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 556810da8..cd7ee2473 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -664,6 +664,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, + #define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM + #define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \ + CPUID_7_1_EAX_FSRC) ++#define TCG_7_1_EDX_FEATURES 0 + #define TCG_APM_FEATURES 0 + #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT + #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1) +@@ -887,6 +888,25 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + }, + .tcg_features = TCG_7_1_EAX_FEATURES, + }, ++ [FEAT_7_1_EDX] = { ++ .type = CPUID_FEATURE_WORD, ++ .feat_names = { ++ NULL, NULL, NULL, NULL, ++ "avx-vnni-int8", NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ }, ++ .cpuid = { ++ .eax = 7, ++ .needs_ecx = true, .ecx = 1, ++ .reg = R_EDX, ++ }, ++ .tcg_features = TCG_7_1_EDX_FEATURES, ++ }, + [FEAT_8000_0007_EDX] = { + .type = CPUID_FEATURE_WORD, + .feat_names = { +@@ -5525,9 +5545,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + } + } else if (count == 1) { + *eax = env->features[FEAT_7_1_EAX]; ++ *edx = env->features[FEAT_7_1_EDX]; + *ebx = 0; + *ecx = 0; +- *edx = 0; + } else { + *eax = 0; + *ebx = 0; +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 4f5e1f35d..79e456d47 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -602,6 +602,7 @@ typedef enum FeatureWord { + FEAT_SGX_12_0_EAX, /* CPUID[EAX=0x12,ECX=0].EAX (SGX) */ + FEAT_SGX_12_0_EBX, /* CPUID[EAX=0x12,ECX=0].EBX (SGX MISCSELECT[31:0]) */ + FEAT_SGX_12_1_EAX, /* CPUID[EAX=0x12,ECX=1].EAX (SGX ATTRIBUTES[31:0]) */ ++ FEAT_7_1_EDX, /* CPUID[EAX=7,ECX=1].EDX */ + FEATURE_WORDS, + } FeatureWord; + +@@ -896,6 +897,9 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + /* Support for VPMADD52[H,L]UQ */ + #define CPUID_7_1_EAX_AVX_IFMA (1U << 23) + ++/* Support for VPDPB[SU,UU,SS]D[,S] */ ++#define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4) ++ + /* XFD Extend Feature Disabled */ + #define CPUID_D_1_EAX_XFD (1U << 4) + +-- +2.25.1 diff --git a/1084-target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch b/1084-target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch new file mode 100644 index 0000000..3672e8b --- /dev/null +++ b/1084-target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch @@ -0,0 +1,59 @@ +From: Jiaxi Chen +Date: Fri, 3 Mar 2023 14:59:12 +0800 +Subject: [PATCH] target/i386: Add support for AVX-NE-CONVERT in CPUID enumeration + +commit ecd2e6ca037d7bf3673c5478590d686d5cd6135a upstream. + +AVX-NE-CONVERT is a new set of instructions which can convert low +precision floating point like BF16/FP16 to high precision floating point +FP32, as well as convert FP32 elements to BF16. This instruction allows +the platform to have improved AI capabilities and better compatibility. + +The bit definition: +CPUID.(EAX=7,ECX=1):EDX[bit 5] + +Add CPUID definition for AVX-NE-CONVERT. + +Intel-SIG: commit ecd2e6ca037d target/i386: Add support for AVX-NE-CONVERT in CPUID enumeration. +Add SPR/GNR/SRA new ISAs backporting + +Signed-off-by: Jiaxi Chen +Signed-off-by: Tao Su +Reviewed-by: Xiaoyao Li +Message-Id: <20230303065913.1246327-6-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 2 +- + target/i386/cpu.h | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index cd7ee2473..eb5e0b0b7 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -892,7 +892,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + .type = CPUID_FEATURE_WORD, + .feat_names = { + NULL, NULL, NULL, NULL, +- "avx-vnni-int8", NULL, NULL, NULL, ++ "avx-vnni-int8", "avx-ne-convert", NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 79e456d47..4757479ac 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -899,6 +899,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + + /* Support for VPDPB[SU,UU,SS]D[,S] */ + #define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4) ++/* AVX NE CONVERT Instructions */ ++#define CPUID_7_1_EDX_AVX_NE_CONVERT (1U << 5) + + /* XFD Extend Feature Disabled */ + #define CPUID_D_1_EAX_XFD (1U << 4) +-- +2.25.1 diff --git a/1085-target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch b/1085-target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch new file mode 100644 index 0000000..38b6f03 --- /dev/null +++ b/1085-target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch @@ -0,0 +1,58 @@ +From: Jiaxi Chen +Date: Fri, 3 Mar 2023 14:59:13 +0800 +Subject: [PATCH] target/i386: Add support for PREFETCHIT0/1 in CPUID enumeration + +commit d1a1111514333e46a98b136235f71eef90d610fa upstream. + +Latest Intel platform Granite Rapids has introduced a new instruction - +PREFETCHIT0/1, which moves code to memory (cache) closer to the +processor depending on specific hints. + +The bit definition: +CPUID.(EAX=7,ECX=1):EDX[bit 14] + +Add CPUID definition for PREFETCHIT0/1. + +Intel-SIG: commit d1a111151433 target/i386: Add support for PREFETCHIT0/1 in CPUID enumeration. +Add SPR/GNR/SRA new ISAs backporting + +Signed-off-by: Jiaxi Chen +Signed-off-by: Tao Su +Reviewed-by: Xiaoyao Li +Message-Id: <20230303065913.1246327-7-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 2 +- + target/i386/cpu.h | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index eb5e0b0b7..7738d29e8 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -894,7 +894,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + NULL, NULL, NULL, NULL, + "avx-vnni-int8", "avx-ne-convert", NULL, NULL, + NULL, NULL, NULL, NULL, +- NULL, NULL, NULL, NULL, ++ NULL, NULL, "prefetchiti", NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 4757479ac..435f458cf 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -901,6 +901,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + #define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4) + /* AVX NE CONVERT Instructions */ + #define CPUID_7_1_EDX_AVX_NE_CONVERT (1U << 5) ++/* PREFETCHIT0/1 Instructions */ ++#define CPUID_7_1_EDX_PREFETCHITI (1U << 14) + + /* XFD Extend Feature Disabled */ + #define CPUID_D_1_EAX_XFD (1U << 4) +-- +2.25.1 diff --git a/1086-target-i386-Adjust-feature-level-according-to-FEAT_7.patch b/1086-target-i386-Adjust-feature-level-according-to-FEAT_7.patch new file mode 100644 index 0000000..d4990f0 --- /dev/null +++ b/1086-target-i386-Adjust-feature-level-according-to-FEAT_7.patch @@ -0,0 +1,43 @@ +From: Tao Su +Date: Thu, 6 Jul 2023 13:49:44 +0800 +Subject: [PATCH] target/i386: Adjust feature level according to FEAT_7_1_EDX + +commit 8731336e90dea3dd04948127e775c9f087f97a4c upstream. + +If FEAT_7_1_EAX is 0 and FEAT_7_1_EDX is non-zero, as is the case +with a Granite Rapids host and +'-cpu host,-avx-vnni,-avx512-bf16,-fzrm,-fsrs,-fsrc,-amx-fp16', we can't +get CPUID_7_1 leaf even though CPUID_7_1_EDX has non-zero value. + +Update cpuid_level_func7 according to CPUID_7_1_EDX, otherwise +guest may report wrong maximum number sub-leaves in leaf 07H. + +Fixes: eaaa197d5b11 ("target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration") +Intel-SIG: commit 8731336e90de target/i386: Adjust feature level according to FEAT_7_1_EDX. +Add SPR/GNR/SRA new ISAs backporting + +Cc: qemu-stable@nongnu.org +Signed-off-by: Tao Su +Reviewed-by: Xiaoyao Li +Message-ID: <20230706054949.66556-2-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 7738d29e8..32937b0d0 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -6369,6 +6369,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX); + x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX); + x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EAX); ++ x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EDX); + x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX); + x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX); + x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX); +-- +2.25.1 diff --git a/1087-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch b/1087-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch new file mode 100644 index 0000000..69cacca --- /dev/null +++ b/1087-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch @@ -0,0 +1,40 @@ +From: Tao Su +Date: Thu, 6 Jul 2023 13:49:47 +0800 +Subject: [PATCH] target/i386: Add new bit definitions of MSR_IA32_ARCH_CAPABILITIES + +commit 6c43ec3b206956a8a3008accafe9eb2dfd885190 upstream. + +Currently, bit 13, 14, 15 and 24 of MSR_IA32_ARCH_CAPABILITIES are +disclosed for fixing security issues, so add those bit definitions. + +Intel-SIG: commit 6c43ec3b2069 target/i386: Add new bit definitions of MSR_IA32_ARCH_CAPABILITIES. +Add SPR/GNR/SRA new ISAs backporting + +Signed-off-by: Tao Su +Reviewed-by: Igor Mammedov +Message-ID: <20230706054949.66556-5-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 435f458cf..c65133ab6 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -977,7 +977,11 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + #define MSR_ARCH_CAP_PSCHANGE_MC_NO (1U << 6) + #define MSR_ARCH_CAP_TSX_CTRL_MSR (1U << 7) + #define MSR_ARCH_CAP_TAA_NO (1U << 8) ++#define MSR_ARCH_CAP_SBDR_SSDP_NO (1U << 13) ++#define MSR_ARCH_CAP_FBSDP_NO (1U << 14) ++#define MSR_ARCH_CAP_PSDP_NO (1U << 15) + #define MSR_ARCH_CAP_FB_CLEAR (1U << 17) ++#define MSR_ARCH_CAP_PBRSB_NO (1U << 24) + + #define MSR_CORE_CAP_SPLIT_LOCK_DETECT (1U << 5) + +-- +2.25.1 diff --git a/1088-target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch b/1088-target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch new file mode 100644 index 0000000..0fcfd8e --- /dev/null +++ b/1088-target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch @@ -0,0 +1,110 @@ +From: Tao Su +Date: Thu, 6 Jul 2023 13:49:45 +0800 +Subject: [PATCH] target/i386: Add support for MCDT_NO in CPUID enumeration + +commit 9dd8b71091f47bac395f543779269c14d8d93c60 upstream. + +CPUID.(EAX=7,ECX=2):EDX[bit 5] enumerates MCDT_NO. Processors enumerate +this bit as 1 do not exhibit MXCSR Configuration Dependent Timing (MCDT) +behavior and do not need to be mitigated to avoid data-dependent behavior +for certain instructions. + +Since MCDT_NO is in a new sub-leaf, add a new CPUID feature word +FEAT_7_2_EDX. Also update cpuid_level_func7 by FEAT_7_2_EDX. + +Intel-SIG: commit 9dd8b71091f4 target/i386: Add support for MCDT_NO in CPUID enumeration. +Add SPR/GNR/SRA new ISAs backporting + +Signed-off-by: Tao Su +Reviewed-by: Xiaoyao Li +Message-ID: <20230706054949.66556-3-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 26 ++++++++++++++++++++++++++ + target/i386/cpu.h | 4 ++++ + 2 files changed, 30 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 32937b0d0..0547dda2e 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -665,6 +665,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, + #define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \ + CPUID_7_1_EAX_FSRC) + #define TCG_7_1_EDX_FEATURES 0 ++#define TCG_7_2_EDX_FEATURES 0 + #define TCG_APM_FEATURES 0 + #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT + #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1) +@@ -907,6 +908,25 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + }, + .tcg_features = TCG_7_1_EDX_FEATURES, + }, ++ [FEAT_7_2_EDX] = { ++ .type = CPUID_FEATURE_WORD, ++ .feat_names = { ++ NULL, NULL, NULL, NULL, ++ NULL, "mcdt-no", NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ }, ++ .cpuid = { ++ .eax = 7, ++ .needs_ecx = true, .ecx = 2, ++ .reg = R_EDX, ++ }, ++ .tcg_features = TCG_7_2_EDX_FEATURES, ++ }, + [FEAT_8000_0007_EDX] = { + .type = CPUID_FEATURE_WORD, + .feat_names = { +@@ -5548,6 +5568,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + *edx = env->features[FEAT_7_1_EDX]; + *ebx = 0; + *ecx = 0; ++ } else if (count == 2) { ++ *edx = env->features[FEAT_7_2_EDX]; ++ *eax = 0; ++ *ebx = 0; ++ *ecx = 0; + } else { + *eax = 0; + *ebx = 0; +@@ -6370,6 +6395,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX); + x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EAX); + x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EDX); ++ x86_cpu_adjust_feat_level(cpu, FEAT_7_2_EDX); + x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX); + x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX); + x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX); +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index c65133ab6..26572b846 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -603,6 +603,7 @@ typedef enum FeatureWord { + FEAT_SGX_12_0_EBX, /* CPUID[EAX=0x12,ECX=0].EBX (SGX MISCSELECT[31:0]) */ + FEAT_SGX_12_1_EAX, /* CPUID[EAX=0x12,ECX=1].EAX (SGX ATTRIBUTES[31:0]) */ + FEAT_7_1_EDX, /* CPUID[EAX=7,ECX=1].EDX */ ++ FEAT_7_2_EDX, /* CPUID[EAX=7,ECX=2].EDX */ + FEATURE_WORDS, + } FeatureWord; + +@@ -904,6 +905,9 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + /* PREFETCHIT0/1 Instructions */ + #define CPUID_7_1_EDX_PREFETCHITI (1U << 14) + ++/* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */ ++#define CPUID_7_2_EDX_MCDT_NO (1U << 5) ++ + /* XFD Extend Feature Disabled */ + #define CPUID_D_1_EAX_XFD (1U << 4) + +-- +2.25.1 diff --git a/1089-target-i386-Add-new-CPU-model-GraniteRapids.patch b/1089-target-i386-Add-new-CPU-model-GraniteRapids.patch new file mode 100644 index 0000000..938ced8 --- /dev/null +++ b/1089-target-i386-Add-new-CPU-model-GraniteRapids.patch @@ -0,0 +1,181 @@ +From: Tao Su +Date: Thu, 6 Jul 2023 13:49:49 +0800 +Subject: [PATCH] target/i386: Add new CPU model GraniteRapids + +commit 6d5e9694ef374159072984c0958c3eaab6dd1d52 upstream. + +The GraniteRapids CPU model mainly adds the following new features +based on SapphireRapids: +- PREFETCHITI CPUID.(EAX=7,ECX=1):EDX[bit 14] +- AMX-FP16 CPUID.(EAX=7,ECX=1):EAX[bit 21] + +And adds the following security fix for corresponding vulnerabilities: +- MCDT_NO CPUID.(EAX=7,ECX=2):EDX[bit 5] +- SBDR_SSDP_NO MSR_IA32_ARCH_CAPABILITIES[bit 13] +- FBSDP_NO MSR_IA32_ARCH_CAPABILITIES[bit 14] +- PSDP_NO MSR_IA32_ARCH_CAPABILITIES[bit 15] +- PBRSB_NO MSR_IA32_ARCH_CAPABILITIES[bit 24] + +Intel-SIG: commit 6d5e9694ef37 target/i386: Add new CPU model GraniteRapids. +Add SPR/GNR/SRA new ISAs backporting + +Signed-off-by: Tao Su +Tested-by: Xuelian Guo +Reviewed-by: Xiaoyao Li +Message-ID: <20230706054949.66556-7-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 136 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 0547dda2e..b7cdca7cc 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -3966,6 +3966,142 @@ static const X86CPUDefinition builtin_x86_defs[] = { + { /* end of list */ }, + }, + }, ++ { ++ .name = "GraniteRapids", ++ .level = 0x20, ++ .vendor = CPUID_VENDOR_INTEL, ++ .family = 6, ++ .model = 173, ++ .stepping = 0, ++ /* ++ * please keep the ascending order so that we can have a clear view of ++ * bit position of each feature. ++ */ ++ .features[FEAT_1_EDX] = ++ CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | ++ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | ++ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | ++ CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR | ++ CPUID_SSE | CPUID_SSE2, ++ .features[FEAT_1_ECX] = ++ CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 | ++ CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | CPUID_EXT_SSE41 | ++ CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE | ++ CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES | ++ CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND, ++ .features[FEAT_8000_0001_EDX] = ++ CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB | ++ CPUID_EXT2_RDTSCP | CPUID_EXT2_LM, ++ .features[FEAT_8000_0001_ECX] = ++ CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH, ++ .features[FEAT_8000_0008_EBX] = ++ CPUID_8000_0008_EBX_WBNOINVD, ++ .features[FEAT_7_0_EBX] = ++ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_HLE | ++ CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | ++ CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RTM | ++ CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ | ++ CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | ++ CPUID_7_0_EBX_AVX512IFMA | CPUID_7_0_EBX_CLFLUSHOPT | ++ CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_AVX512CD | CPUID_7_0_EBX_SHA_NI | ++ CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL, ++ .features[FEAT_7_0_ECX] = ++ CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | ++ CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI | ++ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ | ++ CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG | ++ CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57 | ++ CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT, ++ .features[FEAT_7_0_EDX] = ++ CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_SERIALIZE | ++ CPUID_7_0_EDX_TSX_LDTRK | CPUID_7_0_EDX_AMX_BF16 | ++ CPUID_7_0_EDX_AVX512_FP16 | CPUID_7_0_EDX_AMX_TILE | ++ CPUID_7_0_EDX_AMX_INT8 | CPUID_7_0_EDX_SPEC_CTRL | ++ CPUID_7_0_EDX_ARCH_CAPABILITIES | CPUID_7_0_EDX_SPEC_CTRL_SSBD, ++ .features[FEAT_ARCH_CAPABILITIES] = ++ MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL | ++ MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO | ++ MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_TAA_NO | ++ MSR_ARCH_CAP_SBDR_SSDP_NO | MSR_ARCH_CAP_FBSDP_NO | ++ MSR_ARCH_CAP_PSDP_NO | MSR_ARCH_CAP_PBRSB_NO, ++ .features[FEAT_XSAVE] = ++ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | ++ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES | CPUID_D_1_EAX_XFD, ++ .features[FEAT_6_EAX] = ++ CPUID_6_EAX_ARAT, ++ .features[FEAT_7_1_EAX] = ++ CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_AVX512_BF16 | ++ CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_FSRC | ++ CPUID_7_1_EAX_AMX_FP16, ++ .features[FEAT_7_1_EDX] = ++ CPUID_7_1_EDX_PREFETCHITI, ++ .features[FEAT_7_2_EDX] = ++ CPUID_7_2_EDX_MCDT_NO, ++ .features[FEAT_VMX_BASIC] = ++ MSR_VMX_BASIC_INS_OUTS | MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_ENTRY_LOAD_IA32_PAT | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = ++ MSR_VMX_EPT_EXECONLY | ++ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_PAGE_WALK_LENGTH_5 | ++ MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB | ++ MSR_VMX_EPT_INVEPT | MSR_VMX_EPT_AD_BITS | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | ++ MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_IA32_PAT | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_LOAD_IA32_EFER | VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = ++ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_VMWRITE_VMEXIT, ++ .features[FEAT_VMX_PINBASED_CTLS] = ++ VMX_PIN_BASED_EXT_INTR_MASK | VMX_PIN_BASED_NMI_EXITING | ++ VMX_PIN_BASED_VIRTUAL_NMIS | VMX_PIN_BASED_VMX_PREEMPTION_TIMER | ++ VMX_PIN_BASED_POSTED_INTR, ++ .features[FEAT_VMX_PROCBASED_CTLS] = ++ VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_VIRTUAL_NMI_PENDING | ++ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING | ++ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_USE_MSR_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING | ++ VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_ENABLE_EPT | VMX_SECONDARY_EXEC_DESC | ++ VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_WBINVD_EXITING | ++ VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | ++ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING | ++ VMX_SECONDARY_EXEC_ENABLE_INVPCID | ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | ++ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML | ++ VMX_SECONDARY_EXEC_XSAVES, ++ .features[FEAT_VMX_VMFUNC] = ++ MSR_VMX_VMFUNC_EPT_SWITCHING, ++ .xlevel = 0x80000008, ++ .model_id = "Intel Xeon Processor (GraniteRapids)", ++ .versions = (X86CPUVersionDefinition[]) { ++ { .version = 1 }, ++ { /* end of list */ }, ++ }, ++ }, + { + .name = "KnightsMill", + .level = 0xd, +-- +2.25.1 diff --git a/1090-target-i386-Add-support-for-AMX-COMPLEX-in-CPUID-enu.patch b/1090-target-i386-Add-support-for-AMX-COMPLEX-in-CPUID-enu.patch new file mode 100644 index 0000000..5d175da --- /dev/null +++ b/1090-target-i386-Add-support-for-AMX-COMPLEX-in-CPUID-enu.patch @@ -0,0 +1,57 @@ +From: Tao Su +Date: Wed, 30 Aug 2023 15:43:24 +0800 +Subject: [PATCH] target/i386: Add support for AMX-COMPLEX in CPUID enumeration + +commit 3e76bafb28c8292be5c4a32cab873b3a82cbcc87 upstream. + +Latest Intel platform GraniteRapids-D introduces AMX-COMPLEX, which adds +two instructions to perform matrix multiplication of two tiles containing +complex elements and accumulate the results into a packed single precision +tile. + +AMX-COMPLEX is enumerated via CPUID.(EAX=7,ECX=1):EDX[bit 8]. Add the CPUID +definition for AMX-COMPLEX, AMX-COMPLEX will be enabled automatically when +using '-cpu host' and KVM advertises AMX-COMPLEX to userspace. + +Intel-SIG: commit 3e76bafb28c8 target/i386: Add support for AMX-COMPLEX in CPUID enumeration. +Add SPR/GNR/SRA new ISAs backporting + +Signed-off-by: Tao Su +Reviewed-by: Xiaoyao Li +Message-ID: <20230830074324.84059-1-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 2 +- + target/i386/cpu.h | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index b7cdca7cc..4a33baade 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -894,7 +894,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + .feat_names = { + NULL, NULL, NULL, NULL, + "avx-vnni-int8", "avx-ne-convert", NULL, NULL, +- NULL, NULL, NULL, NULL, ++ "amx-complex", NULL, NULL, NULL, + NULL, NULL, "prefetchiti", NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 26572b846..e84cb8265 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -902,6 +902,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, + #define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4) + /* AVX NE CONVERT Instructions */ + #define CPUID_7_1_EDX_AVX_NE_CONVERT (1U << 5) ++/* AMX COMPLEX Instructions */ ++#define CPUID_7_1_EDX_AMX_COMPLEX (1U << 8) + /* PREFETCHIT0/1 Instructions */ + #define CPUID_7_1_EDX_PREFETCHITI (1U << 14) + +-- +2.25.1 diff --git a/1091-target-i386-Add-new-CPU-model-SierraForest.patch b/1091-target-i386-Add-new-CPU-model-SierraForest.patch new file mode 100644 index 0000000..8ab9a09 --- /dev/null +++ b/1091-target-i386-Add-new-CPU-model-SierraForest.patch @@ -0,0 +1,207 @@ +From: Tao Su +Date: Wed, 20 Mar 2024 10:10:44 +0800 +Subject: [PATCH] target/i386: Add new CPU model SierraForest + +commit 6e82d3b6220777667968a04c87e1667f164ebe88 upstream. + +According to table 1-2 in Intel Architecture Instruction Set Extensions and +Future Features (rev 051) [1], SierraForest has the following new features +which have already been virtualized: + +- CMPCCXADD CPUID.(EAX=7,ECX=1):EAX[bit 7] +- AVX-IFMA CPUID.(EAX=7,ECX=1):EAX[bit 23] +- AVX-VNNI-INT8 CPUID.(EAX=7,ECX=1):EDX[bit 4] +- AVX-NE-CONVERT CPUID.(EAX=7,ECX=1):EDX[bit 5] + +Add above features to new CPU model SierraForest. Comparing with GraniteRapids +CPU model, SierraForest bare-metal removes the following features: + +- HLE CPUID.(EAX=7,ECX=0):EBX[bit 4] +- RTM CPUID.(EAX=7,ECX=0):EBX[bit 11] +- AVX512F CPUID.(EAX=7,ECX=0):EBX[bit 16] +- AVX512DQ CPUID.(EAX=7,ECX=0):EBX[bit 17] +- AVX512_IFMA CPUID.(EAX=7,ECX=0):EBX[bit 21] +- AVX512CD CPUID.(EAX=7,ECX=0):EBX[bit 28] +- AVX512BW CPUID.(EAX=7,ECX=0):EBX[bit 30] +- AVX512VL CPUID.(EAX=7,ECX=0):EBX[bit 31] +- AVX512_VBMI CPUID.(EAX=7,ECX=0):ECX[bit 1] +- AVX512_VBMI2 CPUID.(EAX=7,ECX=0):ECX[bit 6] +- AVX512_VNNI CPUID.(EAX=7,ECX=0):ECX[bit 11] +- AVX512_BITALG CPUID.(EAX=7,ECX=0):ECX[bit 12] +- AVX512_VPOPCNTDQ CPUID.(EAX=7,ECX=0):ECX[bit 14] +- LA57 CPUID.(EAX=7,ECX=0):ECX[bit 16] +- TSXLDTRK CPUID.(EAX=7,ECX=0):EDX[bit 16] +- AMX-BF16 CPUID.(EAX=7,ECX=0):EDX[bit 22] +- AVX512_FP16 CPUID.(EAX=7,ECX=0):EDX[bit 23] +- AMX-TILE CPUID.(EAX=7,ECX=0):EDX[bit 24] +- AMX-INT8 CPUID.(EAX=7,ECX=0):EDX[bit 25] +- AVX512_BF16 CPUID.(EAX=7,ECX=1):EAX[bit 5] +- fast zero-length MOVSB CPUID.(EAX=7,ECX=1):EAX[bit 10] +- fast short CMPSB, SCASB CPUID.(EAX=7,ECX=1):EAX[bit 12] +- AMX-FP16 CPUID.(EAX=7,ECX=1):EAX[bit 21] +- PREFETCHI CPUID.(EAX=7,ECX=1):EDX[bit 14] +- XFD CPUID.(EAX=0xD,ECX=1):EAX[bit 4] +- EPT_PAGE_WALK_LENGTH_5 VMX_EPT_VPID_CAP(0x48c)[bit 7] + +Add all features of GraniteRapids CPU model except above features to +SierraForest CPU model. + +SierraForest doesn’t support TSX and RTM but supports TAA_NO. When RTM is +not enabled in host, KVM will not report TAA_NO. So, just don't include +TAA_NO in SierraForest CPU model. + +[1] https://cdrdv2.intel.com/v1/dl/getContent/671368 + +Intel-SIG: commit 6e82d3b62207 target/i386: Add new CPU model SierraForest. +Add SPR/GNR/SRA new ISAs backporting + +Reviewed-by: Zhao Liu +Reviewed-by: Xiaoyao Li +Signed-off-by: Tao Su +Message-ID: <20240320021044.508263-1-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 126 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 4a33baade..00157dae9 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -3715,6 +3715,132 @@ static const X86CPUDefinition builtin_x86_defs[] = { + { /* end of list */ }, + }, + }, ++ { ++ .name = "SierraForest", ++ .level = 0x23, ++ .vendor = CPUID_VENDOR_INTEL, ++ .family = 6, ++ .model = 175, ++ .stepping = 0, ++ /* ++ * please keep the ascending order so that we can have a clear view of ++ * bit position of each feature. ++ */ ++ .features[FEAT_1_EDX] = ++ CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | ++ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | ++ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | ++ CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR | ++ CPUID_SSE | CPUID_SSE2, ++ .features[FEAT_1_ECX] = ++ CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 | ++ CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | CPUID_EXT_SSE41 | ++ CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE | ++ CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES | ++ CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND, ++ .features[FEAT_8000_0001_EDX] = ++ CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB | ++ CPUID_EXT2_RDTSCP | CPUID_EXT2_LM, ++ .features[FEAT_8000_0001_ECX] = ++ CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH, ++ .features[FEAT_8000_0008_EBX] = ++ CPUID_8000_0008_EBX_WBNOINVD, ++ .features[FEAT_7_0_EBX] = ++ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 | ++ CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | ++ CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | ++ CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT | CPUID_7_0_EBX_CLWB | ++ CPUID_7_0_EBX_SHA_NI, ++ .features[FEAT_7_0_ECX] = ++ CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_GFNI | ++ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ | ++ CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT, ++ .features[FEAT_7_0_EDX] = ++ CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_SERIALIZE | ++ CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_ARCH_CAPABILITIES | ++ CPUID_7_0_EDX_SPEC_CTRL_SSBD, ++ .features[FEAT_ARCH_CAPABILITIES] = ++ MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL | ++ MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO | ++ MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_SBDR_SSDP_NO | ++ MSR_ARCH_CAP_FBSDP_NO | MSR_ARCH_CAP_PSDP_NO | ++ MSR_ARCH_CAP_PBRSB_NO, ++ .features[FEAT_XSAVE] = ++ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | ++ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES, ++ .features[FEAT_6_EAX] = ++ CPUID_6_EAX_ARAT, ++ .features[FEAT_7_1_EAX] = ++ CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_CMPCCXADD | ++ CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_AVX_IFMA, ++ .features[FEAT_7_1_EDX] = ++ CPUID_7_1_EDX_AVX_VNNI_INT8 | CPUID_7_1_EDX_AVX_NE_CONVERT, ++ .features[FEAT_7_2_EDX] = ++ CPUID_7_2_EDX_MCDT_NO, ++ .features[FEAT_VMX_BASIC] = ++ MSR_VMX_BASIC_INS_OUTS | MSR_VMX_BASIC_TRUE_CTLS, ++ .features[FEAT_VMX_ENTRY_CTLS] = ++ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_IA32E_MODE | ++ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_ENTRY_LOAD_IA32_PAT | VMX_VM_ENTRY_LOAD_IA32_EFER, ++ .features[FEAT_VMX_EPT_VPID_CAPS] = ++ MSR_VMX_EPT_EXECONLY | MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | ++ MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB | ++ MSR_VMX_EPT_INVEPT | MSR_VMX_EPT_AD_BITS | ++ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | ++ MSR_VMX_EPT_INVVPID_ALL_CONTEXT | ++ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, ++ .features[FEAT_VMX_EXIT_CTLS] = ++ VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | ++ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | ++ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_IA32_PAT | ++ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | ++ VMX_VM_EXIT_LOAD_IA32_EFER | VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, ++ .features[FEAT_VMX_MISC] = ++ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_ACTIVITY_HLT | ++ MSR_VMX_MISC_VMWRITE_VMEXIT, ++ .features[FEAT_VMX_PINBASED_CTLS] = ++ VMX_PIN_BASED_EXT_INTR_MASK | VMX_PIN_BASED_NMI_EXITING | ++ VMX_PIN_BASED_VIRTUAL_NMIS | VMX_PIN_BASED_VMX_PREEMPTION_TIMER | ++ VMX_PIN_BASED_POSTED_INTR, ++ .features[FEAT_VMX_PROCBASED_CTLS] = ++ VMX_CPU_BASED_VIRTUAL_INTR_PENDING | ++ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | ++ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | ++ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | ++ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | ++ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | ++ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_VIRTUAL_NMI_PENDING | ++ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING | ++ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_TRAP_FLAG | ++ VMX_CPU_BASED_USE_MSR_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING | ++ VMX_CPU_BASED_PAUSE_EXITING | ++ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, ++ .features[FEAT_VMX_SECONDARY_CTLS] = ++ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ VMX_SECONDARY_EXEC_ENABLE_EPT | VMX_SECONDARY_EXEC_DESC | ++ VMX_SECONDARY_EXEC_RDTSCP | ++ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | ++ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_WBINVD_EXITING | ++ VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | ++ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | ++ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | ++ VMX_SECONDARY_EXEC_RDRAND_EXITING | ++ VMX_SECONDARY_EXEC_ENABLE_INVPCID | ++ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | ++ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML | ++ VMX_SECONDARY_EXEC_XSAVES, ++ .features[FEAT_VMX_VMFUNC] = ++ MSR_VMX_VMFUNC_EPT_SWITCHING, ++ .xlevel = 0x80000008, ++ .model_id = "Intel Xeon Processor (SierraForest)", ++ .versions = (X86CPUVersionDefinition[]) { ++ { .version = 1 }, ++ { /* end of list */ }, ++ }, ++ }, + { + .name = "Denverton", + .level = 21, +-- +2.25.1 diff --git a/1092-target-i386-Export-RFDS-bit-to-guests.patch b/1092-target-i386-Export-RFDS-bit-to-guests.patch new file mode 100644 index 0000000..87d9465 --- /dev/null +++ b/1092-target-i386-Export-RFDS-bit-to-guests.patch @@ -0,0 +1,45 @@ +From: Pawan Gupta +Date: Wed, 13 Mar 2024 07:53:23 -0700 +Subject: [PATCH] target/i386: Export RFDS bit to guests + +commit 41bdd9812863c150284a9339a048ed88c40f4df7 upstream. + +Register File Data Sampling (RFDS) is a CPU side-channel vulnerability +that may expose stale register value. CPUs that set RFDS_NO bit in MSR +IA32_ARCH_CAPABILITIES indicate that they are not vulnerable to RFDS. +Similarly, RFDS_CLEAR indicates that CPU is affected by RFDS, and has +the microcode to help mitigate RFDS. + +Make RFDS_CLEAR and RFDS_NO bits available to guests. + +Intel-SIG: commit 41bdd9812863 target/i386: Export RFDS bit to guests. +Add SPR/GNR/SRA new ISAs backporting + +Signed-off-by: Pawan Gupta +Reviewed-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Message-ID: <9a38877857392b5c2deae7e7db1b170d15510314.1710341348.git.pawan.kumar.gupta@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 00157dae9..80c3b58d1 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1025,8 +1025,8 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + NULL, NULL, NULL, NULL, + NULL, "fb-clear", NULL, NULL, + NULL, NULL, NULL, NULL, +- NULL, NULL, NULL, NULL, +- NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, "rfds-no", ++ "rfds-clear", NULL, NULL, NULL, + }, + .msr = { + .index = MSR_IA32_ARCH_CAPABILITIES, +-- +2.25.1 diff --git a/qemu-kvm.spec b/qemu-kvm.spec index a2ed1ec..50c7118 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -982,6 +982,22 @@ Patch1073: 1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch Patch1074: 1074-newfeature-support-vpsp.patch Patch1075: 1075-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch Patch1076: 1076-target-i386-Add-new-Hygon-Dharma-CPU-model.patch +Patch1077: 1077-target-i386-add-FSRM-to-TCG.patch +Patch1078: 1078-target-i386-add-FZRM-FSRS-FSRC.patch +Patch1079: 1079-i386-Add-new-CPU-model-SapphireRapids.patch +Patch1080: 1080-target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch +Patch1081: 1081-target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch +Patch1082: 1082-target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch +Patch1083: 1083-target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch +Patch1084: 1084-target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch +Patch1085: 1085-target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch +Patch1086: 1086-target-i386-Adjust-feature-level-according-to-FEAT_7.patch +Patch1087: 1087-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch +Patch1088: 1088-target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch +Patch1089: 1089-target-i386-Add-new-CPU-model-GraniteRapids.patch +Patch1090: 1090-target-i386-Add-support-for-AMX-COMPLEX-in-CPUID-enu.patch +Patch1091: 1091-target-i386-Add-new-CPU-model-SierraForest.patch +Patch1092: 1092-target-i386-Export-RFDS-bit-to-guests.patch BuildRequires: wget BuildRequires: rpm-build @@ -2257,6 +2273,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : - Support reuse ASID for CSV guests (hanliyang@hygon.cn) - Support tkm key isolation (xiongmengbiao@hygon.cn) - Add Hygon Dhyana-v3 and Dharma CPU model (zhouyanjing@hygon.cn) +- Intel-SIG: Supprt Intel SPR/GNR/SRF new ISAs and cpu models (quanxian.wang@intel.com) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] -- Gitee From 1251db35a4bb41f0b5d51a66831b58dfbdf2f098 Mon Sep 17 00:00:00 2001 From: Xianglai Li Date: Thu, 29 Aug 2024 19:00:58 +0800 Subject: [PATCH 16/17] fix compile error for loongarch Signed-off-by: Xianglai Li --- 0001-Add-Acpi-support.patch | 16 ++-- 0002-Support-rtc.patch | 12 +-- 0003-Add-loongarch-machine.patch | 38 ++++---- 0004-Add-target-loongarch64.patch | 77 ++++++++------- 0005-Add-linux-headers-and-linux-user.patch | 38 ++++---- 0006-Add-disas-gdb.patch | 22 ++--- 0007-Modify-kvm-cpu-vga-qapi.patch | 93 +++++++++---------- 0008-Modify-compile-script.patch | 8 +- 0009-Add-loongarch64-rh-devices.mak.patch | 24 ++--- Add-lbt-support-for-kvm.patch | 6 +- ...to-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch | 8 +- Add-usb-storage-config-for-loongarch.patch | 6 +- Fix-LoongArch-KVM-header-macros.patch | 10 +- ...cture-macro-of-LoongArch-to-HOST_LOO.patch | 11 ++- ...and-fpu-option-to-compat-with-kernel.patch | 6 +- Fix-smp.cores-value.patch | 6 +- ...-where-qemu-specifies-the-boot-order.patch | 6 +- ...tion-lack-and-Modify-the-maximum-num.patch | 12 +-- Modify-the-ioctl-command-of-kvm.patch | 10 +- Support-TPM.patch | 6 +- Support-vfio-config.patch | 6 +- ...pace-code-cleanup-on-7A-virt-machine.patch | 6 +- code-cleanup-for-loongarch-kvm.patch | 6 +- fix-smbios-type4-info-for-numa-support.patch | 6 +- fixup-can-t-find-cpu-type.patch | 6 +- kvm-csr-save-and-restore-optimization.patch | 6 +- pass-to-make-check.patch | 6 +- rename-kvm_msr_buf-with-kvm_csr_buf.patch | 6 +- 28 files changed, 230 insertions(+), 233 deletions(-) diff --git a/0001-Add-Acpi-support.patch b/0001-Add-Acpi-support.patch index 5b1561c..101c3a4 100644 --- a/0001-Add-Acpi-support.patch +++ b/0001-Add-Acpi-support.patch @@ -1,7 +1,7 @@ -From 612826687e639d007e4270b01a61f34f7fc1f813 Mon Sep 17 00:00:00 2001 +From 935f85c0025bbaaed976940ed0d57c23bfc68f94 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Fri, 19 Aug 2022 23:11:23 -0400 -Subject: [PATCH 1/8] Add Acpi support. +Subject: [PATCH 01/28] Add Acpi support. Change-Id: I208228b2178cddf365e97c6faf6111ef40e795eb Signed-off-by: lixianglai @@ -17,7 +17,7 @@ Signed-off-by: lixianglai create mode 100644 include/hw/acpi/ls7a.h diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig -index 622b0b50b7..2f2fb33a7b 100644 +index 622b0b50b..2f2fb33a7 100644 --- a/hw/acpi/Kconfig +++ b/hw/acpi/Kconfig @@ -15,6 +15,14 @@ config ACPI_X86_ICH @@ -37,7 +37,7 @@ index 622b0b50b7..2f2fb33a7b 100644 diff --git a/hw/acpi/larch_7a.c b/hw/acpi/larch_7a.c new file mode 100644 -index 0000000000..35d4a75266 +index 000000000..35d4a7526 --- /dev/null +++ b/hw/acpi/larch_7a.c @@ -0,0 +1,600 @@ @@ -643,7 +643,7 @@ index 0000000000..35d4a75266 + diff --git a/hw/acpi/ls7a.c b/hw/acpi/ls7a.c new file mode 100644 -index 0000000000..2de50ccb9c +index 000000000..2de50ccb9 --- /dev/null +++ b/hw/acpi/ls7a.c @@ -0,0 +1,598 @@ @@ -1246,7 +1246,7 @@ index 0000000000..2de50ccb9c + + diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build -index adf6347bc4..5fe4cfa4f1 100644 +index adf6347bc..5fe4cfa4f 100644 --- a/hw/acpi/meson.build +++ b/hw/acpi/meson.build @@ -6,6 +6,7 @@ acpi_ss.add(files( @@ -1259,7 +1259,7 @@ index adf6347bc4..5fe4cfa4f1 100644 acpi_ss.add(when: 'CONFIG_ACPI_MEMORY_HOTPLUG', if_true: files('memory_hotplug.c')) diff --git a/include/hw/acpi/ls7a.h b/include/hw/acpi/ls7a.h new file mode 100644 -index 0000000000..4401515c7b +index 000000000..4401515c7 --- /dev/null +++ b/include/hw/acpi/ls7a.h @@ -0,0 +1,80 @@ @@ -1344,5 +1344,5 @@ index 0000000000..4401515c7b +void ls7a_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev); +#endif /* HW_ACPI_LS7A_H */ -- -2.27.0 +2.43.5 diff --git a/0002-Support-rtc.patch b/0002-Support-rtc.patch index 082fcdf..989778e 100644 --- a/0002-Support-rtc.patch +++ b/0002-Support-rtc.patch @@ -1,7 +1,7 @@ -From befa5ef7576fdbe2e729203538b066e5f87c3b8f Mon Sep 17 00:00:00 2001 +From e0a8c8cb06e866bd334501d637e7219a14ae601b Mon Sep 17 00:00:00 2001 From: lixianglai Date: Fri, 19 Aug 2022 23:15:49 -0400 -Subject: [PATCH 2/8] Support rtc. +Subject: [PATCH 02/28] Support rtc. Change-Id: Idd50274dd2a6c00b21ec0cd099f8d115ab4fa449 Signed-off-by: lixianglai @@ -13,7 +13,7 @@ Signed-off-by: lixianglai create mode 100644 hw/timer/ls7a_rtc.c diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig -index 010be7ed1f..b395c72d7d 100644 +index 010be7ed1..b395c72d7 100644 --- a/hw/timer/Kconfig +++ b/hw/timer/Kconfig @@ -60,3 +60,5 @@ config STELLARIS_GPTM @@ -24,7 +24,7 @@ index 010be7ed1f..b395c72d7d 100644 + bool diff --git a/hw/timer/ls7a_rtc.c b/hw/timer/ls7a_rtc.c new file mode 100644 -index 0000000000..756f2fc9ce +index 000000000..756f2fc9c --- /dev/null +++ b/hw/timer/ls7a_rtc.c @@ -0,0 +1,325 @@ @@ -354,7 +354,7 @@ index 0000000000..756f2fc9ce + +type_init(ls7a_rtc_register_types) diff --git a/hw/timer/meson.build b/hw/timer/meson.build -index 03092e2ceb..e841a2f6ee 100644 +index 03092e2ce..e841a2f6e 100644 --- a/hw/timer/meson.build +++ b/hw/timer/meson.build @@ -16,6 +16,7 @@ softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_mct.c')) @@ -366,5 +366,5 @@ index 03092e2ceb..e841a2f6ee 100644 softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_epit.c')) softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_gpt.c')) -- -2.27.0 +2.43.5 diff --git a/0003-Add-loongarch-machine.patch b/0003-Add-loongarch-machine.patch index c1617ba..9052ba7 100644 --- a/0003-Add-loongarch-machine.patch +++ b/0003-Add-loongarch-machine.patch @@ -1,7 +1,7 @@ -From 2562504ad867de4a0539c261983c08cd5108bfe4 Mon Sep 17 00:00:00 2001 +From 3cb18285115f8dd7f9135c65b39c93cb7eb3580c Mon Sep 17 00:00:00 2001 From: lixianglai Date: Fri, 19 Aug 2022 23:39:00 -0400 -Subject: [PATCH 3/8] Add loongarch machine. +Subject: [PATCH 03/28] Add loongarch machine. Change-Id: I7e31f874c676b740269945d5e19c6bc836de6a99 Signed-off-by: lixianglai @@ -42,7 +42,7 @@ Signed-off-by: lixianglai diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig new file mode 100644 -index 0000000000..3fe2677fda +index 000000000..3fe2677fd --- /dev/null +++ b/hw/loongarch/Kconfig @@ -0,0 +1,17 @@ @@ -65,7 +65,7 @@ index 0000000000..3fe2677fda + bool diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c new file mode 100644 -index 0000000000..6ba637be53 +index 000000000..6ba637be5 --- /dev/null +++ b/hw/loongarch/acpi-build.c @@ -0,0 +1,783 @@ @@ -854,7 +854,7 @@ index 0000000000..6ba637be53 +} diff --git a/hw/loongarch/acpi-build.h b/hw/loongarch/acpi-build.h new file mode 100644 -index 0000000000..a914268bbe +index 000000000..a914268bb --- /dev/null +++ b/hw/loongarch/acpi-build.h @@ -0,0 +1,16 @@ @@ -876,7 +876,7 @@ index 0000000000..a914268bbe +#endif diff --git a/hw/loongarch/apic.c b/hw/loongarch/apic.c new file mode 100644 -index 0000000000..d6ba2a2cec +index 000000000..d6ba2a2ce --- /dev/null +++ b/hw/loongarch/apic.c @@ -0,0 +1,675 @@ @@ -1557,7 +1557,7 @@ index 0000000000..d6ba2a2cec + diff --git a/hw/loongarch/ioapic.c b/hw/loongarch/ioapic.c new file mode 100644 -index 0000000000..3de0ed88da +index 000000000..3de0ed88d --- /dev/null +++ b/hw/loongarch/ioapic.c @@ -0,0 +1,422 @@ @@ -1985,7 +1985,7 @@ index 0000000000..3de0ed88da +type_init(ls7a_apic_register_types) diff --git a/hw/loongarch/iocsr.c b/hw/loongarch/iocsr.c new file mode 100644 -index 0000000000..14521c2d5c +index 000000000..14521c2d5 --- /dev/null +++ b/hw/loongarch/iocsr.c @@ -0,0 +1,219 @@ @@ -2210,7 +2210,7 @@ index 0000000000..14521c2d5c +type_init(iocsr_register_types) diff --git a/hw/loongarch/ipi.c b/hw/loongarch/ipi.c new file mode 100644 -index 0000000000..ade182abcc +index 000000000..ade182abc --- /dev/null +++ b/hw/loongarch/ipi.c @@ -0,0 +1,267 @@ @@ -2483,7 +2483,7 @@ index 0000000000..ade182abcc +} diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c new file mode 100644 -index 0000000000..3db269274f +index 000000000..3db269274 --- /dev/null +++ b/hw/loongarch/larch_3a.c @@ -0,0 +1,2026 @@ @@ -4515,7 +4515,7 @@ index 0000000000..3db269274f + ls3a5k_ls7a_machine_options); diff --git a/hw/loongarch/larch_hotplug.c b/hw/loongarch/larch_hotplug.c new file mode 100644 -index 0000000000..7bce957124 +index 000000000..7bce95712 --- /dev/null +++ b/hw/loongarch/larch_hotplug.c @@ -0,0 +1,355 @@ @@ -4876,7 +4876,7 @@ index 0000000000..7bce957124 + diff --git a/hw/loongarch/larch_int.c b/hw/loongarch/larch_int.c new file mode 100644 -index 0000000000..ca073a19cf +index 000000000..ca073a19c --- /dev/null +++ b/hw/loongarch/larch_int.c @@ -0,0 +1,91 @@ @@ -4973,7 +4973,7 @@ index 0000000000..ca073a19cf + diff --git a/hw/loongarch/ls7a_nb.c b/hw/loongarch/ls7a_nb.c new file mode 100644 -index 0000000000..5a500fbd5a +index 000000000..5a500fbd5 --- /dev/null +++ b/hw/loongarch/ls7a_nb.c @@ -0,0 +1,352 @@ @@ -5331,7 +5331,7 @@ index 0000000000..5a500fbd5a +type_init(ls7a_register_types) diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build new file mode 100644 -index 0000000000..81ee99a028 +index 000000000..81ee99a02 --- /dev/null +++ b/hw/loongarch/meson.build @@ -0,0 +1,15 @@ @@ -5352,7 +5352,7 @@ index 0000000000..81ee99a028 + diff --git a/include/hw/loongarch/bios.h b/include/hw/loongarch/bios.h new file mode 100644 -index 0000000000..3677303bfa +index 000000000..3677303bf --- /dev/null +++ b/include/hw/loongarch/bios.h @@ -0,0 +1,5 @@ @@ -5363,7 +5363,7 @@ index 0000000000..3677303bfa +#define BIOS_FILENAME "loongarch_bios.bin" diff --git a/include/hw/loongarch/cpudevs.h b/include/hw/loongarch/cpudevs.h new file mode 100644 -index 0000000000..c05ae7a7fc +index 000000000..c05ae7a7f --- /dev/null +++ b/include/hw/loongarch/cpudevs.h @@ -0,0 +1,53 @@ @@ -5422,7 +5422,7 @@ index 0000000000..c05ae7a7fc +#endif diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h new file mode 100644 -index 0000000000..0886ed52af +index 000000000..0886ed52a --- /dev/null +++ b/include/hw/loongarch/larch.h @@ -0,0 +1,163 @@ @@ -5591,7 +5591,7 @@ index 0000000000..0886ed52af +#endif diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h new file mode 100644 -index 0000000000..686af763a0 +index 000000000..686af763a --- /dev/null +++ b/include/hw/loongarch/ls7a.h @@ -0,0 +1,152 @@ @@ -5748,5 +5748,5 @@ index 0000000000..686af763a0 + +#endif /* HW_LS7A_H */ -- -2.27.0 +2.43.5 diff --git a/0004-Add-target-loongarch64.patch b/0004-Add-target-loongarch64.patch index 38e74c2..bca350b 100644 --- a/0004-Add-target-loongarch64.patch +++ b/0004-Add-target-loongarch64.patch @@ -1,14 +1,14 @@ -From 441bbe9ec5021bf56a929134a71cd85815ec3956 Mon Sep 17 00:00:00 2001 +From 73e64c37b5d0f8a12bad7562c4d442f95ee361b8 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Fri, 19 Aug 2022 23:44:33 -0400 -Subject: [PATCH 4/8] Add target/loongarch64. +Subject: [PATCH 04/28] Add target/loongarch64. Change-Id: Idd3ed114968c4a1f1be5fe19dc279028775eb89d Signed-off-by: lixianglai --- target/Kconfig | 1 + target/loongarch64/Kconfig | 2 + - target/loongarch64/arch_dump.c | 175 ++ + target/loongarch64/arch_dump.c | 174 ++ target/loongarch64/cpu-csr.h | 869 ++++++++ target/loongarch64/cpu-param.h | 30 + target/loongarch64/cpu-qom.h | 54 + @@ -36,7 +36,7 @@ Signed-off-by: lixianglai target/loongarch64/trans.inc.c | 3472 ++++++++++++++++++++++++++++++ target/loongarch64/translate.c | 2892 +++++++++++++++++++++++++ target/meson.build | 1 + - 30 files changed, 15657 insertions(+) + 30 files changed, 15656 insertions(+) create mode 100644 target/loongarch64/Kconfig create mode 100644 target/loongarch64/arch_dump.c create mode 100644 target/loongarch64/cpu-csr.h @@ -67,7 +67,7 @@ Signed-off-by: lixianglai create mode 100644 target/loongarch64/translate.c diff --git a/target/Kconfig b/target/Kconfig -index ae7f24fc66..50b46d0487 100644 +index ae7f24fc6..50b46d048 100644 --- a/target/Kconfig +++ b/target/Kconfig @@ -4,6 +4,7 @@ source avr/Kconfig @@ -80,7 +80,7 @@ index ae7f24fc66..50b46d0487 100644 source mips/Kconfig diff --git a/target/loongarch64/Kconfig b/target/loongarch64/Kconfig new file mode 100644 -index 0000000000..46b26b1a85 +index 000000000..46b26b1a8 --- /dev/null +++ b/target/loongarch64/Kconfig @@ -0,0 +1,2 @@ @@ -88,10 +88,10 @@ index 0000000000..46b26b1a85 + bool diff --git a/target/loongarch64/arch_dump.c b/target/loongarch64/arch_dump.c new file mode 100644 -index 0000000000..9fb43b33d2 +index 000000000..7b8708fdf --- /dev/null +++ b/target/loongarch64/arch_dump.c -@@ -0,0 +1,175 @@ +@@ -0,0 +1,174 @@ +/* Support for writing ELF notes for RM architectures + * + * Copyright (C) 2015 Red Hat Inc. @@ -213,11 +213,10 @@ index 0000000000..9fb43b33d2 +} + +int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, -+ int cpuid, void *opaque) ++ int cpuid, DumpState *s) +{ + struct loongarch_note note; + CPULOONGARCHState *env = &LOONGARCH_CPU(cs)->env; -+ DumpState *s = opaque; + int ret, i; + + loongarch_note_init(¬e, s, "CORE", 5, NT_PRSTATUS, sizeof(note.prstatus)); @@ -269,7 +268,7 @@ index 0000000000..9fb43b33d2 + diff --git a/target/loongarch64/cpu-csr.h b/target/loongarch64/cpu-csr.h new file mode 100644 -index 0000000000..e549bb46b6 +index 000000000..e549bb46b --- /dev/null +++ b/target/loongarch64/cpu-csr.h @@ -0,0 +1,869 @@ @@ -1144,7 +1143,7 @@ index 0000000000..e549bb46b6 +#endif diff --git a/target/loongarch64/cpu-param.h b/target/loongarch64/cpu-param.h new file mode 100644 -index 0000000000..24ca458af0 +index 000000000..24ca458af --- /dev/null +++ b/target/loongarch64/cpu-param.h @@ -0,0 +1,30 @@ @@ -1180,7 +1179,7 @@ index 0000000000..24ca458af0 + diff --git a/target/loongarch64/cpu-qom.h b/target/loongarch64/cpu-qom.h new file mode 100644 -index 0000000000..ee9c1de571 +index 000000000..ee9c1de57 --- /dev/null +++ b/target/loongarch64/cpu-qom.h @@ -0,0 +1,54 @@ @@ -1240,7 +1239,7 @@ index 0000000000..ee9c1de571 +#endif diff --git a/target/loongarch64/cpu.c b/target/loongarch64/cpu.c new file mode 100644 -index 0000000000..a4535d34a6 +index 000000000..a4535d34a --- /dev/null +++ b/target/loongarch64/cpu.c @@ -0,0 +1,576 @@ @@ -1822,7 +1821,7 @@ index 0000000000..a4535d34a6 +type_init(loongarch_cpu_register_types) diff --git a/target/loongarch64/cpu.h b/target/loongarch64/cpu.h new file mode 100644 -index 0000000000..10facb3b73 +index 000000000..10facb3b7 --- /dev/null +++ b/target/loongarch64/cpu.h @@ -0,0 +1,326 @@ @@ -2154,7 +2153,7 @@ index 0000000000..10facb3b73 +#endif /* LOONGARCH_CPU_H */ diff --git a/target/loongarch64/csr_helper.c b/target/loongarch64/csr_helper.c new file mode 100644 -index 0000000000..182e59e925 +index 000000000..182e59e92 --- /dev/null +++ b/target/loongarch64/csr_helper.c @@ -0,0 +1,704 @@ @@ -2864,7 +2863,7 @@ index 0000000000..182e59e925 + diff --git a/target/loongarch64/fpu.c b/target/loongarch64/fpu.c new file mode 100644 -index 0000000000..795458205b +index 000000000..795458205 --- /dev/null +++ b/target/loongarch64/fpu.c @@ -0,0 +1,28 @@ @@ -2898,7 +2897,7 @@ index 0000000000..795458205b +}; diff --git a/target/loongarch64/fpu_helper.c b/target/loongarch64/fpu_helper.c new file mode 100644 -index 0000000000..42d7f05ca2 +index 000000000..42d7f05ca --- /dev/null +++ b/target/loongarch64/fpu_helper.c @@ -0,0 +1,952 @@ @@ -3856,7 +3855,7 @@ index 0000000000..42d7f05ca2 +} diff --git a/target/loongarch64/fpu_helper.h b/target/loongarch64/fpu_helper.h new file mode 100644 -index 0000000000..b6898c2e91 +index 000000000..b6898c2e9 --- /dev/null +++ b/target/loongarch64/fpu_helper.h @@ -0,0 +1,129 @@ @@ -3991,7 +3990,7 @@ index 0000000000..b6898c2e91 +#endif diff --git a/target/loongarch64/gdbstub.c b/target/loongarch64/gdbstub.c new file mode 100644 -index 0000000000..4013178f45 +index 000000000..4013178f4 --- /dev/null +++ b/target/loongarch64/gdbstub.c @@ -0,0 +1,109 @@ @@ -4106,7 +4105,7 @@ index 0000000000..4013178f45 +#endif diff --git a/target/loongarch64/helper.c b/target/loongarch64/helper.c new file mode 100644 -index 0000000000..841240e57b +index 000000000..841240e57 --- /dev/null +++ b/target/loongarch64/helper.c @@ -0,0 +1,727 @@ @@ -4839,7 +4838,7 @@ index 0000000000..841240e57b +} diff --git a/target/loongarch64/helper.h b/target/loongarch64/helper.h new file mode 100644 -index 0000000000..ff2026ed82 +index 000000000..ff2026ed8 --- /dev/null +++ b/target/loongarch64/helper.h @@ -0,0 +1,168 @@ @@ -5013,7 +5012,7 @@ index 0000000000..ff2026ed82 +DEF_HELPER_2(memtrace_val, void, env, tl) diff --git a/target/loongarch64/insn.decode b/target/loongarch64/insn.decode new file mode 100644 -index 0000000000..f194f70116 +index 000000000..f194f7011 --- /dev/null +++ b/target/loongarch64/insn.decode @@ -0,0 +1,514 @@ @@ -5533,7 +5532,7 @@ index 0000000000..f194f70116 +bgeu 0110 11 ................ ..... ..... @fmt_rjrdoffs16 diff --git a/target/loongarch64/instmap.h b/target/loongarch64/instmap.h new file mode 100644 -index 0000000000..6e85847f8a +index 000000000..6e85847f8 --- /dev/null +++ b/target/loongarch64/instmap.h @@ -0,0 +1,216 @@ @@ -5755,7 +5754,7 @@ index 0000000000..6e85847f8a +#endif diff --git a/target/loongarch64/internal.h b/target/loongarch64/internal.h new file mode 100644 -index 0000000000..79a70e9d26 +index 000000000..43594c5ac --- /dev/null +++ b/target/loongarch64/internal.h @@ -0,0 +1,184 @@ @@ -5922,7 +5921,7 @@ index 0000000000..79a70e9d26 +uint64_t cpu_loongarch_get_stable_timer_ticks(CPULOONGARCHState *env); +void cpu_loongarch_store_stable_timer_config(CPULOONGARCHState *env, uint64_t value); +int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, -+ int cpuid, void *opaque); ++ int cpuid, DumpState *s); + +void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags); + @@ -5945,7 +5944,7 @@ index 0000000000..79a70e9d26 +#endif diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c new file mode 100644 -index 0000000000..404a605eb6 +index 000000000..404a605eb --- /dev/null +++ b/target/loongarch64/kvm.c @@ -0,0 +1,1622 @@ @@ -7573,7 +7572,7 @@ index 0000000000..404a605eb6 +} diff --git a/target/loongarch64/kvm_larch.h b/target/loongarch64/kvm_larch.h new file mode 100644 -index 0000000000..a56026d10c +index 000000000..a56026d10 --- /dev/null +++ b/target/loongarch64/kvm_larch.h @@ -0,0 +1,41 @@ @@ -7620,7 +7619,7 @@ index 0000000000..a56026d10c +#endif /* KVM_LOONGARCH_H */ diff --git a/target/loongarch64/larch-defs.h b/target/loongarch64/larch-defs.h new file mode 100644 -index 0000000000..d3a61cf255 +index 000000000..d3a61cf25 --- /dev/null +++ b/target/loongarch64/larch-defs.h @@ -0,0 +1,27 @@ @@ -7653,7 +7652,7 @@ index 0000000000..d3a61cf255 +#endif /* QEMU_LOONGARCH_DEFS_H */ diff --git a/target/loongarch64/machine.c b/target/loongarch64/machine.c new file mode 100644 -index 0000000000..b69bca6a9b +index 000000000..b69bca6a9 --- /dev/null +++ b/target/loongarch64/machine.c @@ -0,0 +1,416 @@ @@ -8075,7 +8074,7 @@ index 0000000000..b69bca6a9b +}; diff --git a/target/loongarch64/meson.build b/target/loongarch64/meson.build new file mode 100644 -index 0000000000..6badf4484e +index 000000000..6badf4484 --- /dev/null +++ b/target/loongarch64/meson.build @@ -0,0 +1,35 @@ @@ -8116,7 +8115,7 @@ index 0000000000..6badf4484e +target_user_arch += {'loongarch64': loongarch_user_ss} diff --git a/target/loongarch64/op_helper.c b/target/loongarch64/op_helper.c new file mode 100644 -index 0000000000..9a34c0d25e +index 000000000..9a34c0d25 --- /dev/null +++ b/target/loongarch64/op_helper.c @@ -0,0 +1,533 @@ @@ -8655,7 +8654,7 @@ index 0000000000..9a34c0d25e +} diff --git a/target/loongarch64/stabletimer.c b/target/loongarch64/stabletimer.c new file mode 100644 -index 0000000000..b86fecf899 +index 000000000..b86fecf89 --- /dev/null +++ b/target/loongarch64/stabletimer.c @@ -0,0 +1,122 @@ @@ -8783,7 +8782,7 @@ index 0000000000..b86fecf899 +} diff --git a/target/loongarch64/tlb_helper.c b/target/loongarch64/tlb_helper.c new file mode 100644 -index 0000000000..f5e68349a9 +index 000000000..f5e68349a --- /dev/null +++ b/target/loongarch64/tlb_helper.c @@ -0,0 +1,729 @@ @@ -9518,7 +9517,7 @@ index 0000000000..f5e68349a9 +#endif /* !CONFIG_USER_ONLY */ diff --git a/target/loongarch64/trace-events b/target/loongarch64/trace-events new file mode 100644 -index 0000000000..e0bca4f82e +index 000000000..e0bca4f82 --- /dev/null +++ b/target/loongarch64/trace-events @@ -0,0 +1,3 @@ @@ -9527,7 +9526,7 @@ index 0000000000..e0bca4f82e +# target/loongarch/translate.c diff --git a/target/loongarch64/trans.inc.c b/target/loongarch64/trans.inc.c new file mode 100644 -index 0000000000..e50670be47 +index 000000000..e50670be4 --- /dev/null +++ b/target/loongarch64/trans.inc.c @@ -0,0 +1,3472 @@ @@ -13005,7 +13004,7 @@ index 0000000000..e50670be47 +} diff --git a/target/loongarch64/translate.c b/target/loongarch64/translate.c new file mode 100644 -index 0000000000..fe122e4c31 +index 000000000..fe122e4c3 --- /dev/null +++ b/target/loongarch64/translate.c @@ -0,0 +1,2892 @@ @@ -15902,7 +15901,7 @@ index 0000000000..fe122e4c31 + } +} diff --git a/target/meson.build b/target/meson.build -index 2f6940255e..ac0ce618b7 100644 +index 2f6940255..ac0ce618b 100644 --- a/target/meson.build +++ b/target/meson.build @@ -5,6 +5,7 @@ subdir('cris') @@ -15914,5 +15913,5 @@ index 2f6940255e..ac0ce618b7 100644 subdir('microblaze') subdir('mips') -- -2.27.0 +2.43.5 diff --git a/0005-Add-linux-headers-and-linux-user.patch b/0005-Add-linux-headers-and-linux-user.patch index 93ba8ed..8e5b37e 100644 --- a/0005-Add-linux-headers-and-linux-user.patch +++ b/0005-Add-linux-headers-and-linux-user.patch @@ -1,7 +1,7 @@ -From 0d21e423fc15e8e2e2fdc910a7e94e051427f230 Mon Sep 17 00:00:00 2001 +From be4aee607329aee902b9a03936523c7d57d47100 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Fri, 19 Aug 2022 23:47:06 -0400 -Subject: [PATCH 5/8] Add linux-headers and linux-user. +Subject: [PATCH 05/28] Add linux-headers and linux-user. Change-Id: If052442a981fed87c03ca431c010629dc8e872ca Signed-off-by: lixianglai @@ -42,7 +42,7 @@ Signed-off-by: lixianglai diff --git a/linux-headers/asm-loongarch64/bitsperlong.h b/linux-headers/asm-loongarch64/bitsperlong.h new file mode 100644 -index 0000000000..5c2c8779a6 +index 000000000..5c2c8779a --- /dev/null +++ b/linux-headers/asm-loongarch64/bitsperlong.h @@ -0,0 +1,9 @@ @@ -57,7 +57,7 @@ index 0000000000..5c2c8779a6 +#endif /* __ASM_LOONGARCH_BITSPERLONG_H */ diff --git a/linux-headers/asm-loongarch64/kvm.h b/linux-headers/asm-loongarch64/kvm.h new file mode 100644 -index 0000000000..a24375ee59 +index 000000000..a24375ee5 --- /dev/null +++ b/linux-headers/asm-loongarch64/kvm.h @@ -0,0 +1,346 @@ @@ -409,7 +409,7 @@ index 0000000000..a24375ee59 +#endif /* __LINUX_KVM_LOONGARCH_H */ diff --git a/linux-headers/asm-loongarch64/sgidefs.h b/linux-headers/asm-loongarch64/sgidefs.h new file mode 100644 -index 0000000000..b809608349 +index 000000000..b80960834 --- /dev/null +++ b/linux-headers/asm-loongarch64/sgidefs.h @@ -0,0 +1,20 @@ @@ -435,7 +435,7 @@ index 0000000000..b809608349 +#endif /* __ASM_SGIDEFS_H */ diff --git a/linux-headers/asm-loongarch64/unistd.h b/linux-headers/asm-loongarch64/unistd.h new file mode 100644 -index 0000000000..2a6014562a +index 000000000..2a6014562 --- /dev/null +++ b/linux-headers/asm-loongarch64/unistd.h @@ -0,0 +1,23 @@ @@ -464,7 +464,7 @@ index 0000000000..2a6014562a +#include diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c new file mode 100644 -index 0000000000..6d4093e1d7 +index 000000000..6d4093e1d --- /dev/null +++ b/linux-user/loongarch64/cpu_loop.c @@ -0,0 +1,193 @@ @@ -663,7 +663,7 @@ index 0000000000..6d4093e1d7 +} diff --git a/linux-user/loongarch64/meson.build b/linux-user/loongarch64/meson.build new file mode 100644 -index 0000000000..c4c0b4d701 +index 000000000..c4c0b4d70 --- /dev/null +++ b/linux-user/loongarch64/meson.build @@ -0,0 +1,6 @@ @@ -675,7 +675,7 @@ index 0000000000..c4c0b4d701 +} diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c new file mode 100644 -index 0000000000..6fe6852758 +index 000000000..6fe685275 --- /dev/null +++ b/linux-user/loongarch64/signal.c @@ -0,0 +1,212 @@ @@ -893,14 +893,14 @@ index 0000000000..6fe6852758 +} diff --git a/linux-user/loongarch64/sockbits.h b/linux-user/loongarch64/sockbits.h new file mode 100644 -index 0000000000..0e4c8f012d +index 000000000..0e4c8f012 --- /dev/null +++ b/linux-user/loongarch64/sockbits.h @@ -0,0 +1 @@ +#include "../generic/sockbits.h" diff --git a/linux-user/loongarch64/syscall_nr.h b/linux-user/loongarch64/syscall_nr.h new file mode 100644 -index 0000000000..a30aca8d8e +index 000000000..a30aca8d8 --- /dev/null +++ b/linux-user/loongarch64/syscall_nr.h @@ -0,0 +1,287 @@ @@ -1193,7 +1193,7 @@ index 0000000000..a30aca8d8e +#endif diff --git a/linux-user/loongarch64/target_cpu.h b/linux-user/loongarch64/target_cpu.h new file mode 100644 -index 0000000000..0f6845737f +index 000000000..0f6845737 --- /dev/null +++ b/linux-user/loongarch64/target_cpu.h @@ -0,0 +1,45 @@ @@ -1244,7 +1244,7 @@ index 0000000000..0f6845737f +#endif diff --git a/linux-user/loongarch64/target_elf.h b/linux-user/loongarch64/target_elf.h new file mode 100644 -index 0000000000..6c153d12c4 +index 000000000..6c153d12c --- /dev/null +++ b/linux-user/loongarch64/target_elf.h @@ -0,0 +1,14 @@ @@ -1264,7 +1264,7 @@ index 0000000000..6c153d12c4 +#endif diff --git a/linux-user/loongarch64/target_fcntl.h b/linux-user/loongarch64/target_fcntl.h new file mode 100644 -index 0000000000..a3d7b46062 +index 000000000..a3d7b4606 --- /dev/null +++ b/linux-user/loongarch64/target_fcntl.h @@ -0,0 +1,13 @@ @@ -1283,7 +1283,7 @@ index 0000000000..a3d7b46062 +#endif /* LOONGARCH_TARGET_FCNTL_H */ diff --git a/linux-user/loongarch64/target_signal.h b/linux-user/loongarch64/target_signal.h new file mode 100644 -index 0000000000..e418c8e8f5 +index 000000000..e418c8e8f --- /dev/null +++ b/linux-user/loongarch64/target_signal.h @@ -0,0 +1,23 @@ @@ -1312,7 +1312,7 @@ index 0000000000..e418c8e8f5 +#endif /* LOONGARCH_TARGET_SIGNAL_H */ diff --git a/linux-user/loongarch64/target_structs.h b/linux-user/loongarch64/target_structs.h new file mode 100644 -index 0000000000..280acd0971 +index 000000000..280acd097 --- /dev/null +++ b/linux-user/loongarch64/target_structs.h @@ -0,0 +1,62 @@ @@ -1380,7 +1380,7 @@ index 0000000000..280acd0971 +#endif diff --git a/linux-user/loongarch64/target_syscall.h b/linux-user/loongarch64/target_syscall.h new file mode 100644 -index 0000000000..cb77f07080 +index 000000000..cb77f0708 --- /dev/null +++ b/linux-user/loongarch64/target_syscall.h @@ -0,0 +1,44 @@ @@ -1430,7 +1430,7 @@ index 0000000000..cb77f07080 +#endif /* LOONGARCH_TARGET_SYSCALL_H */ diff --git a/linux-user/loongarch64/termbits.h b/linux-user/loongarch64/termbits.h new file mode 100644 -index 0000000000..6c613a1973 +index 000000000..6c613a197 --- /dev/null +++ b/linux-user/loongarch64/termbits.h @@ -0,0 +1,224 @@ @@ -1659,5 +1659,5 @@ index 0000000000..6c613a1973 + +#endif -- -2.27.0 +2.43.5 diff --git a/0006-Add-disas-gdb.patch b/0006-Add-disas-gdb.patch index 00d9b5e..97e9a6d 100644 --- a/0006-Add-disas-gdb.patch +++ b/0006-Add-disas-gdb.patch @@ -1,7 +1,7 @@ -From 0789663b3a2ad105a209c7aa36d102a5b05f1397 Mon Sep 17 00:00:00 2001 +From dbf0724c5c9e7928f0007e6a5e0009cabba90457 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Fri, 19 Aug 2022 23:51:12 -0400 -Subject: [PATCH 6/8] Add disas gdb. +Subject: [PATCH 06/28] Add disas gdb. Change-Id: If41c0fc8aa128796e342319c7673fab3ccbf3913 Signed-off-by: lixianglai @@ -25,7 +25,7 @@ Signed-off-by: lixianglai diff --git a/configs/devices/loongarch64-softmmu/default.mak b/configs/devices/loongarch64-softmmu/default.mak new file mode 100644 -index 0000000000..fcb7e45dd2 +index 000000000..fcb7e45dd --- /dev/null +++ b/configs/devices/loongarch64-softmmu/default.mak @@ -0,0 +1,154 @@ @@ -185,7 +185,7 @@ index 0000000000..fcb7e45dd2 +CONFIG_LS7A_RTC=y diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak new file mode 100644 -index 0000000000..dc5ab39661 +index 000000000..dc5ab3966 --- /dev/null +++ b/configs/targets/loongarch64-softmmu.mak @@ -0,0 +1,4 @@ @@ -195,7 +195,7 @@ index 0000000000..dc5ab39661 + diff --git a/disas/loongarch.c b/disas/loongarch.c new file mode 100644 -index 0000000000..14dd131e2e +index 000000000..14dd131e2 --- /dev/null +++ b/disas/loongarch.c @@ -0,0 +1,2748 @@ @@ -2948,7 +2948,7 @@ index 0000000000..14dd131e2e + return INSNLEN; +} diff --git a/disas/meson.build b/disas/meson.build -index 449f99e1de..06a69d9d72 100644 +index 449f99e1d..06a69d9d7 100644 --- a/disas/meson.build +++ b/disas/meson.build @@ -12,6 +12,7 @@ common_ss.add(when: 'CONFIG_I386_DIS', if_true: files('i386.c')) @@ -2961,7 +2961,7 @@ index 449f99e1de..06a69d9d72 100644 common_ss.add(when: 'CONFIG_PPC_DIS', if_true: files('ppc.c')) diff --git a/gdb-xml/loongarch-base32.xml b/gdb-xml/loongarch-base32.xml new file mode 100644 -index 0000000000..04891e023f +index 000000000..04891e023 --- /dev/null +++ b/gdb-xml/loongarch-base32.xml @@ -0,0 +1,43 @@ @@ -3010,7 +3010,7 @@ index 0000000000..04891e023f + diff --git a/gdb-xml/loongarch-base64.xml b/gdb-xml/loongarch-base64.xml new file mode 100644 -index 0000000000..6308fb6ecb +index 000000000..6308fb6ec --- /dev/null +++ b/gdb-xml/loongarch-base64.xml @@ -0,0 +1,43 @@ @@ -3059,7 +3059,7 @@ index 0000000000..6308fb6ecb + diff --git a/gdb-xml/loongarch-fpu32.xml b/gdb-xml/loongarch-fpu32.xml new file mode 100644 -index 0000000000..a5b4d80e6c +index 000000000..a5b4d80e6 --- /dev/null +++ b/gdb-xml/loongarch-fpu32.xml @@ -0,0 +1,52 @@ @@ -3117,7 +3117,7 @@ index 0000000000..a5b4d80e6c + diff --git a/gdb-xml/loongarch-fpu64.xml b/gdb-xml/loongarch-fpu64.xml new file mode 100644 -index 0000000000..74ab55a015 +index 000000000..74ab55a01 --- /dev/null +++ b/gdb-xml/loongarch-fpu64.xml @@ -0,0 +1,57 @@ @@ -3179,5 +3179,5 @@ index 0000000000..74ab55a015 + + -- -2.27.0 +2.43.5 diff --git a/0007-Modify-kvm-cpu-vga-qapi.patch b/0007-Modify-kvm-cpu-vga-qapi.patch index c2b94f1..7c09b0a 100644 --- a/0007-Modify-kvm-cpu-vga-qapi.patch +++ b/0007-Modify-kvm-cpu-vga-qapi.patch @@ -1,38 +1,36 @@ -From 6e52e755bd54efb15afa052dac6dd0c7f696e366 Mon Sep 17 00:00:00 2001 +From 42c6c2a89fa44100141cd2b7e178f965d1b8f80f Mon Sep 17 00:00:00 2001 From: lixianglai Date: Sat, 20 Aug 2022 02:18:41 -0400 -Subject: [PATCH 7/8] Modify kvm cpu vga qapi. +Subject: [PATCH 07/28] Modify kvm cpu vga qapi. Change-Id: I7923af804bdbe6d44d3f521df1859aa081afceba Signed-off-by: lixianglai Signed-off-by: Mao Bibo --- - hw/acpi/cpu.c | 11 ++++++ - hw/loongarch/iocsr.c | 2 ++ - hw/loongarch/larch_3a.c | 18 +++++----- - hw/meson.build | 1 + - include/disas/dis-asm.h | 1 + - include/elf.h | 2 ++ - include/hw/loongarch/larch.h | 1 - - include/qemu/osdep.h | 3 ++ - include/sysemu/arch_init.h | 1 + - linux-headers/linux/kvm.h | 23 ++++++++++++ - linux-user/elfload.c | 67 +++++++++++++++++++++++++++++++++++ - linux-user/meson.build | 1 + - linux-user/qemu.h | 2 +- - linux-user/syscall.c | 3 ++ - linux-user/syscall_defs.h | 9 ++--- - meson.build | 1 + - pc-bios/loongarch_bios.bin | Bin 0 -> 4190208 bytes - pc-bios/meson.build | 1 + - qapi/machine-target.json | 6 ++-- - qapi/machine.json | 2 +- - qapi/misc-target.json | 1 + - 21 files changed, 138 insertions(+), 18 deletions(-) - create mode 100644 pc-bios/loongarch_bios.bin + hw/acpi/cpu.c | 11 ++++++ + hw/loongarch/iocsr.c | 2 ++ + hw/loongarch/larch_3a.c | 18 +++++----- + hw/meson.build | 1 + + include/disas/dis-asm.h | 1 + + include/elf.h | 2 ++ + include/hw/loongarch/larch.h | 1 - + include/qemu/osdep.h | 3 ++ + include/sysemu/arch_init.h | 1 + + linux-headers/linux/kvm.h | 23 +++++++++++++ + linux-user/elfload.c | 67 ++++++++++++++++++++++++++++++++++++ + linux-user/meson.build | 1 + + linux-user/qemu.h | 2 +- + linux-user/syscall.c | 3 ++ + linux-user/syscall_defs.h | 9 ++--- + meson.build | 1 + + pc-bios/meson.build | 1 + + qapi/machine-target.json | 6 ++-- + qapi/machine.json | 2 +- + qapi/misc-target.json | 1 + + 20 files changed, 138 insertions(+), 18 deletions(-) diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c -index b20903ea30..cd73fab65b 100644 +index b20903ea3..cd73fab65 100644 --- a/hw/acpi/cpu.c +++ b/hw/acpi/cpu.c @@ -371,14 +371,25 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, @@ -62,7 +60,7 @@ index b20903ea30..cd73fab65b 100644 field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS); diff --git a/hw/loongarch/iocsr.c b/hw/loongarch/iocsr.c -index 14521c2d5c..60daafd6e1 100644 +index 14521c2d5..60daafd6e 100644 --- a/hw/loongarch/iocsr.c +++ b/hw/loongarch/iocsr.c @@ -59,6 +59,7 @@ enum { @@ -82,7 +80,7 @@ index 14521c2d5c..60daafd6e1 100644 #define TYPE_IOCSR "iocsr" diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -index 3db269274f..3194a822cc 100644 +index 3db269274..3194a822c 100644 --- a/hw/loongarch/larch_3a.c +++ b/hw/loongarch/larch_3a.c @@ -846,7 +846,7 @@ static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg, @@ -136,7 +134,7 @@ index 3db269274f..3194a822cc 100644 } } diff --git a/hw/meson.build b/hw/meson.build -index b3366c888e..f224f8ad28 100644 +index b3366c888..f224f8ad2 100644 --- a/hw/meson.build +++ b/hw/meson.build @@ -17,6 +17,7 @@ subdir('intc') @@ -148,7 +146,7 @@ index b3366c888e..f224f8ad28 100644 subdir('misc') subdir('net') diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h -index 08e1beec85..95b93f1002 100644 +index 08e1beec8..95b93f100 100644 --- a/include/disas/dis-asm.h +++ b/include/disas/dis-asm.h @@ -461,6 +461,7 @@ int print_insn_riscv32 (bfd_vma, disassemble_info*); @@ -160,7 +158,7 @@ index 08e1beec85..95b93f1002 100644 #ifdef CONFIG_CAPSTONE bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size); diff --git a/include/elf.h b/include/elf.h -index 811bf4a1cb..66030f4906 100644 +index 4edab8e5a..c614bfb12 100644 --- a/include/elf.h +++ b/include/elf.h @@ -182,6 +182,8 @@ typedef struct mips_elf_abiflags_v0 { @@ -173,7 +171,7 @@ index 811bf4a1cb..66030f4906 100644 * This is an interim value that we will use until the committee comes * up with a final number. diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h -index 0886ed52af..62e2830e27 100644 +index 0886ed52a..62e2830e2 100644 --- a/include/hw/loongarch/larch.h +++ b/include/hw/loongarch/larch.h @@ -159,5 +159,4 @@ bool loongarch_is_acpi_enabled(LoongarchMachineState *vms); @@ -183,7 +181,7 @@ index 0886ed52af..62e2830e27 100644 -extern uint64_t host_cpufreq; #endif diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h -index 60718fc342..903475bb21 100644 +index 60718fc34..903475bb2 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -533,6 +533,9 @@ static inline void qemu_cleanup_generic_vfree(void *p) @@ -197,7 +195,7 @@ index 60718fc342..903475bb21 100644 /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */ # define QEMU_VMALLOC_ALIGN (256 * 4096) diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h -index 70c579560a..62d1a4b92d 100644 +index 70c579560..62d1a4b92 100644 --- a/include/sysemu/arch_init.h +++ b/include/sysemu/arch_init.h @@ -24,6 +24,7 @@ enum { @@ -209,10 +207,10 @@ index 70c579560a..62d1a4b92d 100644 extern const uint32_t arch_type; diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index bcaf66cc4d..20b90426f5 100644 +index c65930288..0e50d3749 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h -@@ -2002,6 +2002,29 @@ struct kvm_stats_desc { +@@ -2115,6 +2115,29 @@ struct kvm_stats_desc { char name[]; }; @@ -243,7 +241,7 @@ index bcaf66cc4d..20b90426f5 100644 /* Available with KVM_CAP_XSAVE2 */ diff --git a/linux-user/elfload.c b/linux-user/elfload.c -index 767f54c76d..9fb632780a 100644 +index 767f54c76..9fb632780 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1041,6 +1041,73 @@ static uint32_t get_elf_hwcap(void) @@ -321,7 +319,7 @@ index 767f54c76d..9fb632780a 100644 #define ELF_START_MMAP 0x80000000 diff --git a/linux-user/meson.build b/linux-user/meson.build -index bf62c13e37..195f9e83ac 100644 +index bf62c13e3..195f9e83a 100644 --- a/linux-user/meson.build +++ b/linux-user/meson.build @@ -39,3 +39,4 @@ subdir('sh4') @@ -330,7 +328,7 @@ index bf62c13e37..195f9e83ac 100644 subdir('xtensa') +subdir('loongarch64') diff --git a/linux-user/qemu.h b/linux-user/qemu.h -index 5c713fa8ab..66ddb25d1c 100644 +index 5c713fa8a..66ddb25d1 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -61,7 +61,7 @@ struct image_info { @@ -343,7 +341,7 @@ index 5c713fa8ab..66ddb25d1c 100644 int interp_fp_abi; #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index f1cfcc8104..729131ecd0 100644 +index f1cfcc810..729131ecd 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1614,6 +1614,9 @@ static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, @@ -357,7 +355,7 @@ index f1cfcc8104..729131ecd0 100644 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1]; return host_pipe[0]; diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h -index 0b13975937..7e2915d53e 100644 +index 0b1397593..7e2915d53 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -74,7 +74,7 @@ @@ -405,7 +403,7 @@ index 0b13975937..7e2915d53e 100644 struct target_statfs { abi_long f_type; diff --git a/meson.build b/meson.build -index 5f6ba86dbb..fc2dc58f33 100644 +index 5f6ba86db..fc2dc58f3 100644 --- a/meson.build +++ b/meson.build @@ -1814,6 +1814,7 @@ disassemblers = { @@ -416,9 +414,8 @@ index 5f6ba86dbb..fc2dc58f33 100644 } if link_language == 'cpp' disassemblers += { - diff --git a/pc-bios/meson.build b/pc-bios/meson.build -index b40ff3f2bd..a09ca4d03c 100644 +index b40ff3f2b..a09ca4d03 100644 --- a/pc-bios/meson.build +++ b/pc-bios/meson.build @@ -83,6 +83,7 @@ blobs = files( @@ -430,7 +427,7 @@ index b40ff3f2bd..a09ca4d03c 100644 if get_option('install_blobs') diff --git a/qapi/machine-target.json b/qapi/machine-target.json -index f5ec4bc172..682dc86b42 100644 +index f5ec4bc17..682dc86b4 100644 --- a/qapi/machine-target.json +++ b/qapi/machine-target.json @@ -324,7 +324,8 @@ @@ -451,7 +448,7 @@ index f5ec4bc172..682dc86b42 100644 + 'TARGET_MIPS', + 'TARGET_LOONGARCH64' ] } } diff --git a/qapi/machine.json b/qapi/machine.json -index a9f33d0f27..cd47b8d6bc 100644 +index a9f33d0f2..cd47b8d6b 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -34,7 +34,7 @@ @@ -464,7 +461,7 @@ index a9f33d0f27..cd47b8d6bc 100644 ## # @CpuS390State: diff --git a/qapi/misc-target.json b/qapi/misc-target.json -index 4bc45d2474..63cebef573 100644 +index ede905244..2cf4fa418 100644 --- a/qapi/misc-target.json +++ b/qapi/misc-target.json @@ -33,6 +33,7 @@ @@ -476,5 +473,5 @@ index 4bc45d2474..63cebef573 100644 ## -- -2.27.0 +2.43.5 diff --git a/0008-Modify-compile-script.patch b/0008-Modify-compile-script.patch index 87054ee..bcf14cc 100644 --- a/0008-Modify-compile-script.patch +++ b/0008-Modify-compile-script.patch @@ -1,7 +1,7 @@ -From b051f9fdabc2cd49c1c80ef50bbee276b6946609 Mon Sep 17 00:00:00 2001 +From c46de76fc41792974d0e1c9896f89ab257cae345 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 22 Aug 2022 08:22:03 -0400 -Subject: [PATCH 08/10] Modify compile script. +Subject: [PATCH 08/28] Modify compile script. Change-Id: I8573477d64f5974092001869d7aa9bb093f347e8 Signed-off-by: lixianglai @@ -10,7 +10,7 @@ Signed-off-by: lixianglai 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build -index fc2dc58f33..c0fb5788f7 100644 +index fc2dc58f3..c0fb5788f 100644 --- a/meson.build +++ b/meson.build @@ -56,7 +56,7 @@ python = import('python').find_installation() @@ -32,5 +32,5 @@ index fc2dc58f33..c0fb5788f7 100644 kvm_targets = [] endif -- -2.27.0 +2.43.5 diff --git a/0009-Add-loongarch64-rh-devices.mak.patch b/0009-Add-loongarch64-rh-devices.mak.patch index ef7533d..a06c1f0 100644 --- a/0009-Add-loongarch64-rh-devices.mak.patch +++ b/0009-Add-loongarch64-rh-devices.mak.patch @@ -1,7 +1,7 @@ -From d2163a939cd14d3d9a8a4afb9d9eacbb71b61517 Mon Sep 17 00:00:00 2001 +From 89fb9c8e0ca11e311417981d46768642d1f8e6d2 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Wed, 24 Aug 2022 22:56:29 -0400 -Subject: [PATCH 09/10] Add loongarch64-rh-devices.mak. +Subject: [PATCH 09/28] Add loongarch64-rh-devices.mak. Change-Id: I375face82c0aa68c053254b879267830d6981756 Signed-off-by: lixianglai @@ -25,7 +25,7 @@ Signed-off-by: lixianglai diff --git a/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak new file mode 100644 -index 0000000000..e7b5bdc8e9 +index 000000000..e7b5bdc8e --- /dev/null +++ b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak @@ -0,0 +1,155 @@ @@ -185,7 +185,7 @@ index 0000000000..e7b5bdc8e9 +CONFIG_ACPI_LOONGARCH=y +CONFIG_LS7A_RTC=y diff --git a/configure b/configure -index 48c21775f3..1f932f7eeb 100755 +index 48c21775f..1f932f7ee 100755 --- a/configure +++ b/configure @@ -581,6 +581,8 @@ elif check_define __arm__ ; then @@ -208,7 +208,7 @@ index 48c21775f3..1f932f7eeb 100755 cpu="mips" ;; diff --git a/meson.build b/meson.build -index c0fb5788f7..c5fdb78569 100644 +index c0fb5788f..c5fdb7856 100644 --- a/meson.build +++ b/meson.build @@ -361,6 +361,8 @@ if not get_option('tcg').disabled() @@ -221,7 +221,7 @@ index c0fb5788f7..c5fdb78569 100644 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch, language: ['c', 'cpp', 'objc']) diff --git a/pc-bios/meson.build b/pc-bios/meson.build -index a09ca4d03c..60009bd89e 100644 +index a09ca4d03..60009bd89 100644 --- a/pc-bios/meson.build +++ b/pc-bios/meson.build @@ -84,6 +84,7 @@ blobs = files( @@ -234,7 +234,7 @@ index a09ca4d03c..60009bd89e 100644 if get_option('install_blobs') diff --git a/tcg/loongarch64/tcg-insn-defs.c.inc b/tcg/loongarch64/tcg-insn-defs.c.inc new file mode 100644 -index 0000000000..d162571856 +index 000000000..d16257185 --- /dev/null +++ b/tcg/loongarch64/tcg-insn-defs.c.inc @@ -0,0 +1,979 @@ @@ -1219,7 +1219,7 @@ index 0000000000..d162571856 +/* End of generated code. */ diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h new file mode 100644 -index 0000000000..349c672687 +index 000000000..349c67268 --- /dev/null +++ b/tcg/loongarch64/tcg-target-con-set.h @@ -0,0 +1,31 @@ @@ -1256,7 +1256,7 @@ index 0000000000..349c672687 +C_O1_I2(r, rZ, rZ) diff --git a/tcg/loongarch64/tcg-target-con-str.h b/tcg/loongarch64/tcg-target-con-str.h new file mode 100644 -index 0000000000..c3986a4fd4 +index 000000000..c3986a4fd --- /dev/null +++ b/tcg/loongarch64/tcg-target-con-str.h @@ -0,0 +1,28 @@ @@ -1290,7 +1290,7 @@ index 0000000000..c3986a4fd4 +CONST('W', TCG_CT_CONST_WSZ) diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc new file mode 100644 -index 0000000000..9b53549edb +index 000000000..9b53549ed --- /dev/null +++ b/tcg/loongarch64/tcg-target.c.inc @@ -0,0 +1,1744 @@ @@ -3040,7 +3040,7 @@ index 0000000000..9b53549edb +} diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h new file mode 100644 -index 0000000000..d58a6162f2 +index 000000000..d58a6162f --- /dev/null +++ b/tcg/loongarch64/tcg-target.h @@ -0,0 +1,178 @@ @@ -3223,5 +3223,5 @@ index 0000000000..d58a6162f2 + +#endif /* LOONGARCH_TCG_TARGET_H */ -- -2.27.0 +2.43.5 diff --git a/Add-lbt-support-for-kvm.patch b/Add-lbt-support-for-kvm.patch index d2d6ef4..660785f 100644 --- a/Add-lbt-support-for-kvm.patch +++ b/Add-lbt-support-for-kvm.patch @@ -1,7 +1,7 @@ -From 02aacf8cfbe627c0012bf38a007a8a8ec9f95cb5 Mon Sep 17 00:00:00 2001 +From b7760c4fd70de74df6014394c5d27d498fed3e31 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 08:00:52 -0400 -Subject: [PATCH 13/14] Add lbt support for kvm +Subject: [PATCH 22/28] Add lbt support for kvm Signed-off-by: lixianglai --- @@ -150,5 +150,5 @@ index b6711da91..0eaabe394 100644 return ret; } -- -2.27.0 +2.43.5 diff --git a/Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch b/Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch index 7991934..330b37d 100644 --- a/Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch +++ b/Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch @@ -1,7 +1,7 @@ -From 1ebc0cc2ede04d6e70291ff1344ee80c38e5ebd2 Mon Sep 17 00:00:00 2001 +From 3e8ddd1af3c46387ed45319dd0dc3c0a673b989f Mon Sep 17 00:00:00 2001 From: Tianrui Zhao Date: Mon, 19 Jun 2023 09:38:16 +0800 -Subject: [PATCH] Add loongarch into QEMU_ARCH_VIRTIO_PCI to support qdev +Subject: [PATCH 25/28] Add loongarch into QEMU_ARCH_VIRTIO_PCI to support qdev alias Signed-off-by: Tianrui Zhao @@ -10,7 +10,7 @@ Signed-off-by: Tianrui Zhao 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c -index 01f3834db..49491d74a 100644 +index 01f3834db..ece96121d 100644 --- a/softmmu/qdev-monitor.c +++ b/softmmu/qdev-monitor.c @@ -60,7 +60,8 @@ typedef struct QDevAlias @@ -24,5 +24,5 @@ index 01f3834db..49491d74a 100644 #define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K) -- -2.39.3 +2.43.5 diff --git a/Add-usb-storage-config-for-loongarch.patch b/Add-usb-storage-config-for-loongarch.patch index 86857da..0529515 100644 --- a/Add-usb-storage-config-for-loongarch.patch +++ b/Add-usb-storage-config-for-loongarch.patch @@ -1,7 +1,7 @@ -From be087165d6ff6c45e768b85a23834d5e68fa0197 Mon Sep 17 00:00:00 2001 +From 1f41256389e5d8862d08b2253d752569727f1e79 Mon Sep 17 00:00:00 2001 From: Tianrui Zhao Date: Mon, 19 Jun 2023 09:34:02 +0800 -Subject: [PATCH] Add usb-storage config for loongarch +Subject: [PATCH 24/28] Add usb-storage config for loongarch Signed-off-by: Tianrui Zhao --- @@ -22,5 +22,5 @@ index 696ee9b72..15fc2d00f 100644 CONFIG_TPM_TIS=y CONFIG_PLATFORM_BUS=y -- -2.39.3 +2.43.5 diff --git a/Fix-LoongArch-KVM-header-macros.patch b/Fix-LoongArch-KVM-header-macros.patch index a6c8233..57ea9d8 100644 --- a/Fix-LoongArch-KVM-header-macros.patch +++ b/Fix-LoongArch-KVM-header-macros.patch @@ -1,7 +1,7 @@ -From 6291b67e4a12d65595de2884e5939a19a3c7b052 Mon Sep 17 00:00:00 2001 +From d090e30797ef1acc5f0f5488a60040606f60ff44 Mon Sep 17 00:00:00 2001 From: Tianrui Zhao Date: Tue, 20 Jun 2023 16:34:43 +0800 -Subject: [PATCH] Fix LoongArch KVM header macros +Subject: [PATCH 27/28] Fix LoongArch KVM header macros Signed-off-by: Tianrui Zhao --- @@ -9,10 +9,10 @@ Signed-off-by: Tianrui Zhao 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 1e6aed0fb..f99455294 100644 +index f5589b068..0e50d3749 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h -@@ -2057,10 +2057,10 @@ struct kvm_loongarch_vcpu_state { +@@ -2126,10 +2126,10 @@ struct kvm_loongarch_vcpu_state { __u64 core_ext_ioisr[4]; }; @@ -28,5 +28,5 @@ index 1e6aed0fb..f99455294 100644 #define KVM_LARCH_SET_VCPU_STATE _IOW(KVMIO, 0xc1, struct kvm_loongarch_vcpu_state) #define KVM_LARCH_GET_CPUCFG _IOR(KVMIO, 0xc2, struct kvm_cpucfg) -- -2.39.3 +2.43.5 diff --git a/Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch b/Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch index ea7daee..9d6896c 100644 --- a/Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch +++ b/Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch @@ -1,7 +1,8 @@ -From 442aa58bc9508065c85a3d2b9790943559c2c812 Mon Sep 17 00:00:00 2001 +From ff15ca716d827e6364e51f1ee9d7bc6440d55c20 Mon Sep 17 00:00:00 2001 From: Tianrui Zhao Date: Mon, 19 Jun 2023 16:38:29 +0800 -Subject: [PATCH] Fix host architecture macro of LoongArch to HOST_LOONGARCH64 +Subject: [PATCH 26/28] Fix host architecture macro of LoongArch to + HOST_LOONGARCH64 Signed-off-by: Tianrui Zhao --- @@ -9,10 +10,10 @@ Signed-off-by: Tianrui Zhao 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index e7d1e9ace..fbd6f5fcc 100644 +index 48034d427..6d63f0ab0 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c -@@ -2423,7 +2423,7 @@ static int kvm_init(MachineState *ms) +@@ -2503,7 +2503,7 @@ static int kvm_init(MachineState *ms) soft_vcpus_limit = kvm_recommended_vcpus(s); hard_vcpus_limit = kvm_max_vcpus(s); @@ -22,5 +23,5 @@ index e7d1e9ace..fbd6f5fcc 100644 * On POWER, the kernel advertises a soft limit based on the * number of CPU threads on the host. We want to allow exceeding -- -2.39.3 +2.43.5 diff --git a/Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch b/Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch index 8937b8d..09a842d 100644 --- a/Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch +++ b/Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch @@ -1,7 +1,7 @@ -From 889d874e72cec80244363d3c4f9594d14f05d529 Mon Sep 17 00:00:00 2001 +From d24d2e0d530e6354d4f9a4b213983779136f4ab7 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 07:38:26 -0400 -Subject: [PATCH 07/14] Fix irq routing and fpu option to compat with kernel +Subject: [PATCH 16/28] Fix irq routing and fpu option to compat with kernel v6.4 Fix set irq routing and enable fpu for kvm to compat @@ -27,5 +27,5 @@ index 6885ec6c9..b6711da91 100644 cpu->kvm_csr_buf = g_malloc0(CSR_BUF_SIZE + CSR_BUF_SIZE); -- -2.27.0 +2.43.5 diff --git a/Fix-smp.cores-value.patch b/Fix-smp.cores-value.patch index 26f4b7b..9517ef9 100644 --- a/Fix-smp.cores-value.patch +++ b/Fix-smp.cores-value.patch @@ -1,7 +1,7 @@ -From 509d230669e65fd45bd3a58f3167e4a12a74877e Mon Sep 17 00:00:00 2001 +From 902dc77676bc6ada74ddbdb57d00821435550bdb Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 07:55:12 -0400 -Subject: [PATCH 12/14] Fix smp.cores value +Subject: [PATCH 21/28] Fix smp.cores value The smp.cores should use the default value passed from qemu start command, and the argument is cores_per_socket. @@ -31,5 +31,5 @@ index b1501e0ea..8fc79546d 100644 return; } -- -2.27.0 +2.43.5 diff --git a/Fixed-the-issue-where-qemu-specifies-the-boot-order.patch b/Fixed-the-issue-where-qemu-specifies-the-boot-order.patch index 781123a..b86a981 100644 --- a/Fixed-the-issue-where-qemu-specifies-the-boot-order.patch +++ b/Fixed-the-issue-where-qemu-specifies-the-boot-order.patch @@ -1,7 +1,7 @@ -From 4e2e6a0576cdf365bf7df1693e7d6debd0179de5 Mon Sep 17 00:00:00 2001 +From d280c3a4a6ea0b3b9bf03bd4d4bd36b7e763287e Mon Sep 17 00:00:00 2001 From: lixianglai Date: Wed, 23 Aug 2023 07:10:25 -0400 -Subject: [PATCH] Fixed the issue where qemu specifies the boot order +Subject: [PATCH 28/28] Fixed the issue where qemu specifies the boot order Fixed the issue that the device path of bootorder in the generated fw_cfg was abnormal because the @@ -136,5 +136,5 @@ index 63a070296..05edee603 100644 } LS7APCIEHost; -- -2.27.0 +2.43.5 diff --git a/Modify-smbios-option-lack-and-Modify-the-maximum-num.patch b/Modify-smbios-option-lack-and-Modify-the-maximum-num.patch index 959dd7e..10eb346 100644 --- a/Modify-smbios-option-lack-and-Modify-the-maximum-num.patch +++ b/Modify-smbios-option-lack-and-Modify-the-maximum-num.patch @@ -1,7 +1,7 @@ -From 5fb830ad315907fca8a30551c1160632001fc6fb Mon Sep 17 00:00:00 2001 +From 3839b5ecff1bb68ed03e0cb901acfd331668d4fd Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 05:48:46 -0400 -Subject: [PATCH 01/14] Modify smbios option lack and Modify the maximum number +Subject: [PATCH 10/28] Modify smbios option lack and Modify the maximum number of CPUs supported by the virtual machine. Add smbios option support for loongarch. @@ -14,10 +14,10 @@ Signed-off-by: lixianglai 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 8f2a53438..e7d1e9ace 100644 +index 3b7bc3982..48034d427 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c -@@ -2423,7 +2423,7 @@ static int kvm_init(MachineState *ms) +@@ -2503,7 +2503,7 @@ static int kvm_init(MachineState *ms) soft_vcpus_limit = kvm_recommended_vcpus(s); hard_vcpus_limit = kvm_max_vcpus(s); @@ -27,7 +27,7 @@ index 8f2a53438..e7d1e9ace 100644 * On POWER, the kernel advertises a soft limit based on the * number of CPU threads on the host. We want to allow exceeding diff --git a/qemu-options.hx b/qemu-options.hx -index 4b7798088..8997969d5 100644 +index 981248e28..1b3f2df49 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2480,7 +2480,7 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios, @@ -40,5 +40,5 @@ index 4b7798088..8997969d5 100644 ``-smbios file=binary`` Load SMBIOS entry from binary file. -- -2.27.0 +2.43.5 diff --git a/Modify-the-ioctl-command-of-kvm.patch b/Modify-the-ioctl-command-of-kvm.patch index 9927a63..6b41fb1 100644 --- a/Modify-the-ioctl-command-of-kvm.patch +++ b/Modify-the-ioctl-command-of-kvm.patch @@ -1,7 +1,7 @@ -From 01a90be04dd6dd7edb3f49feca1ff1500ccb551b Mon Sep 17 00:00:00 2001 +From c593589f83c7655dcd8b9c144bf6061933d4ed40 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 08:44:26 -0400 -Subject: [PATCH 14/14] Modify the ioctl command of kvm. +Subject: [PATCH 23/28] Modify the ioctl command of kvm. Signed-off-by: lixianglai --- @@ -9,10 +9,10 @@ Signed-off-by: lixianglai 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index f99455294..1e6aed0fb 100644 +index 0e50d3749..f5589b068 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h -@@ -2057,10 +2057,10 @@ struct kvm_loongarch_vcpu_state { +@@ -2126,10 +2126,10 @@ struct kvm_loongarch_vcpu_state { __u64 core_ext_ioisr[4]; }; @@ -28,5 +28,5 @@ index f99455294..1e6aed0fb 100644 #define KVM_LARCH_SET_VCPU_STATE _IOW(KVMIO, 0xc1, struct kvm_loongarch_vcpu_state) #define KVM_LARCH_GET_CPUCFG _IOR(KVMIO, 0xc2, struct kvm_cpucfg) -- -2.27.0 +2.43.5 diff --git a/Support-TPM.patch b/Support-TPM.patch index 6601bce..8bfa530 100644 --- a/Support-TPM.patch +++ b/Support-TPM.patch @@ -1,7 +1,7 @@ -From e7b5a4aea5499e793ef769d1c39161ab33870bb2 Mon Sep 17 00:00:00 2001 +From 8eea4ea57942c83f0e1d9d4073004409505fda59 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 07:16:34 -0400 -Subject: [PATCH 04/14] Support TPM. +Subject: [PATCH 13/28] Support TPM. Signed-off-by: lixianglai --- @@ -514,5 +514,5 @@ index 000000000..340c382cd + hwaddr bus_size, int irq_start); +#endif -- -2.27.0 +2.43.5 diff --git a/Support-vfio-config.patch b/Support-vfio-config.patch index 6ae48b9..01b2bb6 100644 --- a/Support-vfio-config.patch +++ b/Support-vfio-config.patch @@ -1,7 +1,7 @@ -From 16268ffb6e5abbb5369a6a6bda9c60cd5fff22c9 Mon Sep 17 00:00:00 2001 +From e2e67dd2c2b0c3ff2737cd477bfc79cac64d4053 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 07:41:14 -0400 -Subject: [PATCH 08/14] Support vfio config +Subject: [PATCH 17/28] Support vfio config Signed-off-by: lixianglai --- @@ -43,5 +43,5 @@ index e7b5bdc8e..696ee9b72 100644 +CONFIG_VFIO_AMD_XGBE=y + -- -2.27.0 +2.43.5 diff --git a/address-space-code-cleanup-on-7A-virt-machine.patch b/address-space-code-cleanup-on-7A-virt-machine.patch index 1e64b4c..61c4d78 100644 --- a/address-space-code-cleanup-on-7A-virt-machine.patch +++ b/address-space-code-cleanup-on-7A-virt-machine.patch @@ -1,7 +1,7 @@ -From fe4009a9b0ddc2058793d3dc782778c95164ef39 Mon Sep 17 00:00:00 2001 +From 731b161d2cfddb67e4088282a33acaf90c2bd928 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 07:33:26 -0400 -Subject: [PATCH 06/14] address space code cleanup on 7A virt-machine. +Subject: [PATCH 15/28] address space code cleanup on 7A virt-machine. Signed-off-by: lixianglai --- @@ -272,5 +272,5 @@ index fc78083be..63a070296 100644 /* LS7A registers */ MemoryRegion iomem; -- -2.27.0 +2.43.5 diff --git a/code-cleanup-for-loongarch-kvm.patch b/code-cleanup-for-loongarch-kvm.patch index a4bbf4b..e94f6de 100644 --- a/code-cleanup-for-loongarch-kvm.patch +++ b/code-cleanup-for-loongarch-kvm.patch @@ -1,7 +1,7 @@ -From 1ab7b25cd4b5d827e8b04c981293b135059681ad Mon Sep 17 00:00:00 2001 +From 4bf40ba9ed6f98e7082623927d1c0c9ec6090f12 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 07:04:10 -0400 -Subject: [PATCH 03/14] code cleanup for loongarch kvm. +Subject: [PATCH 12/28] code cleanup for loongarch kvm. Signed-off-by: lixianglai --- @@ -30,5 +30,5 @@ index a24375ee5..799af7594 100644 * Register set = 2: KVM specific registers (see definitions below). * -- -2.27.0 +2.43.5 diff --git a/fix-smbios-type4-info-for-numa-support.patch b/fix-smbios-type4-info-for-numa-support.patch index 948aab7..3e5f0fb 100644 --- a/fix-smbios-type4-info-for-numa-support.patch +++ b/fix-smbios-type4-info-for-numa-support.patch @@ -1,7 +1,7 @@ -From d68ddb24ed08459b9641615e00cec50e6d025a5e Mon Sep 17 00:00:00 2001 +From 1565426c6bc04bffe941ad6d7ce819278da323e8 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 07:53:36 -0400 -Subject: [PATCH 11/14] fix smbios type4 info for numa support. +Subject: [PATCH 20/28] fix smbios type4 info for numa support. Signed-off-by: lixianglai --- @@ -40,5 +40,5 @@ index 5e271f339..b1501e0ea 100644 } -- -2.27.0 +2.43.5 diff --git a/fixup-can-t-find-cpu-type.patch b/fixup-can-t-find-cpu-type.patch index b9dbf89..3ffeaf4 100644 --- a/fixup-can-t-find-cpu-type.patch +++ b/fixup-can-t-find-cpu-type.patch @@ -1,7 +1,7 @@ -From e2d6998cad687af9d0efcc54139b28b0ff990b57 Mon Sep 17 00:00:00 2001 +From a08da06ba1ca817465e894737dced362babc9f18 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 07:51:55 -0400 -Subject: [PATCH 10/14] fixup can't find cpu type. +Subject: [PATCH 19/28] fixup can't find cpu type. Signed-off-by: lixianglai --- @@ -30,5 +30,5 @@ index f83bd3750..5e271f339 100644 while (*buf_p != ':') { buf_p++; -- -2.27.0 +2.43.5 diff --git a/kvm-csr-save-and-restore-optimization.patch b/kvm-csr-save-and-restore-optimization.patch index 8a60998..a5c3954 100644 --- a/kvm-csr-save-and-restore-optimization.patch +++ b/kvm-csr-save-and-restore-optimization.patch @@ -1,7 +1,7 @@ -From d28802932e2379a474e86010581390dbacfab8f2 Mon Sep 17 00:00:00 2001 +From 2b5b79cc839c3b471724c263a1a5e35bf69c1bc9 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 07:25:52 -0400 -Subject: [PATCH 05/14] kvm csr save and restore optimization. +Subject: [PATCH 14/28] kvm csr save and restore optimization. Signed-off-by: lixianglai --- @@ -595,5 +595,5 @@ index b5c655812..6885ec6c9 100644 } -- -2.27.0 +2.43.5 diff --git a/pass-to-make-check.patch b/pass-to-make-check.patch index a0bc8ca..3a3761e 100644 --- a/pass-to-make-check.patch +++ b/pass-to-make-check.patch @@ -1,7 +1,7 @@ -From b30eda522b141cf4b26a2fb22c2123d487f4169d Mon Sep 17 00:00:00 2001 +From d597742733befe23034a87afad7d18ee36d01ceb Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 07:49:06 -0400 -Subject: [PATCH 09/14] pass to make check. +Subject: [PATCH 18/28] pass to make check. With this patch, when running make check command, qemu passes to compile. @@ -160,5 +160,5 @@ index b69bca6a9..dea6a7034 100644 r = kvm_vcpu_ioctl(CPU(cpu), KVM_LARCH_GET_VCPU_STATE, &vcpu_state); if (r < 0) { -- -2.27.0 +2.43.5 diff --git a/rename-kvm_msr_buf-with-kvm_csr_buf.patch b/rename-kvm_msr_buf-with-kvm_csr_buf.patch index 4ebe9fd..6d13b6e 100644 --- a/rename-kvm_msr_buf-with-kvm_csr_buf.patch +++ b/rename-kvm_msr_buf-with-kvm_csr_buf.patch @@ -1,7 +1,7 @@ -From be136658b2055e4835f1d41c0729dba7b68cba16 Mon Sep 17 00:00:00 2001 +From 25f1ae50858b5c580336321e18ef0029d3dec922 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Mon, 29 May 2023 05:57:27 -0400 -Subject: [PATCH 02/14] rename kvm_msr_buf with kvm_csr_buf. +Subject: [PATCH 11/28] rename kvm_msr_buf with kvm_csr_buf. Signed-off-by: lixianglai --- @@ -634,5 +634,5 @@ index 404a605eb..b5c655812 100644 (uint32_t)e->index); } -- -2.27.0 +2.43.5 -- Gitee From 28a49f8ed2eac36f7cbc83bc4239d379b8d80d6e Mon Sep 17 00:00:00 2001 From: Quanxian Wang Date: Fri, 13 Sep 2024 08:57:10 +0800 Subject: [PATCH 17/17] Intel-SIG: Support new SPR models Backporting commit list: 3baf7ae635,target/i386: Add few security fix bits in ARCH_CAPABILITIES into SapphireRapids CPU model b10b248173,target/i386: Introduce SapphireRapids-v3 to add missing features a495eba03c,ebpf: replace deprecated bpf_program__set_socket_filter 5bef742cc4,target/i386: Export MSR_ARCH_CAPABILITIES bits to guests Signed-off-by: Quanxian Wang --- ...few-security-fix-bits-in-ARCH_CAPABI.patch | 50 +++++++++++++++++++ ...oduce-SapphireRapids-v3-to-add-missi.patch | 45 +++++++++++++++++ ...recated-bpf_program__set_socket_filt.patch | 37 ++++++++++++++ ...rt-MSR_ARCH_CAPABILITIES-bits-to-gue.patch | 45 +++++++++++++++++ qemu-kvm.spec | 5 ++ 5 files changed, 182 insertions(+) create mode 100644 1093-target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch create mode 100644 1094-target-i386-Introduce-SapphireRapids-v3-to-add-missi.patch create mode 100644 1095-ebpf-replace-deprecated-bpf_program__set_socket_filt.patch create mode 100644 1096-target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch diff --git a/1093-target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch b/1093-target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch new file mode 100644 index 0000000..48bd838 --- /dev/null +++ b/1093-target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch @@ -0,0 +1,50 @@ +From: Lei Wang +Date: Thu, 6 Jul 2023 13:49:48 +0800 +Subject: [PATCH] target/i386: Add few security fix bits in ARCH_CAPABILITIES into SapphireRapids CPU model + +commit 3baf7ae63505eb1652d1e52d65798307fead8539 upstream. + +SapphireRapids has bit 13, 14 and 15 of MSR_IA32_ARCH_CAPABILITIES +enabled, which are related to some security fixes. + +Add version 2 of SapphireRapids CPU model with those bits enabled also. + +Intel-SIG: commit 3baf7ae63505 target/i386: Add few security fix bits in ARCH_CAPABILITIES into SapphireRapids CPU model. +6.2-SPR new model support + +Signed-off-by: Lei Wang +Signed-off-by: Tao Su +Message-ID: <20230706054949.66556-6-tao1.su@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 0a3c76854..8a045e065 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -3762,8 +3762,17 @@ static const X86CPUDefinition builtin_x86_defs[] = { + .model_id = "Intel Xeon Processor (SapphireRapids)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, +- { /* end of list */ }, +- }, ++ { ++ .version = 2, ++ .props = (PropValue[]) { ++ { "sbdr-ssdp-no", "on" }, ++ { "fbsdp-no", "on" }, ++ { "psdp-no", "on" }, ++ { /* end of list */ } ++ } ++ }, ++ { /* end of list */ } ++ } + }, + { + .name = "SierraForest", +-- +2.25.1 diff --git a/1094-target-i386-Introduce-SapphireRapids-v3-to-add-missi.patch b/1094-target-i386-Introduce-SapphireRapids-v3-to-add-missi.patch new file mode 100644 index 0000000..a035ee1 --- /dev/null +++ b/1094-target-i386-Introduce-SapphireRapids-v3-to-add-missi.patch @@ -0,0 +1,45 @@ +From: Lei Wang +Date: Wed, 24 Apr 2024 03:29:12 -0400 +Subject: [PATCH] target/i386: Introduce SapphireRapids-v3 to add missing features + +commit b10b2481738304db13d28252e86c10555121a5b3 upstream. + +Add the missing features(ss, tsc-adjust, cldemote, movdiri, movdir64b) in +the SapphireRapids-v3 CPU model. + +Intel-SIG: commit b10b24817383 target/i386: Introduce SapphireRapids-v3 to add missing features. +6.2-SPR new model support + +Signed-off-by: Lei Wang +Message-ID: <20240424072912.43188-1-lei4.wang@intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index f4b5c95c5..baa1a8207 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -3730,6 +3730,17 @@ static const X86CPUDefinition builtin_x86_defs[] = { + { /* end of list */ } + } + }, ++ { ++ .version = 3, ++ .props = (PropValue[]) { ++ { "ss", "on" }, ++ { "tsc-adjust", "on" }, ++ { "cldemote", "on" }, ++ { "movdiri", "on" }, ++ { "movdir64b", "on" }, ++ { /* end of list */ } ++ } ++ }, + { /* end of list */ } + } + }, +-- +2.25.1 diff --git a/1095-ebpf-replace-deprecated-bpf_program__set_socket_filt.patch b/1095-ebpf-replace-deprecated-bpf_program__set_socket_filt.patch new file mode 100644 index 0000000..574626b --- /dev/null +++ b/1095-ebpf-replace-deprecated-bpf_program__set_socket_filt.patch @@ -0,0 +1,37 @@ +From: Haochen Tong +Date: Sat, 28 May 2022 03:06:58 +0800 +Subject: [PATCH] ebpf: replace deprecated bpf_program__set_socket_filter + +commit a495eba03c31c96d6a0817b13598ce2219326691 upstream. + +bpf_program__set_ functions have been deprecated since libbpf 0.8. +Replace with the equivalent bpf_program__set_type call to avoid a +deprecation warning. + +Intel-SIG: commit a495eba03c31 ebpf: replace deprecated bpf_program__set_socket_filter. +6.2-SPR new model support + +Signed-off-by: Haochen Tong +Reviewed-by: Zhang Chen +Signed-off-by: Jason Wang +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + ebpf/ebpf_rss.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ebpf/ebpf_rss.c b/ebpf/ebpf_rss.c +index 118c68da83..cee658c158 100644 +--- a/ebpf/ebpf_rss.c ++++ b/ebpf/ebpf_rss.c +@@ -49,7 +49,7 @@ bool ebpf_rss_load(struct EBPFRSSContext *ctx) + goto error; + } + +- bpf_program__set_socket_filter(rss_bpf_ctx->progs.tun_rss_steering_prog); ++ bpf_program__set_type(rss_bpf_ctx->progs.tun_rss_steering_prog, BPF_PROG_TYPE_SOCKET_FILTER); + + if (rss_bpf__load(rss_bpf_ctx)) { + trace_ebpf_error("eBPF RSS", "can not load RSS program"); +-- +2.25.1 diff --git a/1096-target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch b/1096-target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch new file mode 100644 index 0000000..0387342 --- /dev/null +++ b/1096-target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch @@ -0,0 +1,45 @@ +From: Pawan Gupta +Date: Fri, 23 Jun 2023 13:26:25 -0700 +Subject: [PATCH] target/i386: Export MSR_ARCH_CAPABILITIES bits to guests + +commit 5bef742cc4f0e21c80a31611af7881ba811e507f upstream. + +On Intel CPUs there are certain bits in MSR_ARCH_CAPABILITIES that +indicates if the CPU is not affected by a vulnerability. Without these +bits guests may try to deploy the mitigation even if the CPU is not +affected. + +Export the bits to guests that indicate immunity to hardware +vulnerabilities. + +Intel-SIG: commit 5bef742cc4f0 target/i386: Export MSR_ARCH_CAPABILITIES bits to guests. +6.2-SPR new model support + +Signed-off-by: Pawan Gupta +Message-ID: <63d85cc76d4cdc51e6c732478b81d8f13be11e5a.1687551881.git.pawan.kumar.gupta@linux.intel.com> +Signed-off-by: Paolo Bonzini +[ Quanxian Wang: amend commit log ] +Signed-off-by: Quanxian Wang +--- + target/i386/cpu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 11f52c79b..62149367b 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1022,10 +1022,10 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + "rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry", + "ssb-no", "mds-no", "pschange-mc-no", "tsx-ctrl", + "taa-no", NULL, NULL, NULL, +- NULL, NULL, NULL, NULL, ++ NULL, "sbdr-ssdp-no", "fbsdp-no", "psdp-no", + NULL, "fb-clear", NULL, NULL, + NULL, NULL, NULL, NULL, +- NULL, NULL, NULL, "rfds-no", ++ "pbrsb-no", NULL, NULL, "rfds-no", + "rfds-clear", NULL, NULL, NULL, + }, + .msr = { +-- +2.25.1 diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 50c7118..b7a53c3 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -998,6 +998,10 @@ Patch1089: 1089-target-i386-Add-new-CPU-model-GraniteRapids.patch Patch1090: 1090-target-i386-Add-support-for-AMX-COMPLEX-in-CPUID-enu.patch Patch1091: 1091-target-i386-Add-new-CPU-model-SierraForest.patch Patch1092: 1092-target-i386-Export-RFDS-bit-to-guests.patch +Patch1093: 1093-target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch +Patch1094: 1094-target-i386-Introduce-SapphireRapids-v3-to-add-missi.patch +Patch1095: 1095-ebpf-replace-deprecated-bpf_program__set_socket_filt.patch +Patch1096: 1096-target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch BuildRequires: wget BuildRequires: rpm-build @@ -2274,6 +2278,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : - Support tkm key isolation (xiongmengbiao@hygon.cn) - Add Hygon Dhyana-v3 and Dharma CPU model (zhouyanjing@hygon.cn) - Intel-SIG: Supprt Intel SPR/GNR/SRF new ISAs and cpu models (quanxian.wang@intel.com) +- Intel-SIG: Supprt new SPR models (quanxian.wang@intel.com) * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] -- Gitee

K@wriSq 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%0D!~#{S_Z~(#1(G zGS+d}*Q2MF&ET|x+mth(?^S7%;sG1H@#x4qT_`Sm#Qc{50e|&?UH@`pGQfXws9?4x z%Iy!bn?G(jK53y)=C3nn&MNCE@aBXdf7S1_ng*0_)qU@L<{s0Tu+IFVh}efjQL}vt z380g{e3w+dxeX>?z`)eUD+E|LV!QwB2EPrmyAP-0LSq7}Dd2o!O7fD4317MtvJ& zcyw;fZ&(I%ZY$-p>#SD*FVf@A=OLN6nMT_Bt)jVAy8+q_7G&2%2XLcZ-h82-|md& z@E+udo^3C+_dNJK1Zz$Eblzzv)_P=<@4X?9FL*Y9-~!I<{@Y=s@OQ1@IuHpQ$oQ%- zG5f2jrX!^8F!xh`4I&5;^up`O%w6!Ee+vgt8ifr1%{Bm8CK2uA_)3&3@7#$BuZP@u1hufm0L(i*25 zW`N=n_l%`uPPX<)c%tg^#F{g}ddoj`5|*u!u-=nUDvNJ0H$;by^XW={qcB5CvV8Y0 z;3F{4Nw6842f{Wzb)^z8)|G@6W3+ir)VIC=NPpm7k~HAsQ7qk8;IpT=pU3g+)grK? zrGZOHmL~tM;uCw1bG7^21G0apZpY;L2!OjL`Rt@6BKrK6>!?C@~KM-Lu{E$Z?~U{v3=uHANG`&dSs!-GfbqokMFp-1*6j6E8RN z$(_W4Zn}Y7de~i~0_fKXk+Nx}56n2`c^H|c$imF=6h7Z2@622LW%~| zh_F6IrYFZt)q^Q`KopuYLUm}DDlZL^281z8n2BJAJ`g_x@(6p|NI^RrH|1i?MtbB? zH!)GGpwUGFqm7)Rq{si0A;T%kJ0#Hml|V1_j!%*gSP;3L#f27IFp-pGigzAQ+D3GY z?rUI4a$(|+rpC;84|cfc+Pxs4d5r4y8Vh7Qs-$M+7A~90xoT}w@T*{v$yPcsU=z)v zvUS^+hU}tXVdu1|EN7Dg{RR%;*HCttebSQ|`TC^58uRjyTGYZ*1jqL8 zf5Uf2b++3U@q=iihnE?(L4Pq+OOWERaz$|f5`dUhsA}j98=xKyai6qRY2h= zK-f(^s9PVm6ypOOcLVwwn9dxe6aa2Oq!%1UPLp-3R;W!ya%dWcG1>Pq>~}wVk)%?P z8bh+{zFpCg62c-YHVbD}oZW%c&kwvJ0hK+qW}&4f_Cyq4W3a0?W{;vQ!B>K_%W>z> zGt=&m(FOG=m%EZCO&ZGXUNz>D6{SgnfyJ>q`#HY@O139*2F9JiTo&N1)8BjXmP!~CuW)bg|ryw(9?^ehLZMGz3+ z7gOdtE(Wv2)B5!A#=Q=2q|&jxAEWU;4II=JcNWx&>{<5NK=K43CMSF}mr4E6XM056HF?g~+n-!<@^Tho{mGaWz;OOcX1WcB>zhGQn$QbS_7_~jhvr=CV6(_bE5aoO_q_ z=}tk#ADk!x8}EjD{IavpDv-fY2ZqoQf2EC#Y}%MBc%gR0Usjvc;V$?;e(lXX+PwP_ z?Q!du-hfpOLGPY9cmOBU3U^lE{5cQ8I6rscM1f*AYX_Nj~dR76bQ#^I1Il+5>jjJeO`sIkcD+3szB_9R}p3LtvYZVWB>zlPfk)LQl zjI4_C8W=@1j!@UHhNA(Rj}B_|@c}MxsUGxb%JD{%)9a#X8xQ>=uO3J~aY$+y<*2 zFseHPxJ1)T1{p#2pO<`;ih+iqZ(bPK_?A1rag21J6 zOnpt1ny#YtVSicJ`;`xYp>4~%1SpeR(*bM%!g#pV7LfEbX^f(>{GVWp;FjpD*be5N z2+;pxgQ`mvT$yOz9um;t#tRquzFWhqPbK`bZXmC{PYE-Gh{S>#{aKdN%#+4ch_~l$ zCClqXPh%;lg-V!Lj$~wE4%J~6>CF<}98~ZvyU6xs3 zt9WEy#lbCJ96R!J-%{lD68VI2vD3QBDHy&;?280Up!DohhsT`;Q@!gZ|6Y;d>dyqY z9rY7M&{i-^38M#NL$fbCc^$v%uW5B3gDW9NX_Lc?Hlenf%$E`;-VT|P+IrR)HN})S zk$a`mw07G{79Q*-UK7@RRGk1I8#=tT+x+mDev~R268<_+b9Bzwslj5u8m2i9(hHcu zsUSu>vX0{cyO~5d>~*;(N51ti&41|r3R1nj5ve@UsW_qn;8CU=;(nQwvtQDn*hC9| zJHE19?HI)Eg1cu5=8cNOH)>P_2T_9XKY2li2l1EFtsj;z^39GgtPe&-zeP8O)XHGr zpTFfwv?uwcapvi7LcCdw#2IsXa76yMpNzKB>=E>U7pH{0;$xdrXHt*x{&?sT00AT7 ze)7tT&k~h((9DN&F587c(FyZBH&8H2D3}S?ziM{)UL)(0`sCNE{fe~WTHgMlk+CCC)zo#RvkANLQ)!R+~pWqUp zsD2Y!D^1kepzrm&p0&{DHTstK^7T2%Y;1OUm7G#O$2Pj1!{cVGRojbDp)(1i+RN&; zCay*`)uNwuXOftubIQW{5RVX3|YKwN4JHJ-9EflW|-2?~04N z3&Zwf#&7-0Bl=8n)eDyx`{8#JCwv%zlPnLylxccgi+Z*cD>8l&c7v}zHaGmY@ z`FMu@GcmtnHGOxjum;H&1nJv}?fZZh3&yA;W$>P@*x2Ja-Q(Y<%yq*I_7c7h$fJVG zQs5wq__Va{YBI5us=!M)*q;d9gAJxEs3 zG*j+dHJ~=nfHtQQEr6VP<(Tj4eddDKM6#km;BP2*w9;VTNC}yFReNp=eiUTGOGH1kvoM*s?A#9S%12GBJfsML73y87W zM!d{{so8GNxj*3^0%6$%vWq3Vh54R#Pp)nB1nJD{ej`W zI&CrQDe(;)) zhTk7WXN#=_U#ij6zrxql7~1I;oU5ij#Ty?`1I}ylosO7j&JYR(a+az9?mCxBksI}= zkAW+pQVpZy>HpGZz)na-1XwhQwQTz}a)`{r*S6ar3<|jrLoPGxg=M)6COI&OBMY8n zfWLhQ-d6&e*l->mXb1mG9lOqQS`#G(QKl;>q(?0JbCUu9C|Cj{@M$Oko6@eY27VkD zaXDTR52bZJ<;YeSRR`7d!*8_zw`8qp)*qCxJd z8(DOnKSoHr299V|qS*uN#6Rq0ByXfS)--xOuf8)}so=|(QHdlB6>E>CU-zxD6PEo0 zfsxPr3br!S^aP4i+ffNgYHNeH`ia{?j|Vt|%Zbr19^XC$xewDZm>#W>@{F6hxnPP) zqRR!OX!`D07v)1XZ5%||-Fe;YeZwjO5Snt^OzKawAAl4ZS1s{DgL?gd+6?H!!lmsx z=pJ!~5IMq|^?~`j1hXoV?7NC#_9MyT%-R5_S%Ko;!=%+2>=d&58xxX$ICVqD6j*<~ zr!sbYC*!M$l7mpxU=LT~Yg_7cuPUiGkb_4rn}xM=?5_!80lp%AhGb*0J6gHA?19%Y z;=9JR2|7(`?snwgEd9{NKt!}xXzzjB61a!H}$)(%GjJOKn}oHb5{an^Q=017?7|$cYLlgzYUOfG0W`?PN}Br znNmEBC?lRuFP+(GakF{Q3`DX1hQ~k3MKJo}ne zwt4_`5*SsZc$Lkijtn>}USwL(dlK=!NxmHe2@D|>qFIA7(Wz7Ukd5+QoMbDIK*ZO( zESD~^2AlONeja9COv4A5vV?4u4zP~husn6^U}?@D3XjKOY3K#{{FDem;1;oy8DP!^ zv$eEgo%JW`w=n}mlC8r6L>AHkz%4CPv_;PDg}QG`Y(mt#hj!4_+ECrU`B%}7ir_+W z$1Sn#%DaMLaEbY3+APFhmJp#d9e%3maDB+m!|1ql_&qnt!l};8VpN}?OUJ!omSN-R ze?n`$DH|X^XwJyabedLd>%dgE+)qo`a|skB{2vf2w?3t7Co~<65`{cuY6so_EP`Zg z;xI{iWzrdsNvrWpe{llkJQ$qPGB(EWgdEuNl?HUiFNEzpqc#S>VF4m^K12a8tL2GaYfmpVj|6JO;1>u zW$UP~qb0_>L5Prp=Ihc&5emE6I@bO#j%UVl@ZPLFAnb-FmS0ymz|lXo@bUU8Td8~e z`4n796<*Bi8Y&1Z<1gD7z?1w=oCg--yzZG{bfk;pB0z?nIY18D&y}>=50X-@`FCJ7r&nJX=`}REo43lL`xYt(sTOf4paMn^3SOMEG z{JVX#`~P}J#}=49);vQ>1|n~bua2{oU*^*DNS6jfpJOSzD?zv0?@hA1tf9vaAZgpT z-8C9=V!taOGRcrP^EQLkQbxq~ZuI^?@ksr{WHIO4fpl>1R5N~lVo9b=a9kqrj7I_j z{ycL<$3XHvkkcmlYj@9^z8)gbPS#g3i-)edBv~O{bL9KhYBWPWL-u zD)Y&1=_YnL=dJwKnEkAz_C!BkaPu2X_u1Dol^`{^Cwqv=v8(hM8U$kYiiEDaTd8BW zq&_UCCC!S|z;Fo_ydn=LXUqr{uf)$G5Jw%x9%hNry*u%!JH&`q3uyvvpH!dqth8G%5WUL$MKy zIdr(EPxpBbTp`)Oc*S7!MY5Ftc%7(dwaW1Agcz2e3E!y`F>@CvP(j%a=;^rxc{2H!X*hI&4y{%kE&PV^WMdJ zqB6(gRPZI3mCCz)q;XH#AGmy#<{oWol~nBNR+<2zb;;@F)wTjG1Zz_L2k2G;fiiXV z?P2i8E^gy9Mt4_b4xav=`1H<0fzNZQrI7jt^UU$&PfzPvQ9XPOLNUr#ADN$Ul4 z?Sv)2gh<_|`Q_^WWA2$_EdfGhcFaod(=w@$4o<&8%{B-~OZq2o;qdensshDdh`^)O zq+Y;3$O6JY5O^G*+9uIqc|X%ipK^&k$0q{wA3E2q9pHzr_!X+2^d3>Oi=*b}x`Acc zTlt3^YG$}Clvr&{EyUH!XWE;#sq8AC zYU1Aj3|})Ws#Ii7GWNetjcESbpGJ0rv?pM}LD&L~753vj{@k&r|6L#mrx=KDkjBX) z$H;V%Eo`HAC{}IJ4gw`SG^{nj_!Mk>Y=2=uIN=NIiG{)b##DM_2(bdr?3h_ zs$IN7uOpbGe(OYVg{HikB&=r`VFRDl{%SG$sD;W(22cK6ybgt5`&qCQZ6|=8&x<2b z;;mkbR`unXbTrV~2iE%w;jpYv)X3XFoSF;utPwO8xxZi!++fS9_wyZ$38JoW%FI_SM8n(e^`XoeTKQgF zRx<7vU9%BNOxV(h*Kv?T(-!}2?F?PGNRqcHS3e%D`QnQrZc>|h0JrzEYeT!~9cfo; z#8({ee#S`pI|Lp_?{&s}=fuM5sLXDQX!THQX6m9s$8A8Q9H$m4`(1$*;-GRqV0Rfg z8HU}God3%qDR#6WS-+qlV{;_kh3+Xo6CZd<<`eWi8pyIIUzV#K8TR|FcJ2tDyr9s7o4+Ru-B zbGTNiU!OhPYp&=)xVGOl8~neamh`&3yVr7e(|xJpCYf6V5_6cr^i-#WGW-a&Ws21# zY`jqV+atktcS@8u#h1^9+{MnCOILv56kIc#rdzOszZJU(oXy7`vao}-CM8&?TJ_@% zsIVp&4lXNa650(Fnt*<9i35#IVlmbL@%L82wsgvJj* z_&Qv6ucyLPbo!1Ln~^~xo5~f11p#Wza1n6mHLIeBdE=~eAg*oSi8$l%%W+H0@hg}N zMp@vr3wIAv2}xdqK57T}QGZ>KT=3Y-`dlIKe~dUtx-Qp^WzrGQ zqtMrX59A@)heON1h^w^$ZMBI35Z0NC0s6#Tj$R;RQN0SlZeWe`XeBx`q`mE%+BdEv z`8B(wEekJe4CK~-7G*t}5_cNkTTLhwWAX=*EgeH&Bov^pS}e{-k~xp2;*C#-8r@6U-+VOSV0DMGnYYyjr)$RZrCFB{m=Zy#ArX?jGbp%| zP8?KQV`9OyDF}nDffsjP>9)oBN5?vD?{a&1wsGk5_eb>l5?S-t-A8KfZ{U_IiMf;b z8Cp!A5|!Oj$ZgIxB%_folY0`OyMP1&)t!8;6*P6(4?vUSSl9H=aowH#`-R{D-A(4O z?a;4*&Z6VnyHpQpb_$R@ENpFE;{5zF(TKp#d)bq3LjSVly}bPPRZM7xqsG!Ft6% zEs+>9^Jkw(_d!&xK4dWrn(WbCjVz4 zNR*TEZk&p&Ob)rf900u&KZq$uk-fVBKncKW>60a?_LZ!{UXJ|l8adDKrZW=6l|o5s z9haP!!&sz`Y0hR_v+LdM(u2XtE=8tX>|v&&9``Q9XSAH3>_UE=9&a#eS0`B2GNq$4o4_3?Zv_hzU%WVsf%!+Co;tF5 z+0|Y@xd3@Nlg8rbv-wa92k@})NbcnVmtqk%UR`4MJv?I=1y7T|RI4s&L?Y3;n@uiRqU86n*(Ut6T4 z443`=@UHf5MkyNrp7+p#7xz=A1iSdVV6CLMla*}3)^{%&KO$<%HT1VJb^ zSS7d#R3`cbRibgI{uhI(bo?`2E^Zk08bP3((8k}K+3qQSki=0k6wXYJ^}~TYmlN;= zt#MsFI|R!>dt0D{cg5ZIVlNVTp`4uSDNXX&u0)u{l?K2q+_hHB$SVZkiJ2m8PR4Dg zP9Az2rDQRt7t@db%k{kRT2GD&?DK=~lSphpPSv}}$dEL?{YH&0QN>4=jDfx9tB}@u zU%TgJgY@}ze$c*g`ArzSjOOm~uZA^RgGEWvug%@|K_+4C zdMbTuZwrAPc?`ItcA|r-NzC9NU_<1*OaK2%fXB?ib~b`PB8IQ0y^aQt&Ov`~7StL^FLB~!Aagrc} z)ZI_xpL5x&ol^;08oq_84}a9A05nFE=FTHrUu?RWS`~XPi-Sdr?wH;p_t^o|lEiqI z-jHlx)FP`}zvTD2d?SDo4>yqa;9W)atGOiYi10OVmE6a!G;Ehy-z&uO58t2ec^kVb zwW2eWHc1odnblowA2fxSbE_*OD4>~*v!(=OK!KZYv29e~Ghg(^JxjqIxl~T&2tc2O z&KYYqe!R(tel)HW)Ip^sYeum152{RV=C1vERCQ6Ldq>U<>8VRPO;8&q7HJsp%V5rr z)A(9`zRbY`+m9pl)1d*~9J}|k?Hi(bg35#);~RNTgoN*-p{MhLSbZ^?wxogPin+Im zZTlXSepIJMB`Jg~D-1FeZT=$+Cn>mHht6?*x|07Pl<}e!_2^g5qf%@@nxCB+x%tO^ z>{QlUZd`8u>i415l^J`qW9Yt)$XphMz9y4D$xO|Y)+=wMyDWH*nbgY;8*fmQO`Si7S{ zq|lRB?3|yKa|CwAQe3SLUJrgM zjrzz|VkSMWl}(RbTn!bWzw1l8Br5%+TRA%^Q`HF1{Up%*9(vj;g3qIKF}3i2R#ba%;hVGm(9qIx#H!~&8AWM+(ypn5(s96mswSSYd zbj(J-s1YB&j9%XMx5(lVPDvUu&%g9V*?cpuoqF%L8I=mxy>8QNt2f~Fo(*@Q+7P)j zou(~Jeo3R6@MIp$tS|&yc$AG*M`FH+BU$by;5DpKH%F>YgzBL_2&9l}EqNxrCr!#1p!4uk!G`ROK zL=i~l#xdhx|F|ss?IfuOZIk_f^@;qOPCAs967~4m+5#xJ{BQlzCUEv35TC$^qb()e zmy%xNE2%=jB3_#Pf+plZ7)S)yHGZc#xK4-wW=CL4GAuh|;k^S{$0u|7*yST%{;DlI z;GA4>orZWIOFzZ*=$e6s{Ut=i2pV|YAaV99QO4COu@`O%mxQLv_(XKgwoqAqc8GP- zcNlZE1s6(P?7<2B1ov)>QI<9!HAd$Vo*WR!L=LR|;MJLDXUW^b`D?VgiZ{W^oZvs! z1~WXvk3+yitWbs3dXXi=zuLmtY|jEP-$-F_)h-Le3Y`CZ8P@hj)+(Xm)%|cNpJ8WGGRhKi>Hvw7AZdHnv@4ROWll$DZ*$-&|oSS!Rn$xG^)-MSt3|WW#xHq(QWD?<43?9k}RAZ%C)}%srU+t`t@X5_2!qX zKqTfQdrI-sYY-F)xvu)}pA4n>W02<6Qu*4cU}t5{$>BF(poYHH_&D(O2Zz#?unSsr zD9Nq24KOzD;P$~^!aZzL^i(=Rkl^ICi&K8(BK zKLR?_hqbQ{nB>nHcWA{qUyHT6k07e9H+@xV#eh;zd%B>(Q*lUO%>)r2?nZUPxKB$w zrvSb9&}oA;jM&oRAEMuyGiR7(~PN(!ZV5laci!dW$dJA~GRq#e;Bs6MxaX#xL%Z4`? z)=~hGg7llJH~;r^j>;>-U}mquA9j-0lhcMz=HO&czwI}*Ix7A60kt1ErikC=LglPy za8+^ud{|^8%KZnr@i89N3D#xDhV0%*kG9ZIcZ2R%m5GOU?ZtuhO)NPgK?X{jftIu^z7+-a<|Y)sjCXEzfSLNz3VD{f_q%k8jo{i0lH87KmuxmYS3kJz5wK+oghUx2VwK38^sj zXufAG3kBs;ipz8`zk!jEX4Y~DAhT|&#`sa-;3n~h;5YYZ(LJqMGnz#jq#%-rg)~qF zg4y8?O7x?BvjOdZ=Zl=j%>`&rC^^AKZH3j49`^158X3ihi5p)Ra@A=p1WPT z3&)*qRCmP8yg5WNT_`B8ENB&Es-?n1ut1j1wh{5tp=s3q)JHmNuFW(m`Nq7A6h?kX ze@0I{R5>?#Pvcb(5bp6^SAp%|y&EzVg_k?Su$_umGf693en5_ST=>ihxVrfj^`3m= zdv9Z$m8<|WWIB{v>W`x}ftal;YsfxXt)R+THegBtL!U*%5_ zOp(RPLtW$Q3hQUL`9yC~7cZVQ6=mmb*kip)(HWLSX$CeGK+f7Rwbr^mT~r7d5+6NO zj(d@Zyt%i!13%P{Tz@n-^ZaEidhTd2P?W+<#3d&=`BDq-G;xuSN3zW-FVEK*8g7Ke z5)_L)WVp&(8f{(xfk1pgBGCAiwRFk=#>Prd5UU;!%Iy(w^6*Yq5^P`hLh#Z`Yg)l2 zTlvJINz4t|?Qg>AT~Z(O3<}ggJlC=dRp$a~)hO?Z!hMbn2H`aI8PiULMF_$xZj zF#ILI$T+p54!fn0af(HTE3k?)RBQw+03$ zd+UB(7&FQ-n?}~_b?nKyCB`o}46);|<-nA^ZX>z(*h}Bh9$D>#%>99kj)<)6-+u>j z{NH@hlOJ_^8XruN7eP*%&~3%0p?4iBjRrQSdik!sZSNOh#}n>NX{SB4fl9Y))hkKV zxt6Hg1zY6hr=)o~z&r1N2&$*WGFPNl1qy2U5ZqIBa+jjd2^EuKVmOxq?*j z<|c~5v;k~q#@OWcf!mR?Tn6If&?+??#&a=$E<2ljkGSwI0$9Qhvm(Vg!nXu{+ zcbfNJ&(~bSiV0>q%*bLI)R}T)FyS|u2-2i*=9L3~aWyz26`x3s7x!zm{E3Ty#GGQg zt+Xf<3G%zEWu~HR%_VQNQr+^u;N6*qY8UW%!{F?zi@jL^)M4>_2B1p{Z{G`8 zSk~UI_;a^6+)W8tHXoj0yYr+SIn(24fzLZjCy5sqJB&Sln!@o2ajsb-M4#|DOzxR{ zlb9hKwB}yhhWfkgz5kt<4!9N#GD_@?)!)LVuxqavR#mbv4!~or zh$Wn#ac9QBMPT_btnZ;nTjV)wlB5{ICiHy*6dkBWbaTir>kFaWU4RVFl*mqa4mlVc z(hLu3sE3sWFy5g-(~_f()<>f3v8{d-P|~V)z`i|jCfz}B7c0LIAbZz7&Moq&o<9C> z3yli8sNth?fh*6jD3~Bm*q^w|<^p@r=~v85>*8OR(WIt-V=C3s#LXO+In2x(4?)^i z2|D=*)OEz+zAwn@Oe2Qj-mnSv7H`q&+&CVPCNY?rrW*F@-y0Pcff;AHCPA*z>gtA3 zxnfPTp>Gz~HaO_vOfI1V*599z`!hP~khHVc9AYI(NTzc(k2tKEP`QIgD3WHk^fr7) zfL(wap$Ic(Ca+|6Ay35l?RkYn)jN?}Ag}hARmoMTfjwnlu4;Gs*|u&;=z>W}*xrW% zM=nR)gF|2#oCsp3E^k|**ocr{7XS?S2+^W_FnBrq?ue~nobexKg`Fit?c`JAU+HF~ z%f06amTkxpo;If2ntWnor_?zDlUV)7kWspNXn2&tS-9FDU(%|Z3gE*9%;2NfnNr$= zP|>t2sb?|XBp1G+kFN=2N{KSA3<3WNcb_7Jt0hv71VYB=yyk zTp8-Pl|1)(R;*K8Dv~eI$e4Aq4*pjqcp@Qu_Vuw7kxsNc)_7bT>YY+t@syQH{3fEA zWm!RsuWBf{7u$+@o5mS-lu+geC4J@E(T5k>;rN@oNBwfWkdP(ZMf05K)2ITEY8+;( z?Bu=O+WMLk^0Dd%#&U6bPO;G8Hc_XLlah}y@xZV$SS0vR0so`TP7htGiWeRail$R@ z=4BLmi^}k(&7;-TWvBvXJ6+n~u6xv|LIo+VatsLFI9>>HzQNU|47sE9p_yEf7&?Je4%@@HX_9Utn@In^ zxx0-^ZN4B=nQjOw-zMH5m*35kR+S=1TAhYwSa+E_PKB{*Pl0(RlX*aR``4;#F7n?2 zmfCT)e=Zp0`2d|YFK6>{qK3p@Y;ad37i7w!!+Ef|X!DS=x!vviBe39!9ZxL2+350L zuX7a!5K?irmiGYS!u0rFOnT*;07D#kJ&56p&}msjD^ zk*yO|;yUl=kOysjse$1y@Fn8y()g$)|Am4i09qgFDP6d;U|@UL!eX8P+|VwqkzyG} zv|_VPE=?S2@=AI6*(Vp&Y;Q_K^#<$Dn84=EBT@C6xnw?*^#8k}jSFZDI4IU?jM7#q z(S(h2{-e6G1f-B!AaLH~uKOrlTM3p=XLU4?n}pJZ5{?2LA?@Qrdy*bsxy%wY5ABW} zhOkZfVD?JU)D*iQIqt6N&OBjSC>b;~t9l3=n(aiQpQT6~=!?jqVKq@;G~<+29Q;U)2{sX-dw zZBUmg%ni`fMP1u1x4>t2QPKgS)3hIGFm>19#aL#~F$+)AY_8gILaB!>f!MO&cOUQK z&941>BNtrvbZidP_&qT_wTivP>j1e#1YK~+8ueO&yJtO?l^ID5C}~UGA(%DFJj<_e z_CXhgV(}z|Itt=p%yy)gOQ03a~#GaQ#pIy{9vE6nLx>vg4T+gi=dY39%1493P zp#6aoLxVX2PjQ)b{F*hIyP@J*;4n?oy6x=0BBIvF@ z$2W7(>bauNUUCGq-8BBC54dC$s>Dzz4>D&Fko2E0Gr|jBM9V)79@b`CoHKW&c3^iu zLK;HXv6UsvP z%sI?4`YEtfN_?~B(3Mk$IyKnU`_7E)w+77}?S_!#Oo1_m8&$JHzasMqnvYVMU}ZBY z3pHEgevS?Lxx5K%q(|^>SM`s}Mf>9vLKF7c6b(Gy*+D%YjJFCvMehC%oc`OBFZw`r z^$12w0V=}M=ZjiR1EBkBJL~L;heV&N2#c0(z8JLdSj9s?L2S+~2P-v}v>qJ(q`VmN z2QkvFUZ}UJ|a?r^b2R?H$tkxml zZCijERb`72Fru)0hk1s+tkAv0{bQ6m)3YH@3^-c!8tsLleFulmhd1%}KjFF&ze3wn zVW;MKspNvlWrnm7OF@;5#f~-vi`pv6Ewc4tZA7>2j}y{gYOq}s8`8(U)%pp_d7i?( z7Qw0~T}#H{CdECTs!zAf4$!|J{PS3+_TN?@jLj;HBTgG0zeA7l=KTX_;s)r$VNi$q zSL$&5Qi4@DOo01%op5)EEtlST8Nr`3VO-H+gZubYt(b!@cT6{Th{AJSopiv5-eM`l zP|-tJvb`03FZ9<5W$37$fy8YX>)htDwc{hYj-B>#R~%m25-isgHnomrbIZJrYGGDD z1(7`4-}PUJaD1hQ@}RzJ>=DY9$yhmLl?QBMGn6mdAV1-`l=?H`9CsjW4WktUwI|4qAc)Bq4C7^fUXp&sg1Lar=5hg{0A>lBFt>W4T20cFr7Vt?tiMn zI4beIak^k#;!PGLRsC?&7eSa}^uehM&PHkYaB?s6mP+>8o#e|U8w8;8TfjBpV|EvToo4f&i}~uWj{j{ zQ7kM}P~6mMvxEk260ptgL@2ctcfhBq3keE{EThx347excaU}wfV@0``3!>0UxkTlG znDym%dTUU@5Dkgx*m8nET{Ptdsxw&WMh9&*Nle72NF1qYMqByyqcd3@Vrae=d#n{!-#3Hu{ouHMhsl6r&bh1ka=Gt2oU~2@Fv~Z)gS&Ed~J{PLKp)fO1~E zMH^B~I>E6*=lHR7@53>A0`{x|tCx0t$@S|6wTjfJ5oM;dU$6ZxcJ@^Ii|9;2)~uUX z@_2RvyjmWibAxQy2%Yjgw}X@=n^P(!Jz)`xTwVwH&JC69T-;-$V5vV;&_iW~dBRF& z8bWG52VO<9nG;9=W=AO#3|tibZ?-m`65+1qT2!ae1ZM~8U+9e%9>#5^KL@^)@~D=( z95(c0|1igxaRaxGp~s4|_bAA80kt=*LPdCt(9pApSGT`KrJZM^#=OCXC7$5MdcV?N zJ3%tiZ7LR-MIK)eneQqOtouKbO1Y)I{RR|tm!P2!SwOK;3%_hoaRhEum*vp_y?O41 z0W5RmHwVaijggK%-UNM^`uk`r)V5-Bd!KkUOHM1Jn8R-GR-dV6_rNdnS)`E8O($%X zKnBv+nT4-#)hG zJAkK^l@!vu6TX$1rhY2qkerF-_`nMVFGGer*3R;pca~_AzM)onF#0J#PRqlmX1*7g z9Z)!&1*ZgoBybjXYS|ERn@l-A!p+AF14~lGY;~)ty(S9jLoFW~nL~xR`-sosST7c@ zQU96|XVBne%#A_T(8o{9sfCz&IO8s3Ig+Ix>l-B7qb~BVYPDr3z;_gKHwLJrxQI$( zuVs`(L{l^!=NU#t+N1>RpBI*aME*4bw{21L3QO9INh{Lw27|*L-^uOqe+|!6hUPV? zeZI%{e$lLd6wC5-FT{+F+cAcXmVwFJF}oMQGwmiDV#E~kiH_i^YwSKF)BPpBNS)$O z&m;D5i#y%#la}}w{9?j=1QCQ3@DM*jZ&Xe?iprq(*T_~`JC1Qj67MfMvsXCNfb}q! znDHjDpEnE0sRmBt2jL`C3IgTQ%2^rDRwAWqmQQ4DwERTGgA@pq)Fn2j%QXX8Utm5q zE6AoyNpbXkBo2mPGeqmZxP~S^B5C!#EBGz;w8Gt!U}SczU%Aj@%w=}0{%ZiXFTz;& z9JS-!$34dOnl^LvZX%{pi4C<8hz|@8|#+s5+&k{=yFuvps+bCIZ(xO5nNMi z0|O2XiLcT~u%4^oo_Jq{fdHtQr>b9@GbTO1=@yYC+XbqE@&V9n*Sj0T$$IXd-t*I2 z%(NLsL#iKts(j1T{CuKXZ5YW9^35%c(cMxh&?#pEOmh%X8bGHB(pIGIgC>WvYI*Lk zqX(4E!Lw>kQX!(10iG)?GBd24G2!Z-LbU-%13s#zG3d09wJXIa$V_9i2~dd{p_sPd zYLL-5yV~k|ZWL;|vcqRPBS*ZP_RzM>yJN0-c2Z+qBI2a`(NZBZe(nF~9<%yDjeTYG z`|3~!!iG1mmX40Fv@sOu+6E|HacG0q(=%B=k@WHo440ABtEMI>cZFVezZ?c5hiG>H zBV(BuI*E1Mi7Ha3GY=}PJ&Jnai?5d0EYX}f`btUHA_U!ImUyo;DN#e(P*TGElWs=7yz5SkiL@@ph zpZibcS-)YkYW*}-nVXi|(-K{@DYrG30?XC|>fpq4G{qf!>?#?-VQjOAE3G%{Ad$nT zVyN5~Y6!j!8^yG%%hp7EQ6i~ri@($*n{UD+S;8pdf6{2Lf1jd zs((1Z#=2uMyJ`-mDEUpz7jsL3t1~ERwqND#T~qhH_uQ!bQ2)4nw5B^M;1xIN$Y+hU z*V`I~#gJ<$ehSbqeABZkq=p6uW-i=53@k<>d$lTwi~Zc+0q%IOtb| z3)Nnkn!%%%ZFoB^qQPem1|N>gr<$K#<BBl9cpvFg5) z-z>W@$T{>P*$GirqXr7FGCuL4ts~Sc~8sz;6AlJ?Mm4_$$(^AqP_Ffqw>fO zTUBK@B4@1nija(>OktPi1{pJJ89*T*r#1d9Hh?oIMjEkO zZejH*IH~skx|9%se0oUBw=3bj@ysN;P>fP2CS)e`AG<%_Ru`oiQIh!tX7D)q(&69q zV*QLZ_rv)0q0AHBk+g;F0tUp;pcT z6vrGatW*Zw39u!9Y{0b3Pv8buFm+iq;Ot-Uq}xHN6(V#pExJGcLKc)xQv1jf9BlCV=lSgOK`~wT<%mX3Jc@K}BelsEXMeYGN_PecwqPFP z*Mr%o+eB)8Xj&hTbAGQKeWmCpHS@hLCY}YTEmabNM0H>BZx$B<=U$|umva4q&wQ1| zGSgZ0lOStG+)L*3w5SO$pdZ846^X5vN|t(41Q;~>{(ajXG-96juf)iH>cj0h5Wr|P zre>CG4pYTQWPn`c&_COq|Rbks4pXhl_s0&3ng5 zdC@E%8Y3M-71M#_M4m@fDag4!;>iOA6A5`wRjQ}_O(uANu_k)zjvG6;uEn-O?hq$@ zT_f^O>I)E!)~mR%N>NE-NJ<#qRw}uzt$tHwi1(4E+o+k$KHjl)ERXQ?CjoN+ zv8K(BC84l?>34OVpmRX|u@iaLG{M$3W5rWWjajcuPDF3TUIC2HkRY+(@Bq53Rf>uq zxQCsiidCo-B03CQWYKts*T!+Rpn2Mj7M=#q@fnM#RJ=uchNAcx5C-gcLuuaksIJYr zlJ!XvyKP&NdV3V&eEhPhFi7q+)SD%lTQFAZ27=xqQR4RYlow--3Ln7MHj(VYIX^E3T08-#XbersM7Box!SLEl-zgDBmpyd6?EfG03sGH7V95pG~Ln*q>*C z8u6c#iKxXM=wy*tl_4OirmY@J2ah1mKQ#TlYN+d)t4iQpkPt68VRHj!s!T3B6?3A) zica42Ru=8N_DB7v<69aWS?464Z*)g+yNu@f39sF$Dm#!6HHHJcFeAjO|8^)8icSPn ziXk+_kTF*>K|0=-Llgj#M&y23D1jH!TD>Ke^=-ewK^ui0<3JRK(-DYr-^O+lQA%!U zzI?;T9e96Djtx3JMQqs%PwL2Q$@Awpzi+#^@l^!3`)%u7s6$3vQkZZdSq`0yY^7 zSXdAMbPUKXS}UEV-2Wf3^^M}zX}LCFPL`*-?e}7J@2yBZ9>w^(C)Ov106##$zu|0x z$BL;NnwpAan77U`@kswjdIO*HM;$uOyc=fzWAdM3GhtiukAKna8lU>XDrWWSZ`zL~ zIFxmZ0z4~m_`1&!%$`zYQ#?Ues3+R5NOK7B6m4VBilx+T1~@ilvf8Vq3uTjAta=^E zv{=3!J}lf7X{+q@A+1c$$E;I@1OgigyA^0GOg>)aTo=+$1b8%`?7lI&MAK@%%! z(@di4HK4N)hzMG`$XjBnRqtNX3GP1Y@SAtfpRw-s^Nir}?bA$aM3FxC*VQv+h@n;t zc3csW0^Y$>)I9G}A9HK8kLab$SpS~-U%`9CwNQ5*9cN(Y^d6dSq@t@A0mDcYEP;LW z?et@P?dg*mP(KF7;1CS z7R6KJdiWpXzPl>$Dw6UWMDE;kW!vs1+u}Zc>H=RF4hZZUI<(qO9)~2Ma&W?CpaaX4 zhJ)!bnir6}+e5Uy2TW)wGS0bfIs@RL==UJ_83*+FmTAXist-{z*R~wETr#Z}HbPN& zO+)p1zz-s1XrY~^vlh@3BiaClcH>zp>g0)gg)4%Y6u4bw;U%BjKXJP6UU0yXsU0!j zdI$~_w*RjF;j$-);@3#2quL*ZxKB66@JSb}K}>6Wtb~Kg%{gqc@{!s*5SKs~YG>nj z>eOHX6}~ft|94Mf6C1(WTLpMJV#Fu{9b`|V9Y>T{yS^d^ zrp#Q%$pX3}dFTf5@vC1-G^9n=IK)5ID2(C?qb&*&66vUO3DI|^eRe@R7~DlrO}H6W zaY3!uzAD>mS8|N&X49!s1T=*%rm(9JbK}&{L{Gk8rF^1DOm-sELHX2(e3vIZ-)Q2_ z_za?KT=9wb`z~_>!nTbtialFQ^tj5R0^S(z=I?_*wkHEuP~sWIosg%26f5TY4AjUW z9PJxk5!J#$v=7gF?=*Ucc}N*)ARCu4>PH(I2PR=gY#GE=!d(fHNL&blWtb6iXOw=g zLLryZA*_)J#{m!09c)_f#3SJ@O-eofslQT`{&r)OL+3qdo3KX^F}kPzo&>(oQ26zI z;_%F}CFi18hH+OIEk<1t=ME4$iCgY4=0g_y%6BDLz{&D}GlqR~dkn|qV zDi@t{zb{&>D`IvC{|p&@sxF^I{eD~M62FE<ByB^#ia`hGML2|0KVzb0;j%Fap)t31d!2Toux7v^+`v{5rw?W5}E>ERrA< ztFxVfP{x!CH1_LpBOz^7mIZ3VGXa!8j!}uS9$6?`1i=LesE~GDwx$nvf10(b+@k-! zOx){SdZurd#i^K^P+Xs4z2xvgTU@$O7QUJt^i7ILs~#h9h@V}+s2S|Ic80Y+f2;*# z5M6OE%68lgEFf^|Jc50%WiDg>8{Z_iA~5J)lbo3O^lnTV$zDyY+?oA-^DXnTc#x1) z|FGXdpu4HMPrGbF2BL{&`idp4aBq&7+=aX}7?wj1S_-56%`x&-ewSYehBeq|t<)b0 z7Z;MXQvT&YXXx~d>4 zyVx)8JY2Kh+j~<+g3uJqX+(jOse0HYEs9hTM(P5_C#@_cF-TdWb6Y%N?7oDA6^OiW z>ald{r-s@c7Qqz1rLIcnE_`3Fb=SHbDue6++xznD08%1U-9sGeC#e<`&Hjr!=U=P7 z<;VNEVMNZ8irPzuJ)p|nGPKfr0y$TO;U$kNpluR}sjw67$()eC0F&Nh@)#`)5dNp; zX(6HcuZ11fw#vV$PSR?7>hzhQK{M{mi9sJg+OueEqkMBFvdQj!CAkqL_Gz4w+Lt~GeMY4ZjL&F9(4C?CIu^b=`lAGLYSmX8Gi=2vp0qZ>x z14|R`)LoPPx9-c35I&NrsHy9L!Zb&2Az0NY$H>@t0kX3CHG1WU@W(WN-NC5I8Vqp1CJx2rNN z=lYrr?KM^OKTia5TySO~0~1|hlLMpQk0v0+Rt|t3eKw8blD<5lFv)wU&}fwqg*x+w zGmiNs36Z(lT_Q@yncFIbnJ%!07GrOM{<~)taPluI(^(Z!I;XSTU(3iq?(yc5*0i{w+B2sW`b_P4*QI zE)xI8win-Ax8fQ?(D`~SKK#c#2e+Llgr_L^^GQurix!V7oj_>Db53nMPP;?qt8Jw; zIkDz??dQB$xm?0{RZTJasZG z-U5-9%ltLzL#|%iXeBRwVW((y#iVCqIW8Gi9#EO^!FKN9x;91gALFf79hsq1+zU*6 zbg}J`7lbWb!8hZ{nrtt>Qxg8RVSz^$`=noTnZYX^Y5VGs$CuX;V~ykCC_AG?Wos6@ z%qZN3SEuyVH7mvR9{Kx37E7*iiZgXf2{={YO8Fqj;lfDfOyCGd^tw#NPK0M9TpCxd z+X-Ofv!OS%vR}<)f`nsIZ?K?WHJgsjW^oCxd*P|9W}Dn2+BDhW#)jfAVkBoR5>WN6;U>nVa=|cQ9L)`KotWV7GJ$ zdOzs5kC5x?0PtXX2k0u(iMy9J5^GF_w>m{GE43Lj6SBtCA(2e?v|a;W*%XAh&3v6pB8Iqc(iwV8PL*a%ug5^Q10m3NiU|m+ zfT|jZZRlCPTp;}j50i7^f}5OUZMs%}B6LG(o2Z=&aKDK%)XF%= zteeb*Eekh%RLb1?@t&%F2Ecm-2rq&2f*l8+wpq~sw~N-8JoxPl+tEF5C;mIk{z~98 zP_j>gk)?VDM{HXxgazl-ej&3qSZgj!Rj1^0JHM}>d@jN2;L}4{7pa`%i$sM5N@9CL z3$)6pWFv=SRSMrx-Tyf3Ayh;|;Q?lm@ha369sMd9iPbrplCw{&6+kzF|4itH3)9le zDM>toUurWT`^#p$8y+r)NXRwm3m$!poP21T9GTa>jhLY|Qh$IREgmgP*5zwW_zgj2 z>L4}=W52ORRPL&O29wKXq=Tmg-99>};NT6Mz^Mi8E_iPQP~&!v=y*HRV05Z$9Z6(o zREW)N+EHdb_3~dhg5N$(c=C8>$;J$UXx~%m=!e#~#-4e~R-9GJLkkN795O!d>J)m{ z%nf^0aAx=)($1+kIL}>lkK)^`k?v%fwwZz>#Rv)8krQniF%x*D3^rUFn zbBRSLC?UZNO&6X$u`!sCeL}BUwF^$w@RX_h2WXcc-rm@Z{vBY`N|DK76QM_gTkcT+wvOk-gxY<55Si7}& zJHDTV)6iy`3{kK!5(idP#cUi{x+!6kP=S|Xw)dft?wg}TRO?N4OU^^GxI7TbvEk_& z72BN}@q?#4J&KZq-&oKD{y3eHnFf@}LI;wgY!jJI^`jRIXTa=aFemsO>{HpBr&XY_ zqd1{4pnn8F4d)J%jjC?C$njX~d(P^FJnEkLaqS;hb!1P?G}$=f7xxy7s7>3~E~wOm zl;wg7>)dwVN_Cx%(yru|en}O_3pUx>J?(9@(kdXp#MF;mUTh&UVbRJ^8TUE(x0=zO zi3dgxv$h(OWfa04< z$d*KJ?U5b89)+g^-#%1liv8E0C7+Y)C2xxp;wjcBO}wtrYU~WxL+9@H$%+7Mgkg&^ zeQ5CJa;SLLK`}rZ`8VXbC4Tk~wJG1yL;82Dleh>qZL(B)0AihovribmfKu$4PT#q1 zwt=hbsiC*zt11@ArCGfxb#BEoFLs_vNEpq!ft7jOd-rSD|Cfgj|!GrI^Vuiwtf63xW! z^SZ%J!j9b>`vg^EeW;VD_&a5&6FuXKB=f?elC?q79Ns47Z(8ii7=}G&0J_uu6QGRb zU&0qBhXVyJuVZ7&URAcJ-MQmo)HeW8n#ya=i<+nSN5V7p`8A1jjgiLDFD^KPnyS?l z%(t|~`VU+*X_bXN-QH;k^^%1ZXpjX=Ln`kz`>7Aaq{DUL4E>ld5&;s<0O8n_P|m`g z%q4TJzf`Ihsc@zFwrSNqrW&e-&5(kT-IV_r8nte(gcrMvx@fz!Y>cFSF+)41*^4cBB;;=x{O)1lBho7^dQ1fHWL1blKl zMO|$3bz_3#=r;kmHk|8>| zL<9`6>X4s)_mmBI8_56mZ}!JDy=qeKfR*nEKHBssg>5ztWLc`dTm z+()j-FU$efnBUZhVYQ_su?>qujyr6)+t9&7SmH)Y4^YcEkpKHZWMUnUz!jqL>h6AFMLha?y!`oYYnCCPuzBGpmynBjuZ2L!ez;`5 zMW!@C>KGYWnzEglGm{(LL4};BcD+fuxiN`xtN9bh0U}5iA`YqWuTCL@us_+rJq4xO zZ)p#23~O*d%D2x}s8h9mWgbe&m2~81L$p=-BNq|LsAvJKfZ8XrOMD}9$AzsW>3;#< z75bnP%+9Rfr=nWLQig8X|#&+^X~gihwGs!|5eWz<(%PwuSZsWfms_-!jnhfiqGr1cCRkA z1JZ7qbW)%PnCeBw-$!|ll`y@Nz(3zc9uhQ6vzH9eXpcEOx;(c#!Pi6+YAAQvha7_f z`AKPc^qyPbx}@d&7vkx}jE_k9=ysT@`kP`gG23_07-;3LBK zdrnsEcS)VllWqL36_!bZF3m-tUu~PhTjEkp7Nz*%bVVT%w4mc4+FH^VW`Tj4Xq?5u z2$9q9a%k}=J@+RYcpwftGbRgp6v|o*%sVIW@of5dp(OhCEeYL2)yIrzT<6v%iKQDt zS^xaC@{dsXad;%LyOQh2GVNAd>u$j+Oj1HQ7;|J}@X3BN)=rT9RyJLX<)i*+dJfRC z-hTDP;CeSPIqa@+wKkqOx}samp1euZRHRa+^GDp|@U5 zq{tzaqicbw%YvZn%z~W8rHrLCkN{fHjL2g_0A~`syuO?N^R(=&$1ncQEjStea|(QI(L~`=+DOD0X_!5~w+A`o^7mxlB=-dOk&221x!Pwz(8V z!5Qo+u$(*5A*ktny3t7vBtHxy;mBAxL4U<@brteDSg7u5#Yo{fPyj+36o#dF_avupQ||i8l6AdDIlUR zc;!e?z3;ze5!r1I$2HZQg`_HH9Xv6=Mr(QunHZ5_VqaNtV_E%HIFSbR*s=#KJ5Q(} z`n6!mpOuRuk4GH~Ivgz8&Tf>Waj*Q0PKiz zYd?>6W%TDKSdY81AC}?CQ@lrGxDmf|R`G3AP9Uq8NI~77MESb<9CJ>f_X2ZFH)#-L z+RXWX2uRhP@xH8-C)+{?&#m9iJBbF@_y~2o8Tvz!LD?(URnHgn3ETSDmH$&gco!YE zeIaNWFfx=J*UDnoOGS6E`~PtZ!GEh#hroX>SQA>s%$rs;)liyYtm?GqP3w40Uo zl})d<+@oZacyONe$*f591eiFfvg-bXaD%A8%tNpzrF9k6MS87tTUlqdNx?aBc zvc{dp*hV&0X@sjX$Zld&34tRUN|b`tTF>dE8^Ev1J&#$Le=x?%=R{blJ=c zXfEdLqXUmXN;)w-ST+4)4e>*{%SQJV0C6^OiB-4q;KI@TXfyl)v(CplRH$_ewa^01++veCEl z^>8)>h`b9k8qO^uk$q*zSg)nuV*aF^2#wu)T9OFJ>ffM{ z$M~ky%)n0iw8ZWgwAP=}+#m=xA_4XUNt31fb~40~_{gJ>UG6+wO#eXuf0aOrN2!=| zpk;}aie3nDC9G0RVCYEaF*)k8Bq(rAh&oBh^W$_9HH%je-ES0o2KlYr+kk3+L}> z;SzRho=}z%UbIz2jtES~Mmwx|sQilLqLiMEYHxz};VJP@*mJYX9ID+Naa<05$Pwe! zNoUe?vzW~{Rn`WEv&{x;8ENfjd`Zgs$j#?QsR;9fZeRbWH*yK9Z#j_ji|xgn%L-Cl zG+PD29&M#Fa2U2aaiu0>ZV&?Pf){89mSbKKqRe%ynHP#B$m2W20%r*``fU=VJec?m zN9DUw5erXEeAd$1oYt7|$xc2>JMJdPfr??nV`8|Z>ytwsQ032T#WXiOfBZ7~pimiC zu9VPi9au3mnD<208jvlm-rM0W!Feb8<}=N(fD8wfv&Hnw2#F=5l^OddC@Gt2kK@Eg zz*B)WGXH5t@AS*#3i4DO1eU-Cr5(?`*||%g{JH8$`4j-m$?ST;3Jd!Y^>xcT&A+N( zbq8$*-wXjdn4{QdvoITI)%L`ghX=JG^GAeWypTrnZTFcj>C6bJV zT32b8{u;||p(bPROli*N(%Fx0TRB@43Hi=JyI2NZe%VQxQox;&n&V700QB%fZm9M7oJqr^tzSq;=~b8);L#X=k965Kub$)%E>+*4Jd}u!aSPTo!@hgp5g{#>Uw-O-p$&PZ+<>-YYNbz9@2- zxk~b?Xi9pZy>QN;kJ;7hR`YWBq991~KxIl!;NYv+1;h%2kM z_K1IHqo0WN@k?^UwYy(>w&Q6ik3O_Z3J1jkC{@dT6OsQ5Bi~K(M*$yP$my0Wu8N6y z;r4am@3Ak!mugDQxB*9ykVgzQHBQ4)JM=f5Qrk={0wwxNdFP070B{DjI<(7T?9}Zu z`x&UEA9DWw;-+1ya`6+ef1!9|oJkT?FM6~KQmp-ql2#Qj@%4m}k#{4dbx zR4z$oEt^m?%zPd8(k2Ep#5u(|4(+f~7b0fhMdSLt zl*Q|;A9P?l^78Teu=C<9+UA*Z~cz=*9yZLUfv3 z48nMd1*e=yNUdaCJE*a+q8mZ245%}KHW>nM;0omnz-;AN{2RkeM3MwR0HVAWb?d}& z=!}a~cI7Z!^%g1g4S^f0a#ToUE!*q^Ul>EsMv&}76hx)7)#kLF-0_ycf}T%$8ug^U zc!N)xPVF>O2}6-6`~tLe1%P1mom%+SH?n#l{rptL70sgsD2YCt3KaGEA>;BfbDow+ z_bjRsQ$=mV896PPo9d1EWNHv`VC|JW^}FZC0n=nO@}n;*>a`){hV;;y&HxUvel^M2 z!T_}{XA9bcu;u5T%6nH9;pdRV#k=lhc;nqx5kTmOo(In1n|h(nTh?x!4%aJ^`$~|A z#i{C`-7m*GoE4u`2KH5q*hZPWi%l@~G z;2CxO+LlDLmmQZCWeGn|d@%1)d{un9CbAlyU~BUL%+Z;YZYQ&-H%jCYS0f`v=RZ6j zU8&3P_uaJjWs}$QOY|4o0gmrGC4JUpBB#F~c5&T$QIj+;aPK-)F$yv4<)U?myr9!vC`p3;9dq?+YS>soc{NXTbqOvPJO#y}8o+f|Ryz zDDLHx3n86hbvK-rr3*z4n1rjkYrIDBXmcTP8Q(A*P5kujl2UN+*f`_n#o?NI^j7&K zgi=h65%&S~nc-nxl>Ce3dflHzi6Pvto3Cia`Z-BGr#?l%UwSWpd=4}bA1&NwhJ}y5?$=*uKLx9mXFT^?_^dNI# z>{qR!p{clWSV<&rpfInJT-ts%E->nd`=@g&DK@V5r9l+cH910@p%G|OD`L_wWaxst zH{8?1fC~@T;F6jqWYeIV3qbiWE5xWe%Yt}|?ANaJ#!gM1i*g^zt}WIZDV-wWw*(Pf z)Qu@oSeZ4Q+99ukz~ZRx)@NQxw&A6K;_L2b-RlGRFgcmI)g6wD56Fh~dc@RZTB)jL zvn_(T7Ij`Hy8=>Dti7q9V5jMe!|)9==|7aAcG4 z`6!L@;HU2ej`^z6{y|8u@5+ai5CuMxO*no6v$o4H@?*rA7VI@%8ryzl!vT68PBkrx zorjFSVyK;6qJk6{Qu*rMEgyRvS#Vz-`Han6{{rSSxD;XjUPzrJrL!X6uqKjR{q!Mn zA`@fyIze6rEJel4C4@til($s9A#lSNdYD}w=^^jnF^Ak0j;6vVLKsCd zvL5uo*BNb3)u`>~a2fT1P4;x|g#daF*07^a4EVrc6-PxOnl=CNO}!Yu+zyh>D30AE zwOv?S*L5gun|ve5tod(UKW% z7n(Zd=tY=Ka{S?CpZj;{wn_PEzjW43n~=CnP@&D^=*IEab33zH@$^7+d#maw$*P(q zxt5|_wG8MRfsDVs7b43E*{WzH<+g{J(Cw{Jt#lx-@Uj-B{UmW528GctxP5HkimA?8 z@ba$rgFVQLY0tGBTpgv>D>W|crph_kKSLVz#id8*Xp5YQ*AeqhD`GEjglE$yJ9AS8 z`-&UVf2)%l!3>nv-Hnb05Kv9PK15LY1Hpi5TZqjBNNz01l)e(1=pUgFFV|; zky2I^Jte<{5PQ-XNl5!ht|aG;s|yGbnX`|V>PD@c$c|1LmG6O`tJ+0!U^M7S-v8yO zwK9amQ6(8Cc+$c1_DU*{lm^-tSGu#9F}Oo<^-YY5Bch5)36Ng^Q=Um~I%-~>Bt$!< zh~)7hx;noWc^p#r7emx)DBm=#KeM-&;yRSR`lhrNfQ_II%P+X!>#*Bm)7o$`D_x0rVlSX5dtfHs8}v(oD`+qg6htRv}@p&;_}LAu_jl8hi@vX?)K z|)hN_3luUCZ=FY!0|P~PG4WNx^lgqmjZr#;C` z>bsmpCFH?1m0wls!Iz(}@E-8+p5oyJq}~@4=x&5PHfraW2F6-^u6gFTV$NQ5vT8`J zy`mzs!?31SFds}(eNjF*wjWiSWTw#k(G?Ic01TJii~U_VF5R$w)6%D??@O3|%g@rB z#F|xZi>CmpBiX9`y>a&{$PEm#q-Mq!*d2fI9s)GH9Fq&w_!rWDjQqMbhanuU)Xswa zXvPU7F`3LYFH@o(Jd}5}f*-4;w!&lQGO}Sx%GRSVL9)p2urHm*Rp>IJqOQS$DQ=67imcdpk$%22-Uab(K5j$Lk!YOjH&KTfz3tISgIQo+RgKVF+ zpXxdRL!IX zN(lWUaahG=GsWxfYHPRI6A?Xa&jna#w891RGe+wNO z?K7dmIeB9IZ5*r!tIwB))y*xzfoz59$kpJ8u+bVTC@Z=!yyB~sz8*p@UkvoFE(}+B zS;~thL|6@r;#+TNN(Eu2_+G19{!lHTmf_Gla+rCps`Z>C5)P7nStfR?h^4WBd+b}w zt-O0;Yh^>ei5XkyCFxAupb0=O!G#8=HH2ZyPQoG0;qh`L#u24Ku(RCwQid?NOxmlf zA{MlvTT2C+vGdR04a99A8;-g{qJ8G$@>5$IllEzLe(V8#L;3$R^|&qY%hN;c~VKiSz= zphb%CaAy^#Q*z7{-B30L{D_esmrzZz+u2F_-rwMx3FR)@XP#4F%$fHvEtx_`FbQf! zJB)b+CN=*6#$g7uGodm;W90}BoE*JC^K=x^NX7q(JH5nuUWl;_KSgM18AX{7oTI&d zROA26U26}}ta=+*tdMu!3*MN$MmWDr2r9l((DFlF{i$uz2fqycTyLB7%U94mQP%{v zBq~jTO1XSBx2)5`7Cj`rAe%@$zs?oj0~8>|PJqx(Oi{>R9CdRa9)D{QqoCBTXSAsL z`l^2-C1{y9F1o3qA#(%`(GTqgmBcBa@rBbnAL2QNykrDDxy_`QXj<-Nj=@=Xti9Yz zbZ>&{PY@J^Rvh7|rO5nN&qGVMSV$uyh5I-t9r_uEn8BXpY?q*3r4mZ&;ZqO5rRXXy zsaw9!!W??@yeN0Dt(Xy%Ngd+?(tT2LPUF&)#8b`>PhS{?e8)FJpcP~Ry(a~qBS!vX2YWP3o4|Uo9)SR%a`7}HDlhkh3A_{9rsax zIkOKQn1Hc`gW4HM4QhN^f``zZ>L}*4A2Ho~dS3gK*me@)@^`1dp^Pe!r8IwSiyX?W zp?1lLk1pLyMHY%fv4@w*@#mx|Fek2uQ?shQY0O#u!ijGGN>L|FL?Zzhs0ggW5||Hc zYIV=59`sS;#`9VF_8VzI?+j7P+3vg{@cjQON0RYqFDe{oD%hThRvo~yl=0Brkl6kF zD!2v{)t(miXna^+VqjSgNcEoCMFyy9=Mi9*d|a7rdLQNE6-L>W*mQod_~8IGd3Pk9 zRQ>W6D+h_NDqj$1Z1lwM3LYo8a=iIAg|;{(R8pZz+KHs{;6mvVA@BbZDnXMVme!ew z|E3{4R`3ylQsrFo_hM_2Dr>iKb)y^^k;+I%WTVJ;qYA%f_OgeNG=GZsS~NXij2eN| z6-SO}C@{Bt&$kAu6X&C1SpFHSoL~Ux)|Ulw>t9{{Y=!Q(PN!e z^kC0j9=|j#d585up;V{6f0US%=y@nq>&#G?Vx(hTv&x@_e*iz!m`4;=6|kZq&Yke- zrr;(v3kI0TZSKSDR~R|Rz^D8W3AKL;rD>Gx|GcPm!QAxlI;ZGK=z2#k4FI}=H~B@Q zQN6=MYpvKFjqjXxW8k&4{+tZirF>wmL`Qk>{s+LoI+C=wMY51kZg3rB#yEhO$%F< zzVq%q*69DA!2VoJ3Zlw^e}C8R*P*V?_@}@K_RmsW3`)~nNRe6Z1>|?iOgl2cxZEEQ z%1y4hoqa=sJD91KV6RQ8t%@%Ri3hLOm{lWK^kpWE*E!Es&c|~wPlpF~nSi0zEhoK; z%S`nYPbfsE-kqZpsf9Bx`bRMY=DN`-93akQ2!rME=QJ1j6GrSvN31HG&pLGjcG_P7 z^T6tbNfJy)n{;jMsL1#p<&7|dRO0aoMcdx-E|)Qhfp?7Cdf0p0lP8jnHZ6F76P{d| z;k?KTKiLX+Ni^ivICd1d2I!Ov$ZnqYD)AYjd$y)hpX!bsbX7eHsh&g*>QOJ(llf}G z>#H-=5=q19B@{y5yLtPJ%%||Wv2+=^5mpe*U)aJ0Nskf_^jw!YO>9a-r+YlIe8i6=@T;uy@|^P(;5&Wok=#t_~(&kEaN}iGe{*>_mzr1E`Vu3v=r7Z z#GP$CcmcmA#l!U;2dsd>Dq}01Yzjv$IHWVD1zK7_wFs^T-TV;?$mJp4`zX&z3_;5X zOs@q_R~hh#avJdk!&Qa@d?!uL14%F^F=~1>5dcmU_-an(p1_8Q1;eL0@_%#(R|Q>A zBzTscw2Zie;UOr6=t331`)Nl5_)n37PA`y}aMI&07ZYBbvI=o{yN zmKoE(kVfvZF}w?Do|qw~88=CHgpPHxqz82ASfazn)F&BB`9y!aC;$OKIH-ghK-~HtXuqc*Y!9e@6p-M!=+!BsENQBI!9^MzS>VsN)6%lm>ZybpsMS95SgMb@RFNy=ZdLJ}MHv zvX7v!_LkK3*%f@N(>(c+q_FXD%#yp%@W)N)P)-KPr3a2euZM<{ddQtzfhs#?MFeee zP&}1NOD6MS+jLC*Q>dtC>~UV^pWM$pCO&tPjyz3;Z8G`SS|Cg?u--HfS1`;I;~OHf z0q_ezruE_chB1Q93ilF(h8ItY?F$I|fIs1ks?fNpctiKgbd|>ZUu+eEb%eKP8%fRH zhv)*g<1u3u&p9uDh z0c*%18n^ctio%-l{O_??>H)Dt%G|RYO8gmX4|5gE1@YD_QvuGNw+8wo7 z!YU)%F~yTy2g^4Zpdmr*PdLvyu;>qURr})7LIj(e3MP_SM7daZaEwssp(_4XY2x`U zrPX4INnKx9xHhvVY<@mz>BG;hPutH4?c`{?f`Ubtk@|Z?(Pnl3UyJ zzNit0j92*DvXOVGaH{}p8|RIR!u0xg(=?`f#RDmfI5ThUn-3%hzY~xyw=54t0!aI+EH2)-O@&3vOhz35YT?ukj8n?9y;V2 z@;k^+af4fE;L}Y0;_i_c^#&HrhXw{qsCK#x0~DyyMh+BU$T-}a-g?Nml~{?JM?1l# z9F~Pufj~i%JV;ed6kiiGpQy0*H>~_6K;WkP`G=)}V)Zo}VtV{C1i*avYIuEXy zR_2wcJZRDKZ*&{QP0uS#;Go^hj~SYNi+7z3+pp@CnlD^d!f4$ep)BQDNxwQoE7IJb zWG`R|wML6M`#h*^mlnO)J0K!@t;BiEciWqyq$g)&H?nsCR(ay~IU@1HgwwRsul`PIs^_A#e`YfBcwz6$%b&_@ zgccf`U9_WY*&cxVUUso+%$F?0S3PQ%O40oWr6lk2t>WnEw=`Z!QJ8ic0F9C_@i!6}%}zMR z2H!N?vtvz>?-3A#S5t0noDkEVa^T(F-KR~}d|`}UXk?ji8Z?d?`cyO_1i+)7&u;6$ z3bh=|u*SdWC5Ap*9wSO56RwG1z_bX<0EkDIX;MRZ)SnDbmp=sNkAeOlh2&I9c|*u_ zP0R}SRAPRchgg~d&ah79;;~dd&_yv`z*0^2DE|g)`AP>!Fy!7wQJ&9$=(mA-$)h#( zU3^p_@f+#zN4U7zg>(mVzA_mk$_kv~}6avs5` zst8^{%qC$inKA)?Sz(-K&M?3X9baH^l_%q>>IE-vHu&NA;pj*eKa{PbZIg;gw(-!! zWf$~!n&}v?*sZh3P69*;@>|*5eu$1*C{y#f^<^vgEyRooYXwg4mlnE=%E`~Apsv4} zskC%}JO)C*n zY;D4U%78Gr9|q$>0%@{QNT7bEhtO)U)Qwu0ZIu>eLixaA+zlXY(<+Epw*#V5)ZD zfCUmYq>h;C7RgrE;Rop_p`;VwP;{*Xa%YZKR4c92S}U3Z%uh(zsBe z7x=U--6Fpt?S@DceHU!sc{^txKOQIT4K=8xW>Mbq!78q^^I)Td?-;4X!zOan$go-o zbf9ZQPPc#D8Hv5JO{y@JQN~+YQ#_gwN-!&tblkIAM{xAuH6LRt0~PsAT&&0|Il*zC zq!lRqFN&r)B7!3RT>BZt7I7;W2JVHjT~G!GM%{nhw^DYZfp`4=IH&@zhktOlsN(=oS?{N>!w2qK%l^> z`U|AH#yaB~67k>OxM2rZ0=)3_u9Z4~{EpywJLo@n-4-Od=9VaVK#)LW(JfA=drtTl zyK(tPUuQ;q4Su&5_cw`~q5v~|1zDIFQF;vTvz2t-9$2xJA_*>hKFcwQtExNllb#`5TP*7avpV3*Sm)}!D&M1l}U zPF|7hs0&S3R-Q{|TroZ)dU6sV5KF#8G9hoQPQYI$@$n$W64^91TSh$bLrgG1ZbD&M z6pAGGs=6#9p+v-0ffvnf^ zlsOnMqys$S5CyCzq1QAAm_f7kw%h7Q)Nrn+H0tggHAyIvei|rfo}LU5fYhm~?vXxp zqy5(aUbcOJKyyr$av4Oy#S6FuPk|j4;gd{=bp~ANQ}vQMGa1&uJVp~Nmeh|T&;>bL zIGw{fEK=+npKop;@_{h{(FS|0?ih}Bjxa$>U~)ntD5X<>Lq?Q;>x#=D;o zHW}4s!DZ@mju|_ClUi$CsnO;+8M}wa6(WQl7Hf`rR>20^dQ~*2W`)(cUoHeeTkQ*%@6U$C;b;A96PJJ6{k|)hg7p~ygL&Xs$&9E$)ID(mn zfy36js@vd4#H4$=GA&`tU9jpdXfoj=$HSt=(h&LYxt7X-BAqB(zgt3HO+$toltqa~ z3e6FiJ$w@;IFeJj!{AH;jvv^jSLbOr8OBVm&WQgRbUxrS)>@`=J?%a#dfBaz_r?n( zubu1j`hxu9`oN&Swnl631(n3;!m)@@@3m_Vh~5Cz4x6RrLo&kj6(7u9lWSjneKhpM z#vg0yX9$fvBTr5}z`GFESlY=zMoNTX4kJoh zihB&V6q4~(0bhGY-YLb6tK(AOqm9OFjU%7-pYl`wkYCeHW)Oe~#?o5u*E&6YPfeiI zD+I(W`4m#{ows<-D_HNeB$qb|K1uZY&iho1=}6j=uDST;5wK%7LV2u6e$4r4*u%}= z%Tl4c2dgZHlq~$6Qqb?WnCy9^vrRaLuDAtnC3lgtplg1anfI1QIzs%=(W}>Pt$XGq z5q$7jn62Vqbbih*+CHNU+x867KwilK*33s+d zskVoScfbW=ML&H2mkt;(?ubYvLznz-SJMLqV0=$pU8&0)PnoG`qP{;3waZC=ukxl} z-*t7C-bF~cHN^doT1V=hw^!0koU)V#fw=>C^*5dgf_=4Ax;Yjon$f{sp7qmOV;-}D zM}20x?`ee*e4PWtC9S$J(g+z1u=B#97D3*ozZ2D4l`vL3sn3+`m=Z+YQRz*t4@XOj zi@KBf@jL{Q5)fp&`cu?Gt^aueFJk>9<+wwn44%cVelH62mxOnuhArUg#e$v8TKJCr zwEgS?fOfSh{2&I>JFmX^h0t4^khcQ#05LzQ0P1{dBV)WGqb=lr{sH*DjWH?uKAO2P+1op!B@3(LDT#D>^#EjE#aKsG(E@)B4(=_S#BMajlm}rGKxc3)@ zo*s>9?i~ep(~A#?$f0PtTt2gw3FU~98pZ{sQ?RfHrdK{VLRz-+$+WDkf>)eO?^EjA zEDG=x^c_D3f~p?|foee2gnKn4J^v4}%xIi~($D63kOW{*Q@nCZknknVthfK+) z!n}^hR2cA~+o`&o06Rd$zb@dPnpregGv0B8B)$P#^jeuT0~-*%5uC_mEi!r1Fm_GR|1ZE^DRqnlpizwHf%!(B++5x7%tB((T10#)z=qA+Gc36(ai zI4s`SN9l_-W-$ZdI%gb^*scZGI9r94#0e09{_9lASNH_!&^nt%0W~D<==g? z(u)w)acs+GEx}~=r?sJ{{$3~PC#Gz3b~3mH2wj*66z}(kL#l`qarV!$X?SOr|D-+K zH9otxVP%yXZ*;7Qm8x+N4&eT|gjd?fw%_35K*^g4=6QaVsShUHE5+G|S_>EfjKjrx zp0iv(U*FmK2(!s|@Xo8X+z)FssuEdY*oAPwk8%=1!8_5%Og$s`Bk@8Db-+bqT%$^S zL18|mx+A>eBGC9_i+eFCBrM2sKy*hBbqY2}ll{L1@bkf>%<)G6@tP7&{%-@^Y8^e6 zeMIEh@L7vg#=>TBdqpv0^UxS%S^0%LpsHku)LY0DrihdIHioqB$y)DC?kE{*hVKG< zEEkrO7zO&O>I(K>C;#r$o;Im7S*7~6xe|@Sp{=2Jdv4A$&q|6I-a+s6=&VFSid{AO zNI+Cu0l8`*b$a3W18o&xHavw?zfEk*{etH2Z_4?O(~YW$zAZ<7UZV(7%o?_<{#_v8 zu2|XGY!ZJ0@Iyc&3XlqAdac01)5^~g#TlI7-5qsD{Cf^+q~WhPCr{1)kYI|OwPJfx z`amWw+>SXrTKi9tKc#AaH}&^yLXGZV=f7cIIIy6`%r(=HzTS?U=ZY}$f*y$%eb^s| zxN)Nv!Pth_6H&IQf|`*cBWIoUPYlK+JjQ9avLl*ks#1Cv{W6}~d+>{}iV?l8);Bk}?mK63zs__Z>t-!Sm@kCkPIc-bUO01)_1tK5Okk)xw09yiZ z7)c11!T~UTR*7S+d|>JnbZZ1mwRiTpda2teR{hF(e9er}FGZowiS1tY;D(qlU0wtm z>dy0_tE+gon{Oo){tGtdtnrZwZ$+(DRQFU;2cV6zmQi=8R~Zo^RO{N=bfGoo^&EB8 z3W*0*NkEjqubKJ!EJ!5HWut9KE;i*8YRuiNqaCsNAxKXmW{#umQi?iboyR`qWuvU1 zir%HP{82%Rc&B-|5^yy)GiZASd?5ibzxrU!2EjZ&^<2Im}^}60^y*Hgq@F)-}Cb7^~y$6{C|>T1pqRk zQY-xYMmV&dBDVb|;^+Ir2|Xj)o4uOxRk>Cod`BQn4&r>=(!q2ZzVJ5tj5bqh-RBBV z-5;b4h|Tq5k;uBPas_TJ!_Dp5k}$OI7y9#d90tBoL(&_LP;SUT<77*OQcGAGAM-8n z^qp?xw5!v;T|ROARClhTm|P~<3#S-br6^*4Agod+(DJaJx5x}rAKcdFSP*&_NBQIo z-jfxsR*$jPexAy(GQ+K4m@Tz^bP+a}J6( z#(2l_GV-%p`2rtq*{i$|JkcI@ujf->phT{rG01RR?Yt{(w9!Y(y(rsON!aHE1hc!CqHcc%Y|ENyBUv$Hbd=fn*$jq?jhOG4 zxAu>_L`Dxdd|Pt`_%Qg*e^1&@u9J-onznLEt%|VS5W>`Pi|KeL?u!M01S`F8X=1z~ z!ARYec3(3o%A@Jk6IOA$i(1mmd-ciG-x*FNh;G{E$F0S{ABA@rd=_0*qGowFKw^^B z(od#hv2B?i`&|IW3uX$nSBLO;=)g%LF8d1Quuy)j1UqNOgQd? zen8mo;S&IjuYQiWh&kCp@bNEJMy!_J#@MN#4^qjMn2etVC2@m+NVm4M>5$t*%kbsg z5(GJlp=m~Wr+$W*Av_wz+>ze{R6hsqRt;tpUzxi;&(mAFjP@b6U9JAb!nJ4W7KcXRn6By8tN%o>$mf~SfmQ86Wg|i$G|9@@s@`--WLc8(W zvPOy2UM*Zz{no6(9jd8S!n}kFB4CAw_D}@62nZ_*VYtx&6EtY|G_qkNpnC}8ZxKd; z?xz8evy=Rakq}c7hFdk}Ratc^BkBR1zW)Gh<#*2kd|k%N^@}Qx5E;byUSf*V;pE)j zWCunc-Ie34xixB8>uHpsr%5t2R#Sh5Z1(#}eAwNWA$j58>P&q8@^ni@Je?JnAY zo~fk4Olx7N)H{!`sNYK-)_FlwmcL#_xAF(AY~EQ1KA&3GaWqKRehM&T zV}rjsA)d=+^|8VRISuS6e6EX_)nRr*?uve|wRCXb5I6P2fvav*Y6svbX3IEBF$j=AyS6bm}=ME4f50Rzibtm#Js*`Pw>PGc9A`{w`z?b9@dbd@&g*g; z_S5xOh{>nMjkOEX^|?k_YDhMl6a%kV=fS*UmYcC*{_1Euq-Z(c+$Z7-e9oKs_wcKv zqOz;x#67tRd93Gr&bN*PV%wnW0%6IzDDrq21hJ0A#*q8!YStF@oQrM>{r!T6%VFdn zU`0JKqXRBIRI|YNXStGUB;c*>R2|yOM!taJ7X@nUWFVX=ufuE%GeMXuoP|nHunfynQ`j2;mwl&WzPS4J3<3prLyPbGHEzz`3-ixE7stE@{=b;LbZ#tJ-Db z?6vcjc~d{#(N6#NyepSQF`mFDoXNPV*rlcnn&C})8Oq}Q(l$cOc^v4Fc$ZM^f&Cg3 zg3Zc!_2@+~oBlat7(V-zq)@W8yF%RK!&5zh$&cCvIbXB3bALF>?<++Jl5R|L=?UHt zS(?IY%me%_Iy!QfSha+Mrh-&<3<16#!h88hXGa0evwr6YLFjROY|Z(I94qveXE}%6 zphaPVczk_tXlyR=b_qR_mloNYJ)>QJYZ|16SNu9+C;TqjMkgu?wr=+GO~dx%TK`V4QH4PDf$kRfN0mMF2vNSxU z3aA$SC`KDyQ`(L!2f`URv>dAt@KxQt1x`aNpLg`h8%0rAHcAG zRD3*H3o+V*{dq-ls`?6ArDvn@`^P>;&6eK|7JzFcupx-n2bzIhZ@^WPa2r=1coLCh zrIbKH(6x6%&m@c4)0S_pzwmC3O2esFk&8nl>8i{dy(mfWV_wH5$lD9-I7zvL_nMa2 zSL6h|*_eok1O4dCJ10PxAzw4pOrhpmRke)gU=-+szGgRA(3xy~srp$Fwz*M}gIMFM zL*x=H5=K|JmzDcZqs+T$a&MgEb=W9!EM+@;SX$d6TXDOXi+o>bGT)>H5P*My7Dv_G zEP0VH5UGfEvyPx;04YG)PeB&#Q@|33F`>f419E9YtG{FtJ2Md$Qr|-qrV%8RgKU$c z&2qajY3`IIN4H6&_vf=Lx>zI`cjji|IV)`P@ZQvst0_Jm{I#W+yWfKp8I+7X z8WhU$wdWW(ZlB_7_d!^ZN=wpeT-vQolLKyB7Q32jyMs0|d zO~~8Ec4JCsPOY8sWLnYH5piqK1Lc71(K_*9*6ZAxNrAs-b&_M zf$MW+=?HhcX+@Xeb{gMZfQk1!SCIhpX5w+*g+3T-N3hRtA7SPU$LB#)9~G1QS%`7c zlW12kMC>u+a%Bl@=8r{|kNe^+u|hVLrR!HqALx9CE(4$~r6lG}P9Q@EoetFO2=QG- z`>jFm2#)$`CUC~_yTgHsBH6cTj zOrK!^gNnRsb*x~Iz3X@IX1e_%^0#EcSB|xo55QjsUN_C`BMu45AGFH>;H@?1LlV9B zpTmm)M`@p-D0NeZqRq2pml4fWBpAao8B?Dk9y z*l*Ss!OPLnO3WE}h5<=vbeX*RftCt)K!b{eSJvCBQp`CO?{*i0rIA(N+>YNPz(Kd8 z6z1uwIOW|)92%tKjDrNQXyI5-Do`{>!_dKNkfK7I<9N)5cUn>H1r~W0Atd{cDt}Ts z4ERF_Z;I1JXL6Um{PFMT8mD%>SJN_-I!TI3T{=f?6)8!~p| ztMX+NB!3nnx-kNIlx8pkmT&kO{>gaz$Reae4iBAbjvCwm{Kn9YbmHu~4ws{IQYZFy zCJg&hTYf|hn8GbdHh^^OJV6+!S@oWUBPn*Sb@W6y5KAN(NL-aIsm&685FZc_=dC%M zI7^PBGEDXL=9=+1`B^yf?)cfNmFzI{6(LffBv5Q(H+`pm8wXF|foYnRYHAsr$zjFI zgM8nT_0~m)!DFQh6`^Rh8-+ww@+7gWUB|NC?B;|d;&(2gQgBS**0`PP<0hvz$c$%e z!tx@%WBP~Ab&iVDmJDeeI9fmX4>gT#f7=oaIRcGQ3UTNY}?(c%s+xpp__Yd@ReD- z>&pp-7>4Npn#F3%l$-XhqNThIpUj|TXF;_qRpKWHc*jDz8e>n-3shocU$`9R9qDj~ zs+Q278I1%54aSUq)`3be6Ci3~dFH6^xy|j)8ovTOSsB2b(+Zm9HOs?UNx0OVE4||+ zG5&-z1wXw=XxBSUfYHsl1xtP+zz=BKie(A*=@Yh2^Hr~bfj;Qw0tc)Ykv(vna#98? z26^$(?!Q07U~}Lv2{ek8N2G`1YLByl_iFJgQxI=|6&iK0-PQ=W+x|&LOf(69>rxs& z`vEPFfJ8MShGXzu8LVe=Y!mq{mQ zqJZ9|xuh>lH$%)nCl4J0r8i#}=pq+XMw!@k?HKPX@GC6CkGdMmUm~_0I)E6!Z}VDX zi1sABej$}7$x_{ifL^vzRGPel{Aq?ngmK(aZ zK=Mbwder7U(Bt_6<9q(3mATO-Y$o$Km@xkh*#xj|_+28ebWKSJ@Oif6I|BDaVxxq{ zcTv)5mB64@ir5W+6t|MNFwpqDg>PCAy@$|k^CYWxgr|RPc7f)GBWl(;dhYjPkOzrs zix^vDa*)O*=~@`I3bXfbh%qOi$1MUlIOqp|Eu|cn67&NOSnD4WI$0|sQ4Dy;7=UPQ9Ke!Z>)=GyxmkVWX!N}XfovuU)a<)6!d}Ry;afSQ2%N{4X z>0D1i^nDIyG}uW0)7mPN96cOM^fp$O@kOpMX?ds~m6iX#6{Bueex#A42fA6d-Nf0r{0>Ppcg4C=nQI#K- z14K+Q_4 zE{kkd;cc2fE15_2oYOYmh5=9bpl3U-tmtNl1k`^OGq_5YWTp;1`2GEs;D?He3sEWI zMf5~p;o2YlBw$+loA*%tQ)z{DPeD@K#y=jnRjcLtf})^O^FAAzw}Qe-YR~P~CMLl@2k3hP_il$}pYi8SZtQn4(0z^a2Xnc-wG6B4 zo#F8P%75Bn3F8~=p8kHkS$+dq) zjJz06_td;<`_I#2*I#RU?nRZdAq-ji6 zfYL4?HlrR0WwRwv?n*a|mwuuWck5%E8$^>Q*bojx@}(Tie)2OwA)O*O>J;>Cx`#Ap zwNK-q{Z|CuTF0+W_7kj>zLKx9XcnkL`tX&rco@;r8^`MwgcP`bezk1rl%oN5+Q8%X za{NL-1AZTmU{AwGok|RdlarYZ&?DBVPcQKl_f0q`%6Bm{ z?mE_|EQGUDH_Lp zY|Zqz9k*&+z41cZY2Tr*SG94&s4Ia~leV|Vh~6f8`JF#)_XNdspR$({-i}dk?p$?n zzyC7&ngj2LN?X;6+pWBn3-$6%Os^UVPH=ibx~%xp`>a_CMKVK_UHqP1mR>X0H`C{e zh#t?QBZIDdbyp=fl1S;@1}Y9V{a!7XbXh(LBCqk1Kn0##R8Sk30I3+oLP-SCGDCUy ze0HjY#5b{m1vr^iH{dGwSgR)^{iV%IOX`uodI>4-YUVfRsnsbFx2}LMRp$ah=JA+UKtTLe(iv^VP=Mj7H zL9&sT6%TGt{PT8_6Pofv;-Bl|P7T@WCch%x-lc!$6hYtoqjIo)wV7$@*wwA0L}ck`U{#C{u*mEBI1`^uY5o}Po`9VHTDSJc z1=4u~BX%LQa3Wp1PKY}zhr^SSCxabqM!XY(kMlxR&_xI-b=S|&B8ODK02#8LVx}3o zCv8~4?Y|0{oQ4znErog%=fCr=1Q(4okShFeJ2$65R)_W4zca0n0n}9CP zlmwmFiZzw8KrvM%+l|Xi0Abjj$zF*Hk?RTsuc{#d)ah(T5PR#0_pW`h+I3*D^hoNo zEk6+-1L4+~?-3Zw+Nq?A1Z!ckUq zmW1tz-+fH3J_L2(V91#lOiDrlHj2?7esX71x@B6$p(S`$_!|duW{{!tN`i`82E&Q?-oA3f_^n6 zJ<*oQ{cs0wXA<1q%4U(qwpT|X?fx$Yy2iv+dFAOUOkk-gyADZn1t=)3flWh6YBJxC zBK&u^EUK`Cjt_j|7Rpas7*!%@)Y~~O_sYq%=qrpKb|ICttUlAOZEG#^dqZwfO>z$%q!&L(B zsZq}_HLMk#p*KH|TI!k_2zjLi-D2;Ipjz=r)32u&qb_W>b|*DBi!??8(6PKomF#Wk znIS9bJ))k5b;d&~@m#nHb*ro&l^e4W$0sJ1RuZU{1ijzBQ?+T&GQnwczz$g!4;+XE z*38yD-7BQOPty6%rcW0NA(}$LSNcdV{MeNW#COtw*}Y;S93$LUVlS?&S(fyO`7k1W zD&o6s_Ekb^66rnMD^W|ymHsC z@Kl_VqruEokB_CpfK$rD{S!xM`GH67p#waj_C=HsEhIlL9*8`W3{8=$z^k0C%96bk z_Ae&vj{~C1z3(eYO?E%Ui@k`l@P5TfbM>t30D+`q2V=%F!G5 zMQ0%PeK3Ah@1Nr*Gd!ww(Dz5Uv;SGl2Q$@BT`ZW#o-ic{YV!pr4EY*L@mX-U4d z#=01KY900hBb_aZ4$Q3Doix z-!J`ANmF?ioQ+GW$O~ z#hZKt(z(;nS9Zo4>$GzQ9haBNOkLV;&cgP{=Q26?mIkNad!TVrQLhN1XW?%R=BGnu+2)#&h)QS!$5R05$ z`y?s{!i8A41A$lt?39iB2!GrqWMIiBeHk*eZO=6}3|A!shQksxlLyv`x1RJPuA;YT z`Iw#|4J^rsEVpkPEbQc??+o~e;)AIJetF3@>&&3_chUbQ_;P_|;R-+aR`FKJ(1B1g z1`U=b*Kpi>w#<49r(D)JJ-q<)A9e&gjzyZl;AdzJ@|hbq)jjNyW8y)F|Fp)jTJU6U zXSsjtuAInZ^M7bx-cJT~=vCNewj7|?@Y3=RyH8cYP7G?%<)J67X4L2F(C?D}|Kto8 z>p`%?&0zw8y)gp)8NmXyn<%`tjq*!S#m{4Z7NadR@rMhevw%;~NN5U$N`oG&EWAL; z-E`!~W(x1K22Ph9*jgxOz{;iTTl@)VAI;bNPI`|GJJ<-MV9-{Bycrb``D16E9*e8+ z?Y@?@39#kLSHZ*(zAY%fcl1IQTop+JwVIzlopa(Ow*v&HBvwM_6zCn~%asaaj_v{- z$-1i7nd^!>G!v2*XHcDd8E5L#dh>@2C@U#?CQ?XH6H$IdICQ0MD>v> zZ`2ep-}5zhkh{$bUeQ04}_A=hyrTbkS92V{_x6zH?{m& zpCT)i{jDt!RM~g|wx-^ToC~m*^4{B{;7Itye)XIPnKN;DJlmxiB=vW4W}F9n@=WKu z)S907m0y1{%!1^!({^F*3R5XcN2s}BwH6)NX*6ex#}|C=dr}o8EkWvkE17Nwcz9i@ zW7A(&4DfkxA!# zn`mhU1d>+wd2rjeP0!&D4r!HJn)uV?fOZf;?ZUg5-vMkF${VYMIzVQ<1HO=IjKw=* zgd2WGvt04fpQo&}dltZ!RQx2m!_;uRs`!73)*}YYbn}x{C&qiCEhW<`Jb?>oSY*oH z@wD*cg+@_}e3o5YR}7TOTFlCK_6FdKxSVx3G+?_vT!0c$59YR~S-PiyX>4-orc#-u zle$Ra$zCn{?NnZrpA#?G*iY`DS0Jk$Zp?T(Myw=pp>=c5L}fiU*XXU+h$1)#ty|u@ zLMBrga4|Hs5aT%81JB5Y2Z~N;lFEgMd}4 zDLi3fWHXQ6KVPR2i>lD=8;~_IYSg)&+nwh%LQ$*y>eVJXcn4|?EzzFHS25|Df!9|q zdFG}z8?xmUu_jKt4R?8MSda9Q&u^5!dT)Cnm?kJyf1-`kZ}I&DF}JU8o9NuVaiQ;@ zy+j=jb-A%hHX!FFDUg_ege3wi4W0ssCw^)nc9BJonMN;;xPxRDHqQ6GV2gGO#Ps=DyCr z;upINbSnLjHaI4W#K!VPMA?`u5SD=RF=OWuK05^%KYsm-*hW$c7keBXYe2A=gV8gx z89V_*);A4ZDZc%ayzZgHwfY9EYI)vT8E;YK%_U;f+SlI$_EeuzZ~d+NO!TkpV;Nr~ zne7AE1F_IxD~UDVek@oO(SeaEFSTRl?Ej-VmtpP?QwA`LhLjRYl5(-#buGk`e)&+1 z4K3MdR#-fjnI?GoIKI)VZHq_2JW)g{UBPJc_~}V1%Z{-i7YOsBp2^D&+gUFQ{3!Xh zL0~d&gfbSW`sUx>%cEGDJ@V~dKGqlQoJ~3060BP#A^Z9jzD<5+_DRLLT{2vtxs+nO z*&>AX)@l9z^HTpVL%g!|!76XV*Uk0g3bx_729m>g8(v($dIGHKC7FKe1SQt$x#jjX zA>QNak+zqZ>lr-S2<$SVKXl&agC|Fg3p>A(_hDw0GivywWq7>LxeHl4zQG=6ng9UJ zgW*eha32&;H;+EJ<{&ABRWe3WlG=gz@9rXMuibij7%HjCE7%I(xIy_53|%TBpv^=) zyTqac&ya}riio~cU`dqA$YSyuRy!F384!<#VLmjlA>Zy8>GUz-`sp|>MCG#WS>@jA zOEWVS89lWI?YC5(l$+b8jn*S}{&C{HVpUk~692)?1{SkPxd|Zn7}0ysKx@GMJ5$c} z1NGOqNZqy0@JQ2-|6k?od~%Kq+tiEmrK_?5&s|017cLKwv^AdDDmSX6&-ckymhk>< zSg!xWDclt!wI%-h;tUa38U%x@ltI`79BJxnrYq5zik*I9iFxHM!7eiLkg$~x1Lie& z&x?xQ3KY4F6PzI`+~}1)C~Ll439ue~8F8Idz^Rqd@k zKbbQ-R81Ew8=8I+U3Z0TaWw}BB@K7pGl;cfv}E^t#Mb9UMdD#^ou7akjgm7G$fYX4 ze|_-2iSD-KysI%EHQ0PdmVkEya*YVsn7qz!q#1`Zvsb$YX!;vpSH!0oyS&0@F5qzN zaDmHX6}^+R&~zIcN_H*4osqrWk+L^GpnVHOPW!tmy>~iw+p{J87QDPQc3(P44A^wN zN6JHs8-&+LIZ83afGcT#G8~hd|K74_AM3$D&Qz~5>w1UT%ef0kIbQQ`Zqz|i*P_@yP*rfF7GL+ zEeMhDP8r0u+b!5`V0fX3o|H%<*xkrjl(YBZrOUlA87uRoa5`73MfL3R)}O@`PkcE} z)!Sj8i^F=?mx}TEEd4&*ZTViN7}mG_L$}Lxmsp`!r=%O4$@U63uP1XF0ux3##&(ed zwNv2aRwRBnmfg>v_c?h$THOx7-$)%8N4~wBmE&{~@r4-?iUF4FHlsCmuKDk=oNZ6g z1Q|tVFLS#_;7osk9N3cm#D!MB`}Y0lXv4LvF`*Tk-VUfw(Dk5fzmxDkFM(-*oFl$D zQR^t4)S04_X2mumP;`E82ZpRnN~FvIOfFX*Z0n);P3Fmv$bmOTd;9rduILfu$>YdV zFu%&guUXvqTj2#AZjJNkBS|+#887K;2-}~tOxcZJVkZ7VJ*TCTKvGy!fD)5`Yr?I7 z$sH9l4(9XF|5L;g10a`~k|Z@)++I7silJ;dhJczqEdR;-Duj`pp&i{dcDrEj`+WKYMbw17E$}=81{PKC1m+w!1ePn?s+RQLV`t zNJxkio_%&8IUhlkoHvGf9j5;7XL-7{KSYlU@@7+(owdNOl!7Du5JNc42u0&csET?O zZ2+fy`sx<9(+W>BnmN)uIPc->tl#iFt`}#V(vWTs^^L&>ja5+j_I7HWSxbBQ{YT`^ zn+_%~E*2{fh(d-!pt2*lte%nPfF4K-2rZ0j6cvt2>QiMfNZlzjciU$54r)ckR$@eO zufaL5;{5!Cb_nsecDal8slKrtpT@-5(FA0szyJ+r`e0_T~DSWq2Sq6q&lzR?sB79~aF$G0w^0M{=Zj2Z* z7&Qh1yfYCam8xm@e42}sg>j&5Jfa|h2ikI?Um2GghF)I=O%3vW|0+v!GlH$^oe z#|9_VGB75NEG4`GG#wvC-oCDouE6nTLP-cezIvFASAJ|O(HP)y@JbM_1o zhD68RtBr;!;M-llC;H)J22Q5+o|A2LR#U6klK3gu$fS!LRN8t0A&&mchTToX-9aXK zPgQ|O^AG~{^6v{?tNm{BtJbF8pm&~L)y7ASNu7+bIfaS~Wb2;XV0^98blx60ib-BZ z?T2g7bu$=3>L*0#Pq0CB`Wm@KLvrLmXRM&!&%H6m>E^8}*)`FKG0&RWhu~t?dd?$o zDos9@PTSw#jUrf-%oRI7_1_B~2S^@Fw`MBaMBs_JGe6CLRG9^&s=cMi?Q1Af9lY>S zl)=ReON=M7TNVltuKbLxSN9CP^94JhBh*7iXZ@7;^oL@E>UV#G)SlHvSBw2Ez^WQ7 z=kW^b8h$dIsCDW@BKtHjJQzzM?XB{2ARF~s`$Cd>2L$u2-Rz?g}cG=gZ zCJd=Z2Km!}_-Y;H!shfIC=XdSVfYd6LZ6x^sO@9PtT)96P|aWUWfMosH|>VvCw@{F_%Lv zGJmrgvb3rp(;_m=u;^%{uF+lP^W=!l#_00RiCOtdb@KvMnHtv;)yj8XdogiRkifhQ z+u9cn#-X+oea6evy2Izmk~?4Ne2-b3>g3@VFL?Eg5!!OhjH-!Sp}A@I&xxAA=Y{|p zRbM7gkkZk!)s7n@zl~;nJBxy&5ocIDO5?z@UVXYuT#(K^eSN^vw7XqckTji*^S`C-%C7H$mNJ!1{2I~Y=U8j_`mz(|I1}wplI<4-xJJO59@`VG8^^D=Fsxx zm+$1s?pu7=8@tzafXBm$eUOyd^ZW3Z>RHmZw|5`h{e&QSK}tu?d)=BQF%ek$>Y!<7 zv<9^BzdN+v(X*uEwYOkS#^K^!93S4bFr6Qfr30xQdj3;K`*o$%#3_Bp{Lk!UkbmMc zce^L=`)Y3cAE-@W@QhZ`NgToOeilmkJF$LU_B z;3AVbcRad0$cVmgIGB2gmmgyPp8jbYS?Pd-k4+$Nu)?GJipxwYo<6wU!uKt^f>xE} zl?l4$yfmPx^sjYJKOebM-#N{H{okl>YdB+o9jNZ46WLoTcf%JT6-7k%%n}1Fr!YW_ z-Bdb1M#5C#qJ7rtF|wSJA0tsn>;*w^`m7AY%zEqjsTiz;e{7@cF^tr7K-)gfbd$X)fDK4#L92^8%;;#P)=&`Iz#3RS&cd6J54{ZK?swQ6dasS=XDVmrHHQ ztnz^oz|1>DO5D?b^aBP+oZ?b`f0zF`j3ZtVtBJ$jf-@|+ss_>UGd>?F2+5*njlGJ$VHWOkyyu!{sbTbb@mOh=)=Sn6 z*=cAEFWjhKs**PHV^F5PBroh4S<;QGkXF>m05YP&KTi>Po#gt90iBw;kL>r!+TBtLua^ENyO<-D zCg&J$HfiO)Pkk;ewAp2-*$Q7X3`dm;#7H+7tSRz-oq|4DM(K6WDIBrfru40<+5~L+ z)<5$X!rLgkqzqv)FS(wlRs(w*_mY~q8%ZC5(vq$qzy%)u{(9E?7&An!hVnX(18k}C zRuWs#PaCjwQz?XUj&sR2K8&pVjosmhUO zM;QyT%4CE`hQWcr?9zu4Vxdlbi6uX^S(!t3bcJ)f#7wC8V*Z?Jyk zBOh77l3SY~Ry8IBsgbu6g!G@-$#^hL*7<*u%`4_hu)>Z40VUU4@ZwHCwjr~ph@sr? zDxl&rL12S&*`RpmO9Z&iULatLRF(r>w8_UTn?3S%5G3SuQG@+q@ZPJVh54RT)hSd4 zS@ZGH^(>yv2?Xv)_2&@F>rw&Mt=?Y!vm{Zy&Ds+tqyuk*V7X=Z_ibRrB=WMfa|nK~ z5b%JT_Ah^H)X1JZJi0RJn{=uYRZ}~6@ejB#{e|oT+Df7f+6KeU_TRZ>SFSpU zsSAuF>&|p&dpCNvV?at_^RFz#D)dzJ;F}>$Ii#TOwj%URxXK*GqyF=)ho3>B@$EpU zE+%BE(Wb%44zd5uP7d+(gucS@!aq+fegnK z{50I}LjO1f*Iqk{e#z*|cF4|TXj_Hm%4cU?6fYA_(-JYb=NR@_dg6w0pTLgv3_8{V zmC4nskgzfhlAWrv^PxL59T4_^Fp~LT?&U~djHvH^)fB-M$7U3X77x8ABos~pn>Mdh z!E4w)E*M2xBHppnS{K&K`+9J4;2RBR4gnt8rYegSxI5Aag1@XE_QIHO$DqZwY?~qu z;vpCfCJW-_B!|5xk@)btRT4E8_shUqyQN$Y?(_?dEAXtwTqjci;Fo?JpZYd6Vg#W4 zj^OM3_a4C#iZUIs0J~K(E@9N9k0GweZ{CtsSXfVA!4qGsLUhp*2=8DlD3xsis<}Y1 z*I}aJiwoXx1pb$=9LW~dcU0L3EG%%kPZoe9#kI*kZ+SPipW&i5;_4lc3zXAQ~RZBh2-d`N&Yrtre6=`c}xRtr&Fhz2XrKj!e|yc zk8?52RFga}cbL_0>-mA-*fi*fFzxh;(#H!4GBtT1md45j(>{fDcw82EUNJIu5TwaH zva>B9%XDFBcj6nqhb`Obd_G`C4MIqlSMgjRDjzBFm?Q7)6D$nTqe9`YwqAyDNw}Or zs&XdwjH>4PU~T@yhB&D(dd%Yo2KsZ}p}Rm5y{`^OJWCs%_s^r)PjRuz2_2nKs(k^f zuQ64NI?G}zYGF;pFkg9%+qHM_j(9=M1dQ$Q)J1b}Q-mhrSN#7hki0IVi<53-b3S~N zJx2Ao;z*xK&zD}o^hgBg-Imf0`2p=@fiWo~$U;Q?Q#{KsE;2IJnXm6Vz#m^*FTMbg z^g!Dr%Fa)331i~JanC*@5Qp~oj(2B1(UPeiNo;P(@;l0Qaa)9vUTe4q^OF@fvDKEd zFJRS@wf48VZ+Q4SCwIvgR~Z*$&~BJPTOU{_7Zr?6et58jhkL6Mf*3_^BN02Yc_HJ= zo{`fIk%?#seBgtL&pPrJFt7-SC%ZvC^}>^qsLQh+P%hr`*m(@2!Ap zNIGOHqk^<+NAS3{YyPb;9s3HhkASYRdrZYF3~9@IPv2sx-&*8C@#~fOSpc4Jtyf@P zd64Jz`US=Y&IdLm2~_W0nU1o`qZ;-OQ1kfHY5vUV*_EC3mvm4*G=|Bd**89j5Si8! zd=#*?HxLS33QPQG$XZTw(am&|EAfmEDVCRa?=u_YWT1;%RvdRBUpS0eGB%L=89@&)ZB*Kd5{ zp2O|*u6o^q4`HzB;OpCgO~f%{XdP6Iwx3`R^>bDg!1zhL%_(|(d^5*12Aw-O0~#W>(>zJ$sb@9klQ z1%x>dnR1J}P+NuJLpD4#xKFXZ9)#wh#Q5GQETvYE_#f%iqIf~X<U_WSEVP;m+6| zZJ(XN9_WF!@(vp*Zg~XGIK>)W3}}>5C&-T6ttbg^c2>xOG|8z2?D;~3zrycA%Kv{* zEda8~oi)RX1UYHS!!}SPPsiX~!g5jWT>cC;19}i*gK4PKx3lJTxsNSw^*eNY_gVO( z$h>4H7v8u&z3rmNopL;0sc5vY?BdA^`i%+*Jz*eK`$_?q6@@k%@G<`=s*;n7NmyJ+@6i{DtFfeGR7ezl$xhfcH-PUs|AAABH(;D z)LGig9g!+Cz<+M>LGPxD%5h{Q44X4sY*CJEY&r`p{zztVN7rT7s#SC~B8ia@)GS{U z1}GIq3VbJ>p;|L&KrMQxdjw}6`sue3;9I`mLvY-(S7X(3}jm=h|-Zc>}riwkDQ z9@5i1hFf+XGD$_OY7^pJyVOFLu1Sy(r07) zG0~1BNS3bftobho?^u{{W85=OTkJ?Yu3mwVRb?AB{P=i4!`UN8)a_p~VMv?o#V@yu zn5*TuYgGpHc^a!mVCC=2j(p#4`H^hdW*<#>ed3W)(O$(}^(^PIG}V9a^KrziOWWp` z+m^WV)H;JMUyONd`#)EzeQ4djP0omOrv|S}vZvh-T_>*Dy|>(%e0%bziaIOx!PPq} zq}VuPL(Bs^_Kuu1_DkuY1c9HL#MybO^UNF>0-s;moN(c9)i&lTGwQ&=4hbiO%b)Mu zl}Cf7PwcU{f3&_g!WH@$Z)V(Z9YeB4Zj*W1i=cPi&mO)0c4zqh(Zfcx>Yt!TvKm`+ zW=od%&uOK%b{u+P#>(bP#s{n$`orsVOFAqG`(@AiH!rq#E%DpJANOa!(BXLc&@2~o z4NZ9Sr*>;*1=nbp`SGOSZCmCOC_HD|OEo=Se11g^zm}*P;_Nl5hm>e(jiGEWgGvvoTX%$TfVk-FcK#a{4f<=vaH`=_0Kadg}BBQm9V(5+Ovogt<3HJvg2YPl_) zPE0TI)1Lj=e?7Dz?AEF7t&5N7({oas@G-s|?)^CCs7u*5tT=L``=UHK4$SRSCVI{E zjiUxGpEc}8#(AX&&Yv)L!L3VmV#fYBaDUy6*WR~3l4A1aoL4>{&rs~fuHWK@)ouTK z{P7P1zhpQywotLFS3^$Bc@R)CL7@VPx{tisJ9VdQNw4OO*eI}k&!mT<%}7%#Mqt!- zLvO#x`+jlXkiiY_&u=om)qsxg{%pN-NwgYmn|8}q>Ughale30zf3m>$R~ObRTA}=% zCs|uX$Tzuds#ohjH~7}8!Pc8|mZVLU@p$`2FPAQVa<}ED&5H&VxRNS&j`-ELr|;Q5 zU7mIGz7%gzqsqRIhw={{96V%9ttKs~FH`0Iq zZ;4^KX59!G*85V^f^Vj0joh@;;^!4#Kg@kA$(J7z4V+Z_V!0D(OBMS5>Dau7_I)Y7 zW%j!37xsKRQ#<#)YbiSH>~v{ni{R*|2d7OLHX`HJ_ydj)Xw$ykyT~7>TImo;f=AmnIF?yjom8&ijBN1E*kB`>G;`k>3@GxIH=BzX*b4w zzP z-e`9%!NOnmuN?9;UC@p`HCyeQGjQe6MWx@@C~;)w#tv&*mLBtY{qI*d#w}c_(WKc^ zGE5Fz7bpGNzGH^Ri=HodRo?XVdw&|gv;O3jqlTqBcd)mCmRv6wbw7~f`7qTyG`ReyF?e8w_)b{VWWxKR4k$>*$ID1Yk z%U7jX>_W98?%nrh{pbg02S;lkW8sx09a=;=n?In^f_kUx+-bS9eeEqJ59T<3ufmxO z%8-4k^Im>!qYS{4Nzm=kwnKHOm*!8G2>;L%RUCK6dR{nYI;I-+uhY$T2 zb8Y7Ny(<0up=7woe;p{DtzU-yDzd!a)Rj91)fv7$ zMb2KEK2#o%u37ZD0Y#gPOg!Larv$lbH|sumf7-)ohxFbR7|?e}%NAX-oLZH8>V&Kn zZ_jBIns#25%f~1G_+)T`)Wu6|o-+AajJ+d9?Y+G!{J!5$#4ML*$c0?#g2s&f zOR^VuB;{1R!)%ixmRCe=JPyx-20gCF;J5v|PT#Jg7~d{w^n>5KELh9z!3 zINRTIgZ@k(dbo4e1* zuFO)ZYu%Fpy{gT+zp{DPLVKS_tT%ekq|gs{TFshw`2M+M8K+nLCGoBVo3`#e(Rt0T z3vbRGxHR+1wNaVcpI*_h&!hFr@*bHstLCwV6CRh3{qV-mcaIi)J-1Kn0^l@Yh%{Zeyhx^uG!pE)wPe2=I1 z7OgvZV#tMSC9B0%k z+va!_GiJW5wHxFcKB(uYD}8CTjSqqt2|$k-Omi zeQ!TU%zvbQrahmEwAnMQa_=EO=Lmin6k~FC%NMtJ^p;1Cy$#8Juy*wfMS6Al zerJr_JKu(lX|y-))T6ZyrdyTcmnUTIHN|V~-j*tJ(tgcfHCq1i{BKheUyRr`OX#?hHQPr#z5n;z&BDTd zj5j~Wi5?wGz1Y$%OWhMGN_AMa@Yufh%{m_#9`br|uk~l<9lKUALE(c*)-|b;y5s1G zNjjf6I^y}$2OT2ctGeJt?UH?x9BDmeXQ^F%D$d$d@$tV)56^tlwfUFlp9YlO*CF@A z{Am`w>9Xq8+5-pkZaxyX&dBE9UN34FR<`o&zqW2GwPR@98&UV}T$CdBKL;1jeEi|| z%bQg`rbzvvNtcCxZb|n2rRmWpr+syKV4jPm{w|ayUGu;!2lj8A`S8%@ObgC+cr<=? z?lZF@rMukq{kTgxLn2n)U-gf(xszr)cQaGOE8QZeZ2$e|Jgfe_+CFxKD!q>+i?{sU zilz@rx4qgs;`n8A8;$B%wC1DlpG@ttaKMaK4Z2Mj+T~WZCnYb1bd6WCSAw-Qj{VsA z)#m5lqD&cjbk2@U6W*oDO2Y)L1YQf^O9hN*D zo2Fmu+EFJRPg-JU&xe^}RSA4}ux42K1^EJEm;U?2_MUf+y_ofEUg+U2qw6ZAH08MLy}`R^Uiw`63`(2AD1d`P8y|ChV_NxZT#nt454+KJ*zkP z@5|BpwCNN1)uYKdw-+hYXZh2lkGc;1k|U%`lzdg*4nDW1V7yar>Wm9mv^`0oz-~io z&8@qt{q3v8FGj0X;pc|glMkKpy4ju2sVe4aFk@WD2~9>VuGVnJ#~mfhw5?vPUEyw{ z`P3q)( zSt4nKXwRY~_^V-1&&8)(Kh8b2XWKg+%lz3dxY3?csoq!qR+5%pvju7TO##6on`)trFkZmd|o?j;owr$58lq*{HN6KY7_{pnkcaMpZixW z9GZ7y$7Ks&&&!t~dil^3za}62pw686gK{J-7eCGIBH;(ktCBFr#A`oYX_&tI;!m+k zRT_FOdYOyyy53DvJGeqX`Jl&nr;lryt7eo>A4_Z-S}J?^iosc{H%ys+_L*JJg99Sp zY?1zSjUw0nh&F!x%B{av4_nk^?5ovl3U7H9Iq&L5k&A!dCBfEe`68st)pK#RfU%kO zeN8=ec;~gLU)G({bjJD>g&*dqJ2qD77>%o@?C@aO?IfEDH2gN?zrP0Cr&;mozgHVQ z@~z90WOSWz4}(|zJ~L|K@58or9$e?i@%`P_RgW}r$NBAVBftOr{MVza3Wq#xnB#h# zJ^l8-E!1J=ttIcC?k$qA`K~GFuhcu&YS8CVkv~_8J^ESWO8v^-8U1xzmKXnSTlRO9 z6A50Ni%@@cw}p+4#d^8tRQth$8dQvwYx9s+)t60+SZGbvfUxDu-o>exrSzUFr(gcE zwqL~LH@5Aqus`|f*ITY7t^fMSm$0avzrTF<@7Skn3|~4U&W&)lKhHZ`=7(N)Qg8ir z!>g3L(o`<|ton_bKlNK$IIwl%&iB{UT#&uvFSUx^emFbN)NBK1b_lni(UjjiWUZg~ z$mR}FqWtnT$-gfHtL5EYG0)_2xyl}UHf&v{!F@)?|5#{r-qH1DEv&ZipIUiZr|CC6 z@$a9~gncbj{z&E$_4mh|H!w!MR6VjsUo`%w8$TzS(0$C7le6dcy_w^;tVyqYEx31D z-Tt4K7fc&DdD8^{HqTjQQ>>tbfv0~9fBH+-Ej6Q+eUhwMk~Gf?BrF^0^ND=l9t}B{ zFZ-OG85(aK+HicFgtaDps(JK8v@1^vtcm?KB;4lvzb>wju~gd3{gy=9^-Jz~v8S&X zm$uc@&i}kw+2rQfP3^9IUOW3p=L+2h4j8d}Ptqg5-cGkK{=gQup47jeFlYO24fbX# zbZXYfA3BX#(QEDQfgc)Y{qx<7R$ZT$n3JgOf@_cJXWO!DNP}BVde>=DvqPGNe@r}d z_}7>-$_`#o;qBKViwe(aysGwP<3;_87RD-YdB z-f91l1E&VG>GNZw5*<%R9G`Xgi!qa5UwArh(cWd{%6*LTyg}HQ>eg?u=P>PMLULP4NVcddY$nlV>g}sG`M#7Z6#jzX`CiT^YI(&ZcP0l zcllZ~%O!gfe^CDI_41~_zH3#@TBnb;|MV(-<+^=(rU<|O;@&R{(_ajqdTy0PGs}-Z z6kPag@t9frEO@zg<*G}?1~+;b^YVw);Trw^sQK;-AM^GK8<8$~l}Rc8{4k=y=XXCh zyB3tM$cSSJGvCGid#aWm#S-;vzCJa40C~MRO>3ZBe zI^p5KpbOb|L~WDy?4TFh?~aHcu3-I;Uu&#b9T>1UVo;)VPx>SuvpFzvmHmekbV$4{ z__yG7-LB6M_wL9aniX2M201%ifAdF*9nDYO zDe<9EjeDsh7W-+{kWHOp9connyI9$>{oQ8K)|2H1tecj3=#J!hN`AkiXQEY|@BR4s zb>|9kn%*B+eeXQY{2yi|@I?Xu*IdFy1yJ#&xc zn17?e#^*`a*Ut6)O_XFmZY=)ypnnQC%vf>Bm+O-=HHy7E-jEM3ij}z#kR)?x$7kD5 z%| z$hBp!KHalr%%up`-XsYOJU22{)0@Mdol0D}-jr~a8ysnI?2m|hoA$porPc7*o1)e$ zoIL)V1OW#=-!4|@W7iG|J3bh``LBvsuNCNUb8@BZN#A`tb#Gyz(#f8^?R=&B!QJP2 zU(1*KbWn|2M?URI)u%$#oqwkLHnLIZmK#|rT}fML?wLRCUAwg_M$PDZT7B4mwt2T~ zt?xBi{33huSId{q_@`ygbKgDN*x_0H%inrs+Vtz9G>=ZTh?U{siku&E1yzhtHy~a} zly_2%T()7$v?kl4=7!?#r$>4pOwkJy~CR) zky~bK92EVRS7~;S8gXUc&{;(?#mt*7?TDZR>94oW+atlIbz9=C%XU0pnYbhWsz0Fp zl*Hv$=4+ekQ0@V%#uu9rxOl;o*nPX7+8I!`QnHzwzST(n-L2aB8|NyzcmMhDt;Vmu zU*puNhF6!o{jhsc#%vq1Qm z!3olY>mM;qxNsH2#YqruRMuDDCUqN8amkRNGEqaSR1Fs{O1S?` B3V{Fs diff --git a/pass-to-make-check.patch b/pass-to-make-check.patch deleted file mode 100644 index 3a3761e..0000000 --- a/pass-to-make-check.patch +++ /dev/null @@ -1,164 +0,0 @@ -From d597742733befe23034a87afad7d18ee36d01ceb Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 07:49:06 -0400 -Subject: [PATCH 18/28] pass to make check. - -With this patch, when running make check command, qemu passes to -compile. - -Signed-off-by: lixianglai ---- - hw/loongarch/apic.c | 4 ++-- - hw/loongarch/ioapic.c | 4 ++-- - hw/loongarch/iocsr.c | 20 ++++++++++++++++++-- - hw/loongarch/ipi.c | 4 ++-- - hw/loongarch/larch_3a.c | 3 --- - target/loongarch64/machine.c | 7 +++++++ - 6 files changed, 31 insertions(+), 11 deletions(-) - -diff --git a/hw/loongarch/apic.c b/hw/loongarch/apic.c -index d6ba2a2ce..67994d201 100644 ---- a/hw/loongarch/apic.c -+++ b/hw/loongarch/apic.c -@@ -64,7 +64,7 @@ static int ext_irq_pre_save(void *opaque) - struct kvm_loongarch_ls3a_extirq_state *kstate; - int ret, length, i, vcpuid; - #endif -- if (!kvm_irqchip_in_kernel()) { -+ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { - return 0; - } - #ifdef CONFIG_KVM -@@ -112,7 +112,7 @@ static int ext_irq_post_load(void *opaque, int version) - struct kvm_loongarch_ls3a_extirq_state *kstate; - int ret, length, i, vcpuid; - #endif -- if (!kvm_irqchip_in_kernel()) { -+ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { - return 0; - } - #ifdef CONFIG_KVM -diff --git a/hw/loongarch/ioapic.c b/hw/loongarch/ioapic.c -index 3de0ed88d..60abff855 100644 ---- a/hw/loongarch/ioapic.c -+++ b/hw/loongarch/ioapic.c -@@ -253,7 +253,7 @@ static int kvm_ls7a_pre_save(void *opaque) - struct ls7a_ioapic_state *state; - int ret, i, length; - -- if (!kvm_irqchip_in_kernel()) { -+ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { - return 0; - } - -@@ -297,7 +297,7 @@ static int kvm_ls7a_post_load(void *opaque, int version) - struct ls7a_ioapic_state *state; - int ret, i, length; - -- if (!kvm_irqchip_in_kernel()) { -+ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { - return 0; - } - length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct ls7a_ioapic_state); -diff --git a/hw/loongarch/iocsr.c b/hw/loongarch/iocsr.c -index 60daafd6e..13d356d80 100644 ---- a/hw/loongarch/iocsr.c -+++ b/hw/loongarch/iocsr.c -@@ -95,6 +95,11 @@ static int kvm_iocsr_pre_save(void *opaque) - IOCSRState *s = opaque; - struct kvm_iocsr_entry entry; - int i = 0; -+ -+ if ((!kvm_enabled())) { -+ return 0; -+ } -+ - for (i = 0; i < IOCSR_MAX; i++) { - entry.addr = iocsr_array[i]; - kvm_vm_ioctl(kvm_state, KVM_LOONGARCH_GET_IOCSR, &entry); -@@ -172,8 +177,19 @@ static void iocsr_instance_init(Object *obj) - { - IOCSRState *s = IOCSR(obj); - int i; -- LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); -- LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ LoongarchMachineState *lsms; -+ LoongarchMachineClass *lsmc; -+ Object *machine = qdev_get_machine(); -+ ObjectClass *mc = object_get_class(machine); -+ -+ -+ /* 'lams' should be initialized */ -+ if (!strcmp(MACHINE_CLASS(mc)->name, "none")) { -+ return; -+ } -+ -+ lsms = LoongarchMACHINE(machine); -+ lsmc = LoongarchMACHINE_GET_CLASS(lsms); - - init_vendor_cpuname((uint64_t *)&iocsr_init.iocsr_val[IOCSR_VENDOR], - (uint64_t *)&iocsr_init.iocsr_val[IOCSR_CPUNAME], -diff --git a/hw/loongarch/ipi.c b/hw/loongarch/ipi.c -index ade182abc..59186f1de 100644 ---- a/hw/loongarch/ipi.c -+++ b/hw/loongarch/ipi.c -@@ -25,7 +25,7 @@ static int gipi_pre_save(void *opaque) - int ret, i, j, length; - #endif - -- if (!kvm_irqchip_in_kernel()) { -+ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { - return 0; - } - -@@ -67,7 +67,7 @@ static int gipi_post_load(void *opaque, int version) - int ret, i, j, length; - #endif - -- if (!kvm_irqchip_in_kernel()) { -+ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { - return 0; - } - -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -index 6eaa53d74..f83bd3750 100644 ---- a/hw/loongarch/larch_3a.c -+++ b/hw/loongarch/larch_3a.c -@@ -1435,9 +1435,6 @@ static void ls3a5k_bios_init(LoongarchMachineState *lsms, - - if (kernel_filename) { - lsms->reset_info[0]->vector = load_kernel(); -- } else { -- error_report("Please specify at lease one of -bios and -kernel"); -- exit(1); - } - } - } -diff --git a/target/loongarch64/machine.c b/target/loongarch64/machine.c -index b69bca6a9..dea6a7034 100644 ---- a/target/loongarch64/machine.c -+++ b/target/loongarch64/machine.c -@@ -15,6 +15,10 @@ static int cpu_post_load(void *opaque, int version_id) - CPULOONGARCHState *env = &cpu->env; - int r = 0; - -+ if (!kvm_enabled()) { -+ return 0; -+ } -+ - #ifdef CONFIG_KVM - struct kvm_loongarch_vcpu_state vcpu_state; - int i; -@@ -48,6 +52,9 @@ static int cpu_pre_save(void *opaque) - LOONGARCHCPU *cpu = opaque; - struct kvm_loongarch_vcpu_state vcpu_state; - int i, r = 0; -+ if (!kvm_enabled()) { -+ return 0; -+ } - - r = kvm_vcpu_ioctl(CPU(cpu), KVM_LARCH_GET_VCPU_STATE, &vcpu_state); - if (r < 0) { --- -2.43.5 - diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 1bcc23b..57297f6 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -1,4 +1,3 @@ -%define anolis_release .0.1 %global SLOF_gittagdate 20191022 %global SLOF_gittagcommit 899d9883 @@ -11,10 +10,6 @@ %global have_kvm_setup 0 %global have_memlock_limits 0 -%global user_static 0 -%ifarch x86_64 -%global user_static 1 -%endif # Release candidate version tracking @@ -59,11 +54,7 @@ %ifarch aarch64 %global kvm_target aarch64 %endif -%ifarch loongarch64 - %global kvm_target loongarch64 - %global have_spice 1 - %global have_usbredir 1 -%endif + #Versions of various parts: %global requires_all_modules \ @@ -92,13 +83,13 @@ Obsoletes: %1-rhev <= %{epoch}:%{version}-%{release} Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 6.2.0 -Release: 53%{?rcrel}%{anolis_release}%{?dist} +Release: 53%{?rcrel}%{?dist}.2 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 15 License: GPLv2 and GPLv2+ and CC-BY Group: Development/Tools URL: http://www.qemu.org/ -ExclusiveArch: x86_64 %{power64} aarch64 s390x loongarch64 +ExclusiveArch: x86_64 %{power64} aarch64 s390x Source0: http://wiki.qemu.org/download/qemu-6.2.0.tar.xz @@ -124,15 +115,13 @@ Source30: kvm-s390x.conf Source31: kvm-x86.conf Source32: qemu-pr-helper.service Source33: qemu-pr-helper.socket -Source34: 81-kvm-anolis.rules +Source34: 81-kvm-rhel.rules Source35: udev-kvm-check.c Source36: README.tests Source37: tests_data_acpi_pc_SSDT.dimmpxm Source38: tests_data_acpi_q35_FACP.slic Source39: tests_data_acpi_q35_SSDT.dimmpxm Source40: tests_data_acpi_virt_SSDT.memhp -Source41: loongarch_bios.bin -Source42: loongarch_vars.bin Patch0001: 0001-redhat-Adding-slirp-to-the-exploded-tree.patch Patch0005: 0005-Initial-redhat-build.patch @@ -896,106 +885,12 @@ Patch361: kvm-nbd-server-Favor-qemu_aio_context-over-iohandler-con.patch Patch362: kvm-iotests-test-NBD-TLS-iothread.patch # For RHEL-52611 - CVE-2024-7409 virt:rhel/qemu-kvm: Denial of Service via Improper Synchronization in QEMU NBD Server During Socket Closure [rhel-8.10.z] Patch363: kvm-nbd-server-CVE-2024-7409-Avoid-use-after-free-when-c.patch - -Patch1000: kvm-virtiofsd-Adjust-limit-for-minor-version.patch - -Patch1001: 0001-Add-Acpi-support.patch -Patch1002: 0002-Support-rtc.patch -Patch1003: 0003-Add-loongarch-machine.patch -Patch1004: 0004-Add-target-loongarch64.patch -Patch1005: 0005-Add-linux-headers-and-linux-user.patch -Patch1006: 0006-Add-disas-gdb.patch -Patch1007: 0007-Modify-kvm-cpu-vga-qapi.patch -Patch1008: 0008-Modify-compile-script.patch -Patch1009: 0009-Add-loongarch64-rh-devices.mak.patch -Patch1010: Modify-smbios-option-lack-and-Modify-the-maximum-num.patch -Patch1011: rename-kvm_msr_buf-with-kvm_csr_buf.patch -Patch1012: code-cleanup-for-loongarch-kvm.patch -Patch1013: Support-TPM.patch -Patch1014: kvm-csr-save-and-restore-optimization.patch -Patch1015: address-space-code-cleanup-on-7A-virt-machine.patch -Patch1016: Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch -Patch1017: Support-vfio-config.patch -Patch1018: pass-to-make-check.patch -Patch1019: fixup-can-t-find-cpu-type.patch -Patch1020: fix-smbios-type4-info-for-numa-support.patch -Patch1021: Fix-smp.cores-value.patch -Patch1022: Add-lbt-support-for-kvm.patch -Patch1023: Modify-the-ioctl-command-of-kvm.patch -Patch1024: Add-usb-storage-config-for-loongarch.patch -Patch1025: Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch -Patch1026: Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch -Patch1027: Fix-LoongArch-KVM-header-macros.patch -Patch1028: Fixed-the-issue-where-qemu-specifies-the-boot-order.patch - -# CSV3 feature on Hygon hardware -Patch1030: 0001-anolis-csv-i386-add-CSV-context.patch -Patch1031: 0002-anolis-csv-i386-add-command-to-initialize-CSV-contex.patch -Patch1032: 0003-anolis-csv-i386-add-command-to-load-data-to-guest-me.patch -Patch1033: 0004-anolis-csv-i386-add-command-to-load-vmcb-to-guest-me.patch -Patch1034: 0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch -Patch1035: 0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch -Patch1036: 0007-anolis-target-i386-csv-load-initial-image-to-private.patch -Patch1037: 0008-anolis-vga-force-full-update-for-CSV-guest.patch -Patch1038: 1038-doc-update-AMD-SEV-to-include-Live-migration-flow.patch -Patch1039: 1039-migration.json-add-AMD-SEV-specific-migration-parame.patch -Patch1040: 1040-confidential-guest-support-introduce-ConfidentialGue.patch -Patch1041: 1041-target-i386-sev-provide-callback-to-setup-outgoing-c.patch -Patch1042: 1042-target-i386-sev-do-not-create-launch-context-for-an-.patch -Patch1043: 1043-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch -Patch1044: 1044-target-i386-sev-add-support-to-load-incoming-encrypt.patch -Patch1045: 1045-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch -Patch1046: 1046-migration-add-support-to-migrate-shared-regions-list.patch -Patch1047: 1047-migration-ram-add-support-to-send-encrypted-pages.patch -Patch1048: 1048-migration-ram-Force-encrypted-status-for-flash0-flas.patch -Patch1049: 1049-migration-for-SEV-live-migration-bump-downtime-limit.patch -Patch1050: 1050-i386-kvm-Add-support-for-MSR-filtering.patch -Patch1051: 1051-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch -Patch1052: 1052-anolis-migration-ram-Force-encrypted-status-for-VGA-.patch -Patch1053: 1053-anolis-target-i386-sev-Clear-shared_regions_list-whe.patch -Patch1054: 1054-anolis-migration-ram-Fix-calculation-of-gfn-correpon.patch -Patch1055: 1055-anolis-target-i386-csv-Move-is_hygon_cpu-to-header-f.patch -Patch1056: 1056-anolis-target-i386-csv-Read-cert-chain-from-file-whe.patch -Patch1057: 1057-anolis-target-i386-csv-add-support-to-queue-the-outg.patch -Patch1058: 1058-anolis-target-i386-csv-add-support-to-encrypt-the-ou.patch -Patch1059: 1059-anolis-target-i386-csv-add-support-to-queue-the-inco.patch -Patch1060: 1060-anolis-target-i386-csv-add-support-to-load-incoming-.patch -Patch1061: 1061-anolis-migration-ram-Accelerate-the-transmission-of-.patch -Patch1062: 1062-anolis-migration-ram-Accelerate-the-loading-of-CSV-g.patch -Patch1063: 1063-anolis-target-i386-csv-Add-support-for-migrate-VMSA-.patch -Patch1064: 1064-anolis-target-i386-get-set-migrate-GHCB-state.patch -Patch1065: 1065-anolis-target-i386-kvm-Return-resettable-when-emulat.patch -Patch1066: 1066-anolis-kvm-Add-support-for-CSV2-reboot.patch -Patch1067: 1067-anolis-vfio-only-map-shared-region-for-CSV-virtual-m.patch -Patch1068: 1068-anolis-linux-headers-update-kernel-headers-to-includ.patch -Patch1069: 1069-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch -Patch1070: 1070-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch -Patch1071: 1071-anolis-csv-i386-add-support-to-migrate-the-outgoing-.patch -Patch1072: 1072-anolis-csv-i386-add-support-to-migrate-the-incoming-.patch -Patch1073: 1073-anolis-target-i386-sev-Add-support-for-reuse-ASID-fo.patch -Patch1074: 1074-newfeature-support-vpsp.patch -Patch1075: 1075-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch -Patch1076: 1076-target-i386-Add-new-Hygon-Dharma-CPU-model.patch -Patch1077: 1077-target-i386-add-FSRM-to-TCG.patch -Patch1078: 1078-target-i386-add-FZRM-FSRS-FSRC.patch -Patch1079: 1079-i386-Add-new-CPU-model-SapphireRapids.patch -Patch1080: 1080-target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch -Patch1081: 1081-target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch -Patch1082: 1082-target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch -Patch1083: 1083-target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch -Patch1084: 1084-target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch -Patch1085: 1085-target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch -Patch1086: 1086-target-i386-Adjust-feature-level-according-to-FEAT_7.patch -Patch1087: 1087-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch -Patch1088: 1088-target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch -Patch1089: 1089-target-i386-Add-new-CPU-model-GraniteRapids.patch -Patch1090: 1090-target-i386-Add-support-for-AMX-COMPLEX-in-CPUID-enu.patch -Patch1091: 1091-target-i386-Add-new-CPU-model-SierraForest.patch -Patch1092: 1092-target-i386-Export-RFDS-bit-to-guests.patch -Patch1093: 1093-target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch -Patch1094: 1094-target-i386-Introduce-SapphireRapids-v3-to-add-missi.patch -Patch1095: 1095-ebpf-replace-deprecated-bpf_program__set_socket_filt.patch -Patch1096: 1096-target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch +# For RHEL-60553 - Frequent VM pauses on OpenShift Virtualization with Portworx storage +Patch364: kvm-block-move-bdrv_qiov_is_aligned-to-file-posix.patch +# For RHEL-60553 - Frequent VM pauses on OpenShift Virtualization with Portworx storage +Patch365: kvm-block-use-the-request-length-for-iov-alignment.patch +# For RHEL-26197 - virtiofsd --help and manpage does not agree on --thread-pool-size default value +Patch366: kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch BuildRequires: wget BuildRequires: rpm-build @@ -1105,10 +1000,6 @@ BuildRequires: pkgconfig(gbm) BuildRequires: perl-Test-Harness -%if %{user_static} -BuildRequires: glibc-static pcre-static glib2-static zlib-static -%endif - Requires: qemu-kvm-core = %{epoch}:%{version}-%{release} Requires: qemu-kvm-docs = %{epoch}:%{version}-%{release} %rhev_ma_conflicts qemu-kvm @@ -1189,7 +1080,7 @@ Requires(postun): systemd-units Requires: seabios-bin >= 1.10.2-1 Requires: sgabios-bin %endif -%ifnarch aarch64 s390x loongarch64 +%ifnarch aarch64 s390x Requires: seavgabios-bin >= 1.12.0-3 Requires: ipxe-roms-qemu >= 20170123-1 %endif @@ -1321,15 +1212,6 @@ This package provides usbredir support. %endif -%if %{user_static} -%package -n qemu-user-static -Summary: QEMU user mode emulation of qemu targets static build -%description -n qemu-user-static -This package provides the user mode emulation of qemu targets built as -static binaries -%endif - - %prep %setup -q -n qemu-%{version}%{?rcstr} # Remove slirp content in scratchbuilds because it's being applyed as a patch @@ -1337,9 +1219,6 @@ rm -fr slirp mkdir slirp %autopatch -p1 -cp %{SOURCE41} ./pc-bios/ -f -cp %{SOURCE42} ./pc-bios/ -f - %global qemu_kvm_build qemu_kvm_build mkdir -p %{qemu_kvm_build} @@ -1348,9 +1227,6 @@ cp -f %{SOURCE38} tests/data/acpi/q35/FACP.slic cp -f %{SOURCE39} tests/data/acpi/q35/SSDT.dimmpxm cp -f %{SOURCE40} tests/data/acpi/virt/SSDT.memhp -%global static_builddir static_builddir -mkdir -p %{static_builddir} - %build %global buildarch %{kvm_target}-softmmu @@ -1626,25 +1502,6 @@ gcc %{SOURCE35} $RPM_OPT_FLAGS $RPM_LD_FLAGS -o udev-kvm-check popd -%if %{user_static} -pushd %{static_builddir} -# add more targets here when necessary -%define static_targets aarch64-linux-user - -../configure \ - %{disable_everything} \ - --enable-docs \ - --enable-attr \ - --enable-tcg \ - --enable-linux-user \ - --target-list=%{static_targets} \ - --static - -make -j - -popd -%endif - %install pushd %{qemu_kvm_build} %define _udevdir %(pkg-config --variable=udevdir udev) @@ -1831,8 +1688,6 @@ rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/opensbi-riscv64-virt-fw_jump.bin rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/opensbi-riscv64-generic-fw_dynamic.* rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/qemu-nsis.bmp rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/npcm7xx_bootrom.bin -rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/loongarch_bios.bin -rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/loongarch_vars.bin rm -rf ${RPM_BUILD_ROOT}%{_libdir}/qemu-kvm/ui-spice-app.so @@ -1848,11 +1703,6 @@ rm -rf ${RPM_BUILD_ROOT}%{_mandir}/man1/virtfs-proxy-helper* rm -rf ${RPM_BUILD_ROOT}%{_libdir}/qemu-kvm/hw-s390x-virtio-gpu-ccw.so %endif -%ifarch loongarch64 - install -m 0644 pc-bios/loongarch_bios.bin $RPM_BUILD_ROOT%{_datadir}/%{name}/ - install -m 0644 pc-bios/loongarch_vars.bin $RPM_BUILD_ROOT%{_datadir}/%{name}/ -%endif - %ifnarch x86_64 rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/kvmvapic.bin rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/linuxboot.bin @@ -1953,27 +1803,11 @@ rm -rf $RPM_BUILD_ROOT%{qemudocdir}/specs popd -%if %{user_static} -# Install qemu-user-static -mkdir -p $RPM_BUILD_ROOT%{_bindir}/ -pushd %{static_builddir} -for src in qemu-*\.*; do - rm -rf $src -done - -for src in qemu-*; do - mv $src $RPM_BUILD_ROOT%{_bindir}/$(basename $src)-static -done -popd -%endif - %check -%ifnarch loongarch64 pushd %{qemu_kvm_build} echo "Testing qemu-kvm-build" export DIFF=diff; make check V=1 popd -%endif %post -n qemu-kvm-common %systemd_post ksm.service @@ -2068,7 +1902,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %{_unitdir}/ksmtuned.service %{_sbindir}/ksmtuned %{_udevdir}/udev-kvm-check -%{_udevrulesdir}/81-kvm-anolis.rules +%{_udevrulesdir}/81-kvm-rhel.rules %ghost %{_sysconfdir}/kvm %config(noreplace) %{_sysconfdir}/ksmtuned.conf %dir %{_sysconfdir}/%{name} @@ -2094,10 +1928,6 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %{_datadir}/%{name}/s390-ccw.img %{_datadir}/%{name}/s390-netboot.img %endif -%ifarch loongarch64 - %{_datadir}/%{name}/loongarch_bios.bin - %{_datadir}/%{name}/loongarch_vars.bin -%endif %ifnarch aarch64 s390x %{_datadir}/%{name}/vgabios.bin %{_datadir}/%{name}/vgabios-cirrus.bin @@ -2119,7 +1949,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %ifnarch s390x %{_libdir}/%{name}/hw-display-virtio-gpu-pci-gl.so %endif -%ifarch x86_64 %{power64} loongarch64 +%ifarch x86_64 %{power64} %{_libdir}/%{name}/hw-display-virtio-vga-gl.so %endif %{_libdir}/%{name}/accel-qtest-%{kvm_target}.so @@ -2212,7 +2042,7 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %{_libdir}/qemu-kvm/audio-spice.so %{_libdir}/qemu-kvm/ui-spice-core.so %{_libdir}/qemu-kvm/chardev-spice.so -%ifarch x86_64 loongarch64 +%ifarch x86_64 %{_libdir}/qemu-kvm/hw-display-qxl.so %endif %endif @@ -2228,51 +2058,18 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %{_libdir}/qemu-kvm/hw-usb-redirect.so %endif -%if %{user_static} -%files -n qemu-user-static -%{_bindir}/qemu-aarch64-static -%endif %changelog -* Wed Sep 25 2024 Jacob Wang - 6.2.0-53.0.1 -- Adjust limit for virtiofsd minor version -- Add loongarch supporti (lixianglai@loongson.cn) -- Add package qemu-user-static (fuyuan.wh@alibaba-inc.com) -- Modify-smbios-option-lack-and-Modify-the-maximum-num.patch (lixianglai@loongson.cn) -- rename-kvm_msr_buf-with-kvm_csr_buf.patch (lixianglai@loongson.cn) -- code-cleanup-for-loongarch-kvm.patch (lixianglai@loongson.cn) -- Support-TPM.patch (lixianglai@loongson.cn) -- kvm-csr-save-and-restore-optimization.patch (lixianglai@loongson.cn) -- address-space-code-cleanup-on-7A-virt-machine.patch (lixianglai@loongson.cn) -- Fix-irq-routing-and-fpu-option-to-compat-with-kernel.patch (lixianglai@loongson.cn) -- Support-vfio-config.patch (lixianglai@loongson.cn) -- pass-to-make-check.patch (lixianglai@loongson.cn) -- fixup-can-t-find-cpu-type.patch (lixianglai@loongson.cn) -- fix-smbios-type4-info-for-numa-support.patch (lixianglai@loongson.cn) -- Fix-smp.cores-value.patch (lixianglai@loongson.cn) -- Add-lbt-support-for-kvm.patch (lixianglai@loongson.cn) -- Modify-the-ioctl-command-of-kvm.patch (lixianglai@loongson.cn) -- Add-usb-storage-config-for-loongarch.patch (zhaotianrui@loongson.c) -- Add-loongarch-into-QEMU_ARCH_VIRTIO_PCI-to-support-q.patch (zhaotianrui@loongson.c) -- Fix-host-architecture-macro-of-LoongArch-to-HOST_LOO.patch (zhaotianrui@loongson.c) -- Fix-LoongArch-KVM-header-macros.patch (zhaotianrui@loongson.c) -- loongarch: Fixed the issue where qemu specifies the boot order (lixianglai@loongson.cn) -- 0001-anolis-csv-i386-add-CSV-context.patch (jiangxin@hygon.cn) -- 0002-anolis-csv-i386-add-command-to-initialize-CSV-contex.patch (jiangxin@hygon.cn) -- 0003-anolis-csv-i386-add-command-to-load-data-to-guest-me.patch (jiangxin@hygon.cn) -- 0004-anolis-csv-i386-add-command-to-load-vmcb-to-guest-me.patch (jiangxin@hygon.cn) -- 0005-anolis-cpu-i386-populate-CPUID-0x8000_001F-when-CSV-.patch (jiangxin@hygon.cn) -- 0006-anolis-csv-i386-CSV-guest-do-not-need-register-unreg.patch (jiangxin@hygon.cn) -- 0007-anolis-target-i386-csv-load-initial-image-to-private.patch (jiangxin@hygon.cn) -- 0008-anolis-vga-force-full-update-for-CSV-guest.patch (jiangxin@hygon.cn) - (Hygon CSV3 feature) -- Support Hygon CSV/CSV2 live migration, CSV2 reboot (hanliyang@hygon.cn) -- Support CSV3 live migration (jiangxin@hygon.cn) -- Support reuse ASID for CSV guests (hanliyang@hygon.cn) -- Support tkm key isolation (xiongmengbiao@hygon.cn) -- Add Hygon Dhyana-v3 and Dharma CPU model (zhouyanjing@hygon.cn) -- Intel-SIG: Supprt Intel SPR/GNR/SRF new ISAs and cpu models (quanxian.wang@intel.com) -- Intel-SIG: Supprt new SPR models (quanxian.wang@intel.com) +* Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 +- kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] +- Resolves: RHEL-26197 + (virtiofsd --help and manpage does not agree on --thread-pool-size default value) + +* Tue Oct 08 2024 Jon Maloy - 6.2.0-53.el8.1 +- kvm-block-move-bdrv_qiov_is_aligned-to-file-posix.patch [RHEL-60553] +- kvm-block-use-the-request-length-for-iov-alignment.patch [RHEL-60553] +- Resolves: RHEL-60553 + (Frequent VM pauses on OpenShift Virtualization with Portworx storage) * Thu Sep 05 2024 Miroslav Rezanina - 6.2.0-53.el8 - kvm-nbd-server-Favor-qemu_aio_context-over-iohandler-con.patch [RHEL-52611] diff --git a/rename-kvm_msr_buf-with-kvm_csr_buf.patch b/rename-kvm_msr_buf-with-kvm_csr_buf.patch deleted file mode 100644 index 6d13b6e..0000000 --- a/rename-kvm_msr_buf-with-kvm_csr_buf.patch +++ /dev/null @@ -1,638 +0,0 @@ -From 25f1ae50858b5c580336321e18ef0029d3dec922 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Mon, 29 May 2023 05:57:27 -0400 -Subject: [PATCH 11/28] rename kvm_msr_buf with kvm_csr_buf. - -Signed-off-by: lixianglai ---- - target/loongarch64/cpu.h | 2 +- - target/loongarch64/kvm.c | 564 +++++++++++++++++++-------------------- - 2 files changed, 283 insertions(+), 283 deletions(-) - -diff --git a/target/loongarch64/cpu.h b/target/loongarch64/cpu.h -index 10facb3b7..078556a22 100644 ---- a/target/loongarch64/cpu.h -+++ b/target/loongarch64/cpu.h -@@ -200,7 +200,7 @@ struct LOONGARCHCPU { - VMChangeStateEntry *cpuStateEntry; - int32_t node_id; /* NUMA node this CPU belongs to */ - int32_t core_id; -- struct kvm_msrs *kvm_msr_buf; -+ struct kvm_msrs *kvm_csr_buf; - /* 'compatible' string for this CPU for Linux device trees */ - const char *dtb_compatible; - }; -diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c -index 404a605eb..b5c655812 100644 ---- a/target/loongarch64/kvm.c -+++ b/target/loongarch64/kvm.c -@@ -31,7 +31,7 @@ - #define DEBUG_KVM 0 - /* A 16384-byte buffer can hold the 8-byte kvm_msrs header, plus - * 2047 kvm_msr_entry structs */ --#define MSR_BUF_SIZE 16384 -+#define CSR_BUF_SIZE 16384 - - #define DPRINTF(fmt, ...) \ - do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0) -@@ -101,7 +101,7 @@ int kvm_arch_init_vcpu(CPUState *cs) - int ret = 0; - - cpu->cpuStateEntry = qemu_add_vm_change_state_handler(kvm_loongarch_update_state, cs); -- cpu->kvm_msr_buf = g_malloc0(MSR_BUF_SIZE); -+ cpu->kvm_csr_buf = g_malloc0(CSR_BUF_SIZE); - DPRINTF("%s\n", __func__); - return ret; - } -@@ -111,15 +111,15 @@ int kvm_arch_destroy_vcpu(CPUState *cs) - return 0; - } - --static void kvm_msr_buf_reset(LOONGARCHCPU *cpu) -+static void kvm_csr_buf_reset(LOONGARCHCPU *cpu) - { -- memset(cpu->kvm_msr_buf, 0, MSR_BUF_SIZE); -+ memset(cpu->kvm_csr_buf, 0, CSR_BUF_SIZE); - } - --static void kvm_msr_entry_add(LOONGARCHCPU *cpu, uint32_t index, uint64_t value) -+static void kvm_csr_entry_add(LOONGARCHCPU *cpu, uint32_t index, uint64_t value) - { -- struct kvm_msrs *msrs = cpu->kvm_msr_buf; -- void *limit = ((void *)msrs) + MSR_BUF_SIZE; -+ struct kvm_msrs *msrs = cpu->kvm_csr_buf; -+ void *limit = ((void *)msrs) + CSR_BUF_SIZE; - struct kvm_csr_entry *entry = &msrs->entries[msrs->ncsrs]; - - assert((void *)(entry + 1) <= limit); -@@ -767,144 +767,144 @@ static int kvm_loongarch_put_csr_registers(CPUState *cs, int level) - - (void)level; - -- kvm_msr_buf_reset(cpu); -- -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CRMD, env->CSR_CRMD); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRMD, env->CSR_PRMD); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_EUEN, env->CSR_EUEN); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_MISC, env->CSR_MISC); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ECFG, env->CSR_ECFG); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ESTAT, env->CSR_ESTAT); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERA, env->CSR_ERA); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADV, env->CSR_BADV); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADI, env->CSR_BADI); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_EEPN, env->CSR_EEPN); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, env->CSR_TLBIDX); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, env->CSR_TLBEHI); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, env->CSR_TLBELO0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, env->CSR_TLBELO1); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GTLBC, env->CSR_GTLBC); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TRGP, env->CSR_TRGP); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ASID, env->CSR_ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDL, env->CSR_PGDL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDH, env->CSR_PGDH); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGD, env->CSR_PGD); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, env->CSR_PWCTL0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, env->CSR_PWCTL1); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, env->CSR_STLBPGSIZE); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_RVACFG, env->CSR_RVACFG); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CPUID, env->CSR_CPUID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, env->CSR_PRCFG1); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, env->CSR_PRCFG2); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, env->CSR_PRCFG3); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS0, env->CSR_KS0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS1, env->CSR_KS1); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS2, env->CSR_KS2); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS3, env->CSR_KS3); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS4, env->CSR_KS4); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS5, env->CSR_KS5); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS6, env->CSR_KS6); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS7, env->CSR_KS7); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TMID, env->CSR_TMID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CNTC, env->CSR_CNTC); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, env->CSR_TINTCLR); -- -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GSTAT, env->CSR_GSTAT); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCFG, env->CSR_GCFG); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GINTC, env->CSR_GINTC); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCNTC, env->CSR_GCNTC); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, env->CSR_LLBCTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, env->CSR_IMPCTL1); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, env->CSR_IMPCTL2); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GNMI, env->CSR_GNMI); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, env->CSR_TLBRENT); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, env->CSR_TLBRBADV); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, env->CSR_TLBRERA); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, env->CSR_TLBRSAVE); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, env->CSR_TLBRELO0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, env->CSR_TLBRELO1); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, env->CSR_TLBREHI); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, env->CSR_TLBRPRMD); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, env->CSR_ERRCTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, env->CSR_ERRINFO); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, env->CSR_ERRINFO1); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRENT, env->CSR_ERRENT); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRERA, env->CSR_ERRERA); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, env->CSR_ERRSAVE); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CTAG, env->CSR_CTAG); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, env->CSR_DMWIN0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, env->CSR_DMWIN1); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, env->CSR_DMWIN2); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, env->CSR_DMWIN3); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, env->CSR_PERFCTRL0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, env->CSR_PERFCNTR0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, env->CSR_PERFCTRL1); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, env->CSR_PERFCNTR1); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, env->CSR_PERFCTRL2); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, env->CSR_PERFCNTR2); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, env->CSR_PERFCTRL3); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, env->CSR_PERFCNTR3); -+ kvm_csr_buf_reset(cpu); -+ -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CRMD, env->CSR_CRMD); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRMD, env->CSR_PRMD); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_EUEN, env->CSR_EUEN); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MISC, env->CSR_MISC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ECFG, env->CSR_ECFG); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ESTAT, env->CSR_ESTAT); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERA, env->CSR_ERA); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_BADV, env->CSR_BADV); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_BADI, env->CSR_BADI); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_EEPN, env->CSR_EEPN); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, env->CSR_TLBIDX); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, env->CSR_TLBEHI); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, env->CSR_TLBELO0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, env->CSR_TLBELO1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GTLBC, env->CSR_GTLBC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TRGP, env->CSR_TRGP); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ASID, env->CSR_ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGDL, env->CSR_PGDL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGDH, env->CSR_PGDH); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGD, env->CSR_PGD); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, env->CSR_PWCTL0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, env->CSR_PWCTL1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, env->CSR_STLBPGSIZE); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_RVACFG, env->CSR_RVACFG); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CPUID, env->CSR_CPUID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, env->CSR_PRCFG1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, env->CSR_PRCFG2); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, env->CSR_PRCFG3); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS0, env->CSR_KS0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS1, env->CSR_KS1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS2, env->CSR_KS2); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS3, env->CSR_KS3); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS4, env->CSR_KS4); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS5, env->CSR_KS5); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS6, env->CSR_KS6); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS7, env->CSR_KS7); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TMID, env->CSR_TMID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CNTC, env->CSR_CNTC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, env->CSR_TINTCLR); -+ -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GSTAT, env->CSR_GSTAT); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GCFG, env->CSR_GCFG); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GINTC, env->CSR_GINTC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GCNTC, env->CSR_GCNTC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, env->CSR_LLBCTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, env->CSR_IMPCTL1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, env->CSR_IMPCTL2); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GNMI, env->CSR_GNMI); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, env->CSR_TLBRENT); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, env->CSR_TLBRBADV); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, env->CSR_TLBRERA); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, env->CSR_TLBRSAVE); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, env->CSR_TLBRELO0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, env->CSR_TLBRELO1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, env->CSR_TLBREHI); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, env->CSR_TLBRPRMD); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, env->CSR_ERRCTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, env->CSR_ERRINFO); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, env->CSR_ERRINFO1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRENT, env->CSR_ERRENT); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRERA, env->CSR_ERRERA); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, env->CSR_ERRSAVE); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CTAG, env->CSR_CTAG); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, env->CSR_DMWIN0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, env->CSR_DMWIN1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, env->CSR_DMWIN2); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, env->CSR_DMWIN3); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, env->CSR_PERFCTRL0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, env->CSR_PERFCNTR0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, env->CSR_PERFCTRL1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, env->CSR_PERFCNTR1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, env->CSR_PERFCTRL2); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, env->CSR_PERFCNTR2); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, env->CSR_PERFCTRL3); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, env->CSR_PERFCNTR3); - - /* debug */ -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPC, env->CSR_MWPC); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPS, env->CSR_MWPS); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, env->CSR_DB0ADDR); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, env->CSR_DB0MASK); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, env->CSR_DB0CTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, env->CSR_DB0ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, env->CSR_DB1ADDR); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, env->CSR_DB1MASK); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, env->CSR_DB1CTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, env->CSR_DB1ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, env->CSR_DB2ADDR); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, env->CSR_DB2MASK); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, env->CSR_DB2CTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, env->CSR_DB2ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, env->CSR_DB3ADDR); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, env->CSR_DB3MASK); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, env->CSR_DB3CTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, env->CSR_DB3ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPC, env->CSR_FWPC); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPS, env->CSR_FWPS); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, env->CSR_IB0ADDR); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, env->CSR_IB0MASK); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, env->CSR_IB0CTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, env->CSR_IB0ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, env->CSR_IB1ADDR); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, env->CSR_IB1MASK); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, env->CSR_IB1CTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, env->CSR_IB1ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, env->CSR_IB2ADDR); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, env->CSR_IB2MASK); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, env->CSR_IB2CTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, env->CSR_IB2ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, env->CSR_IB3ADDR); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, env->CSR_IB3MASK); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, env->CSR_IB3CTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, env->CSR_IB3ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, env->CSR_IB4ADDR); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, env->CSR_IB4MASK); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, env->CSR_IB4CTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, env->CSR_IB4ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, env->CSR_IB5ADDR); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, env->CSR_IB5MASK); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, env->CSR_IB5CTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, env->CSR_IB5ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, env->CSR_IB6ADDR); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, env->CSR_IB6MASK); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, env->CSR_IB6CTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, env->CSR_IB6ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, env->CSR_IB7ADDR); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, env->CSR_IB7MASK); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, env->CSR_IB7CTL); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, env->CSR_IB7ASID); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DEBUG, env->CSR_DEBUG); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DERA, env->CSR_DERA); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DESAVE, env->CSR_DESAVE); -- -- ret = kvm_vcpu_ioctl(cs, KVM_SET_MSRS, cpu->kvm_msr_buf); -- if (ret < cpu->kvm_msr_buf->ncsrs) { -- struct kvm_csr_entry *e = &cpu->kvm_msr_buf->entries[ret]; -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MWPC, env->CSR_MWPC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MWPS, env->CSR_MWPS); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, env->CSR_DB0ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, env->CSR_DB0MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, env->CSR_DB0CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, env->CSR_DB0ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, env->CSR_DB1ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, env->CSR_DB1MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, env->CSR_DB1CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, env->CSR_DB1ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, env->CSR_DB2ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, env->CSR_DB2MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, env->CSR_DB2CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, env->CSR_DB2ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, env->CSR_DB3ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, env->CSR_DB3MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, env->CSR_DB3CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, env->CSR_DB3ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_FWPC, env->CSR_FWPC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_FWPS, env->CSR_FWPS); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, env->CSR_IB0ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, env->CSR_IB0MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, env->CSR_IB0CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, env->CSR_IB0ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, env->CSR_IB1ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, env->CSR_IB1MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, env->CSR_IB1CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, env->CSR_IB1ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, env->CSR_IB2ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, env->CSR_IB2MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, env->CSR_IB2CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, env->CSR_IB2ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, env->CSR_IB3ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, env->CSR_IB3MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, env->CSR_IB3CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, env->CSR_IB3ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, env->CSR_IB4ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, env->CSR_IB4MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, env->CSR_IB4CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, env->CSR_IB4ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, env->CSR_IB5ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, env->CSR_IB5MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, env->CSR_IB5CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, env->CSR_IB5ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, env->CSR_IB6ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, env->CSR_IB6MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, env->CSR_IB6CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, env->CSR_IB6ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, env->CSR_IB7ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, env->CSR_IB7MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, env->CSR_IB7CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, env->CSR_IB7ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DEBUG, env->CSR_DEBUG); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DERA, env->CSR_DERA); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DESAVE, env->CSR_DESAVE); -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_SET_MSRS, cpu->kvm_csr_buf); -+ if (ret < cpu->kvm_csr_buf->ncsrs) { -+ struct kvm_csr_entry *e = &cpu->kvm_csr_buf->entries[ret]; - printf("error: failed to set CSR 0x%" PRIx32 " to 0x%" PRIx64"\n", - (uint32_t)e->index, (uint64_t)e->data); - } -@@ -935,147 +935,147 @@ static int kvm_loongarch_get_csr_registers(CPUState *cs) - LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); - CPULOONGARCHState *env = &cpu->env; - int ret = 0, i; -- struct kvm_csr_entry *csrs = cpu->kvm_msr_buf->entries; -- -- kvm_msr_buf_reset(cpu); -- -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CRMD, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRMD, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_EUEN, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_MISC, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ECFG, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ESTAT, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERA, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADV, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADI, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_EEPN, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GTLBC, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TRGP, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDH, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGD, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_RVACFG, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CPUID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS0, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS1, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS2, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS3, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS4, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS5, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS6, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS7, 0); -- -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TMID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CNTC, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GSTAT, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCFG, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GINTC, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCNTC, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_GNMI, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRENT, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRERA, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_CTAG, 0); -- -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, 0); -+ struct kvm_csr_entry *csrs = cpu->kvm_csr_buf->entries; -+ -+ kvm_csr_buf_reset(cpu); -+ -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CRMD, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRMD, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_EUEN, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MISC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ECFG, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ESTAT, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERA, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_BADV, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_BADI, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_EEPN, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GTLBC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TRGP, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGDL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGDH, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGD, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_RVACFG, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CPUID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS2, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS3, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS4, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS5, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS6, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS7, 0); -+ -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TMID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CNTC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GSTAT, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GCFG, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GINTC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GCNTC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GNMI, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRENT, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRERA, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CTAG, 0); -+ -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, 0); - - /* debug */ -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPC, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPS, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPC, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPS, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DEBUG, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DERA, 0); -- kvm_msr_entry_add(cpu, LOONGARCH_CSR_DESAVE, 0); -- -- ret = kvm_vcpu_ioctl(cs, KVM_GET_MSRS, cpu->kvm_msr_buf); -- if (ret < cpu->kvm_msr_buf->ncsrs) { -- struct kvm_csr_entry *e = &cpu->kvm_msr_buf->entries[ret]; -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MWPC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MWPS, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_FWPC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_FWPS, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DEBUG, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DERA, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DESAVE, 0); -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_GET_MSRS, cpu->kvm_csr_buf); -+ if (ret < cpu->kvm_csr_buf->ncsrs) { -+ struct kvm_csr_entry *e = &cpu->kvm_csr_buf->entries[ret]; - printf("error: failed to get CSR 0x%" PRIx32"\n", - (uint32_t)e->index); - } --- -2.43.5 - -- Gitee From 564ea010a40784c56628c8b5e6fb9f7193e3f0fb Mon Sep 17 00:00:00 2001 From: Jacob Wang Date: Sun, 1 Aug 2021 13:37:55 +0800 Subject: [PATCH 02/17] Adjust to support virtiofsd minor > 27 Signed-off-by: Jacob Wang --- ...iofsd-Adjust-limit-for-minor-version.patch | 41 +++++++++++++++++++ qemu-kvm.spec | 8 +++- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 kvm-virtiofsd-Adjust-limit-for-minor-version.patch diff --git a/kvm-virtiofsd-Adjust-limit-for-minor-version.patch b/kvm-virtiofsd-Adjust-limit-for-minor-version.patch new file mode 100644 index 0000000..30ec553 --- /dev/null +++ b/kvm-virtiofsd-Adjust-limit-for-minor-version.patch @@ -0,0 +1,41 @@ +From 3b7200134925fcf5ae99b5c3b34465456d3bc002 Mon Sep 17 00:00:00 2001 +From: Jacob Wang +Date: Mon, 2 Aug 2021 01:16:05 +0800 +Subject: [PATCH 1/1] virtiofsd: Adjust limit for minor version + +Upstream virtiofsd only supports fuse >= 7.31 +(https://github.com/qemu/qemu/commit/72c42e2d65510e073cf78fdc924d121c77fa0080), +while Cloud Kernel has fuse version 7.27, which causes virtiofs fails to run +due to version mismatch. This limitation is unnecessary in Cloud Kernel because +we have already backported mandatory fuse patches to support virtofs +frontend in Kernel. Hence, adjust the minor version limit to 7.27 to +suppress the limitation. + +Note that current fuse implementation in Cloud Kernel might lack of some +certain capabilities in fuse 7.28 ~ 7.31, which may cause unexpected results, +this patch is merely a workaround to enable virtiofs in guest kernel side and +further action is ongoing to make sure fuse APIs in both sides are 100% +compatible. + +Signed-off-by: Jacob Wang +Acked-by: Caspar Zhang +--- + tools/virtiofsd/fuse_lowlevel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c +index 2dd36ec..2bb4318 100644 +--- a/tools/virtiofsd/fuse_lowlevel.c ++++ b/tools/virtiofsd/fuse_lowlevel.c +@@ -1917,7 +1917,7 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, + outarg.major = FUSE_KERNEL_VERSION; + outarg.minor = FUSE_KERNEL_MINOR_VERSION; + +- if (arg->major < 7 || (arg->major == 7 && arg->minor < 31)) { ++ if (arg->major < 7 || (arg->major == 7 && arg->minor < 27)) { + fuse_log(FUSE_LOG_ERR, "fuse: unsupported protocol version: %u.%u\n", + arg->major, arg->minor); + fuse_reply_err(req, EPROTO); +-- +1.8.3.1 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 57297f6..80946fe 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -1,3 +1,4 @@ +%define anolis_release .0.1 %global SLOF_gittagdate 20191022 %global SLOF_gittagcommit 899d9883 @@ -83,7 +84,7 @@ Obsoletes: %1-rhev <= %{epoch}:%{version}-%{release} Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 6.2.0 -Release: 53%{?rcrel}%{?dist}.2 +Release: 53%{?rcrel}%{anolis_release}%{?dist}.2 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 15 License: GPLv2 and GPLv2+ and CC-BY @@ -892,6 +893,8 @@ Patch365: kvm-block-use-the-request-length-for-iov-alignment.patch # For RHEL-26197 - virtiofsd --help and manpage does not agree on --thread-pool-size default value Patch366: kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch +Patch1000: kvm-virtiofsd-Adjust-limit-for-minor-version.patch + BuildRequires: wget BuildRequires: rpm-build BuildRequires: ninja-build @@ -2060,6 +2063,9 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %changelog +* Fri Nov 08 2024 Jacob Wang - 6.2.0-53.0.1.2 +- Adjust limit for virtiofsd minor version + * Tue Oct 15 2024 Jon Maloy - 6.2.0-53.el8.2 - kvm-Fix-thread-pool-size-default-value-in-the-man-page.patch [RHEL-26197] - Resolves: RHEL-26197 -- Gitee From 058e1b8c4cd70dcb3053a4c854bdfddab0d7810b Mon Sep 17 00:00:00 2001 From: lixianglai Date: Thu, 25 Aug 2022 05:55:22 -0400 Subject: [PATCH 03/17] Support loongarch. Signed-off-by: lixianglai --- 0001-Add-Acpi-support.patch | 1348 ++ 0002-Support-rtc.patch | 370 + 0003-Add-loongarch-machine.patch | 5752 +++++++ 0004-Add-target-loongarch64.patch | 15918 ++++++++++++++++++ 0005-Add-linux-headers-and-linux-user.patch | 1663 ++ 0006-Add-disas-gdb.patch | 3183 ++++ 0007-Modify-kvm-cpu-vga-qapi.patch | 480 + 0008-Modify-compile-script.patch | 36 + 0009-Add-loongarch64-rh-devices.mak.patch | 3227 ++++ loongarch_bios.bin | Bin 0 -> 4190208 bytes loongarch_vars.bin | Bin 0 -> 389120 bytes qemu-kvm.spec | 43 +- 12 files changed, 32015 insertions(+), 5 deletions(-) create mode 100644 0001-Add-Acpi-support.patch create mode 100644 0002-Support-rtc.patch create mode 100644 0003-Add-loongarch-machine.patch create mode 100644 0004-Add-target-loongarch64.patch create mode 100644 0005-Add-linux-headers-and-linux-user.patch create mode 100644 0006-Add-disas-gdb.patch create mode 100644 0007-Modify-kvm-cpu-vga-qapi.patch create mode 100644 0008-Modify-compile-script.patch create mode 100644 0009-Add-loongarch64-rh-devices.mak.patch create mode 100644 loongarch_bios.bin create mode 100644 loongarch_vars.bin diff --git a/0001-Add-Acpi-support.patch b/0001-Add-Acpi-support.patch new file mode 100644 index 0000000..5b1561c --- /dev/null +++ b/0001-Add-Acpi-support.patch @@ -0,0 +1,1348 @@ +From 612826687e639d007e4270b01a61f34f7fc1f813 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Fri, 19 Aug 2022 23:11:23 -0400 +Subject: [PATCH 1/8] Add Acpi support. + +Change-Id: I208228b2178cddf365e97c6faf6111ef40e795eb +Signed-off-by: lixianglai +--- + hw/acpi/Kconfig | 8 + + hw/acpi/larch_7a.c | 600 +++++++++++++++++++++++++++++++++++++++++ + hw/acpi/ls7a.c | 598 ++++++++++++++++++++++++++++++++++++++++ + hw/acpi/meson.build | 1 + + include/hw/acpi/ls7a.h | 80 ++++++ + 5 files changed, 1287 insertions(+) + create mode 100644 hw/acpi/larch_7a.c + create mode 100644 hw/acpi/ls7a.c + create mode 100644 include/hw/acpi/ls7a.h + +diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig +index 622b0b50b7..2f2fb33a7b 100644 +--- a/hw/acpi/Kconfig ++++ b/hw/acpi/Kconfig +@@ -15,6 +15,14 @@ config ACPI_X86_ICH + bool + select ACPI_X86 + ++config ACPI_LOONGARCH ++ bool ++ select ACPI ++ select ACPI_CPU_HOTPLUG ++ select ACPI_MEMORY_HOTPLUG ++ select ACPI_PIIX4 ++ select ACPI_PCIHP ++ + config ACPI_CPU_HOTPLUG + bool + +diff --git a/hw/acpi/larch_7a.c b/hw/acpi/larch_7a.c +new file mode 100644 +index 0000000000..35d4a75266 +--- /dev/null ++++ b/hw/acpi/larch_7a.c +@@ -0,0 +1,600 @@ ++#include "qemu/osdep.h" ++#include "sysemu/sysemu.h" ++#include "sysemu/runstate.h" ++#include "sysemu/reset.h" ++#include "hw/hw.h" ++#include "hw/irq.h" ++#include "hw/acpi/acpi.h" ++#include "hw/acpi/ls7a.h" ++#include "hw/nvram/fw_cfg.h" ++#include "qemu/config-file.h" ++#include "qapi/opts-visitor.h" ++#include "qapi/qapi-events-run-state.h" ++#include "qapi/error.h" ++#include "hw/loongarch/ls7a.h" ++#include "hw/mem/pc-dimm.h" ++#include "hw/mem/nvdimm.h" ++#include "migration/vmstate.h" ++ ++static void ls7a_pm_update_sci_fn(ACPIREGS *regs) ++{ ++ LS7APCIPMRegs *pm = container_of(regs, LS7APCIPMRegs, acpi_regs); ++ acpi_update_sci(&pm->acpi_regs, pm->irq); ++} ++ ++static uint64_t ls7a_gpe_readb(void *opaque, hwaddr addr, unsigned width) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ return acpi_gpe_ioport_readb(&pm->acpi_regs, addr); ++} ++ ++static void ls7a_gpe_writeb(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val); ++ acpi_update_sci(&pm->acpi_regs, pm->irq); ++} ++ ++static const MemoryRegionOps ls7a_gpe_ops = { ++ .read = ls7a_gpe_readb, ++ .write = ls7a_gpe_writeb, ++ .valid.min_access_size = 1, ++ .valid.max_access_size = 8, ++ .impl.min_access_size = 1, ++ .impl.max_access_size = 1, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++#define VMSTATE_GPE_ARRAY(_field, _state) \ ++ { \ ++ .name = (stringify(_field)), \ ++ .version_id = 0, \ ++ .num = ACPI_GPE0_LEN, \ ++ .info = &vmstate_info_uint8, \ ++ .size = sizeof(uint8_t), \ ++ .flags = VMS_ARRAY | VMS_POINTER, \ ++ .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ ++ } ++ ++static uint64_t ls7a_reset_readw(void *opaque, hwaddr addr, unsigned width) ++{ ++ return 0; ++} ++ ++static void ls7a_reset_writew(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ if (val & 1) { ++ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); ++ return; ++ } ++} ++ ++static const MemoryRegionOps ls7a_reset_ops = { ++ .read = ls7a_reset_readw, ++ .write = ls7a_reset_writew, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static bool vmstate_test_use_memhp(void *opaque) ++{ ++ LS7APCIPMRegs *s = opaque; ++ return s->acpi_memory_hotplug.is_enabled; ++} ++ ++static const VMStateDescription vmstate_memhp_state = { ++ .name = "ls7a_pm/memhp", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .minimum_version_id_old = 1, ++ .needed = vmstate_test_use_memhp, ++ .fields = (VMStateField[]) { ++ VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, LS7APCIPMRegs), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static const VMStateDescription vmstate_cpuhp_state = { ++ .name = "ls7a_pm/cpuhp", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .minimum_version_id_old = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_CPU_HOTPLUG(cpuhp_state, LS7APCIPMRegs), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++const VMStateDescription vmstate_ls7a_pm = { ++ .name = "ls7a_pm", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT16(acpi_regs.pm1.evt.sts, LS7APCIPMRegs), ++ VMSTATE_UINT16(acpi_regs.pm1.evt.en, LS7APCIPMRegs), ++ VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, LS7APCIPMRegs), ++ VMSTATE_TIMER_PTR(acpi_regs.tmr.timer, LS7APCIPMRegs), ++ VMSTATE_INT64(acpi_regs.tmr.overflow_time, LS7APCIPMRegs), ++ VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, LS7APCIPMRegs), ++ VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, LS7APCIPMRegs), ++ VMSTATE_END_OF_LIST() ++ }, ++ .subsections = (const VMStateDescription * []) { ++ &vmstate_memhp_state, ++ &vmstate_cpuhp_state, ++ NULL ++ } ++}; ++ ++static inline int64_t acpi_pm_tmr_get_clock(void) ++{ ++ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY, ++ NANOSECONDS_PER_SECOND); ++} ++ ++static uint32_t acpi_pm_tmr_get(ACPIREGS *ar) ++{ ++ uint32_t d = acpi_pm_tmr_get_clock(); ++ return d & 0xffffff; ++} ++ ++static void acpi_pm_tmr_timer(void *opaque) ++{ ++ ACPIREGS *ar = opaque; ++ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_PMTIMER, NULL); ++ ar->tmr.update_sci(ar); ++} ++ ++static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width) ++{ ++ return acpi_pm_tmr_get(opaque); ++} ++ ++static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ /* nothing */ ++} ++ ++static const MemoryRegionOps acpi_pm_tmr_ops = { ++ .read = acpi_pm_tmr_read, ++ .write = acpi_pm_tmr_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void ls7a_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, ++ MemoryRegion *parent, uint64_t offset) ++{ ++ ar->tmr.update_sci = update_sci; ++ ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar); ++ memory_region_init_io(&ar->tmr.io, memory_region_owner(parent), ++ &acpi_pm_tmr_ops, ar, "acpi-tmr", 4); ++ memory_region_add_subregion(parent, offset, &ar->tmr.io); ++} ++ ++static void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val) ++{ ++ uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar); ++ if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) { ++ /* if TMRSTS is reset, then compute the new overflow time */ ++ acpi_pm_tmr_calc_overflow_time(ar); ++ } ++ ar->pm1.evt.sts &= ~val; ++} ++ ++static uint64_t acpi_pm_evt_read(void *opaque, hwaddr addr, unsigned width) ++{ ++ ACPIREGS *ar = opaque; ++ switch (addr) { ++ case 0: ++ return acpi_pm1_evt_get_sts(ar); ++ case 4: ++ return ar->pm1.evt.en; ++ default: ++ return 0; ++ } ++} ++ ++static void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val) ++{ ++ ar->pm1.evt.en = val; ++ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, ++ val & ACPI_BITMASK_RT_CLOCK_ENABLE); ++ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, ++ val & ACPI_BITMASK_TIMER_ENABLE); ++} ++ ++static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ ACPIREGS *ar = opaque; ++ switch (addr) { ++ case 0: ++ acpi_pm1_evt_write_sts(ar, val); ++ ar->pm1.evt.update_sci(ar); ++ break; ++ case 4: ++ acpi_pm1_evt_write_en(ar, val); ++ ar->pm1.evt.update_sci(ar); ++ break; ++ } ++} ++ ++static const MemoryRegionOps acpi_pm_evt_ops = { ++ .read = acpi_pm_evt_read, ++ .write = acpi_pm_evt_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void ls7a_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, ++ MemoryRegion *parent, uint64_t offset) ++{ ++ ar->pm1.evt.update_sci = update_sci; ++ memory_region_init_io(&ar->pm1.evt.io, memory_region_owner(parent), ++ &acpi_pm_evt_ops, ar, "acpi-evt", 8); ++ memory_region_add_subregion(parent, offset, &ar->pm1.evt.io); ++} ++ ++static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width) ++{ ++ ACPIREGS *ar = opaque; ++ return ar->pm1.cnt.cnt; ++} ++ ++/* ACPI PM1aCNT */ ++static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val) ++{ ++ ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE); ++ if (val & ACPI_BITMASK_SLEEP_ENABLE) { ++ /* change suspend type */ ++ uint16_t sus_typ = (val >> 10) & 7; ++ switch (sus_typ) { ++ /* s3,s4 not support */ ++ case 5: ++ case 6: ++ warn_report("acpi s3,s4 state not support"); ++ break; ++ /* s5: soft off */ ++ case 7: ++ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ acpi_pm1_cnt_write(opaque, val); ++} ++ ++static const MemoryRegionOps acpi_pm_cnt_ops = { ++ .read = acpi_pm_cnt_read, ++ .write = acpi_pm_cnt_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void acpi_notify_wakeup(Notifier *notifier, void *data) ++{ ++ ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup); ++ WakeupReason *reason = data; ++ ++ switch (*reason) { ++ case QEMU_WAKEUP_REASON_RTC: ++ ar->pm1.evt.sts |= ++ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS); ++ break; ++ case QEMU_WAKEUP_REASON_PMTIMER: ++ ar->pm1.evt.sts |= ++ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS); ++ break; ++ case QEMU_WAKEUP_REASON_OTHER: ++ /* ACPI_BITMASK_WAKE_STATUS should be set on resume. ++ * Pretend that resume was caused by power button */ ++ ar->pm1.evt.sts |= ++ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void ls7a_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, ++ bool disable_s3, bool disable_s4, uint8_t s4_val, uint64_t offset) ++{ ++ FWCfgState *fw_cfg; ++ ++ ar->pm1.cnt.s4_val = s4_val; ++ ar->wakeup.notify = acpi_notify_wakeup; ++ qemu_register_wakeup_notifier(&ar->wakeup); ++ memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent), ++ &acpi_pm_cnt_ops, ar, "acpi-cnt", 4); ++ memory_region_add_subregion(parent, offset, &ar->pm1.cnt.io); ++ ++ fw_cfg = fw_cfg_find(); ++ if (fw_cfg) { ++ uint8_t suspend[6] = {128, 0, 0, 129, 128, 128}; ++ suspend[3] = 1 | ((!disable_s3) << 7); ++ suspend[4] = s4_val | ((!disable_s4) << 7); ++ fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6); ++ } ++} ++ ++static void ls7a_pm_reset(void *opaque) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ ++ acpi_pm1_evt_reset(&pm->acpi_regs); ++ acpi_pm1_cnt_reset(&pm->acpi_regs); ++ acpi_pm_tmr_reset(&pm->acpi_regs); ++ acpi_gpe_reset(&pm->acpi_regs); ++ ++ acpi_update_sci(&pm->acpi_regs, pm->irq); ++} ++ ++static void pm_powerdown_req(Notifier *n, void *opaque) ++{ ++ LS7APCIPMRegs *pm = container_of(n, LS7APCIPMRegs, powerdown_notifier); ++ ++ acpi_pm1_evt_power_down(&pm->acpi_regs); ++} ++ ++void ls7a_pm_init(LS7APCIPMRegs *pm, qemu_irq *pic) ++{ ++ unsigned long base, gpe_len, acpi_aci_irq; ++ ++ /* ls7a board acpi hardware info, including ++ * acpi system io base address ++ * acpi gpe length ++ * acpi sci irq number ++ */ ++ base = ACPI_IO_BASE; ++ gpe_len = ACPI_GPE0_LEN; ++ acpi_aci_irq = ACPI_SCI_IRQ; ++ ++ pm->irq = pic[acpi_aci_irq - 64]; ++ memory_region_init(&pm->iomem, NULL, "ls7a_pm", ACPI_IO_SIZE); ++ memory_region_add_subregion(get_system_memory(), base, &pm->iomem); ++ ++ cpu_hotplug_hw_init(get_system_memory(), NULL, ++ &pm->cpuhp_state, CPU_HOTPLUG_BASE); ++ ++ ls7a_pm_tmr_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, LS7A_PM_TMR_BLK); ++ ls7a_pm1_evt_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, LS7A_PM_EVT_BLK); ++ ls7a_pm1_cnt_init(&pm->acpi_regs, &pm->iomem, false, false, 2, LS7A_PM_CNT_BLK); ++ ++ acpi_gpe_init(&pm->acpi_regs, gpe_len); ++ memory_region_init_io(&pm->iomem_gpe, NULL, &ls7a_gpe_ops, pm, ++ "acpi-gpe0", gpe_len); ++ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_STS_REG, &pm->iomem_gpe); ++ ++ memory_region_init_io(&pm->iomem_reset, NULL, &ls7a_reset_ops, pm, ++ "acpi-reset", 4); ++ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_RESET_REG, &pm->iomem_reset); ++ ++ qemu_register_reset(ls7a_pm_reset, pm); ++ ++ pm->powerdown_notifier.notify = pm_powerdown_req; ++ qemu_register_powerdown_notifier(&pm->powerdown_notifier); ++ ++ if (pm->acpi_memory_hotplug.is_enabled) { ++ acpi_memory_hotplug_init(get_system_memory(), NULL, ++ &pm->acpi_memory_hotplug, MEMORY_HOTPLUG_BASE); ++ } ++} ++ ++ ++static void ls7a_pm_get_gpe0_blk(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ uint64_t value = ACPI_IO_BASE + LS7A_GPE0_STS_REG; ++ ++ visit_type_uint64(v, name, &value, errp); ++} ++ ++static bool ls7a_pm_get_memory_hotplug_support(Object *obj, Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(obj); ++ ++ return ls7a->pm.acpi_memory_hotplug.is_enabled; ++} ++ ++static void ls7a_pm_set_memory_hotplug_support(Object *obj, bool value, ++ Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(obj); ++ ++ ls7a->pm.acpi_memory_hotplug.is_enabled = value; ++} ++ ++static void ls7a_pm_get_disable_s3(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ uint8_t value = pm->disable_s3; ++ ++ visit_type_uint8(v, name, &value, errp); ++} ++ ++static void ls7a_pm_set_disable_s3(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ Error *local_err = NULL; ++ uint8_t value; ++ ++ visit_type_uint8(v, name, &value, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ pm->disable_s3 = value; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void ls7a_pm_get_disable_s4(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ uint8_t value = pm->disable_s4; ++ ++ visit_type_uint8(v, name, &value, errp); ++} ++ ++static void ls7a_pm_set_disable_s4(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ Error *local_err = NULL; ++ uint8_t value; ++ ++ visit_type_uint8(v, name, &value, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ pm->disable_s4 = value; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void ls7a_pm_get_s4_val(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ uint8_t value = pm->s4_val; ++ ++ visit_type_uint8(v, name, &value, errp); ++} ++ ++static void ls7a_pm_set_s4_val(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ Error *local_err = NULL; ++ uint8_t value; ++ ++ visit_type_uint8(v, name, &value, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ pm->s4_val = value; ++out: ++ error_propagate(errp, local_err); ++} ++ ++void ls7a_pm_add_properties(Object *obj, LS7APCIPMRegs *pm, Error **errp) ++{ ++ static const uint32_t gpe0_len = ACPI_GPE0_LEN; ++ pm->acpi_memory_hotplug.is_enabled = true; ++ pm->disable_s3 = 0; ++ pm->disable_s4 = 0; ++ pm->s4_val = 2; ++ ++ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE, ++ &pm->pm_io_base, OBJ_PROP_FLAG_READ); ++ object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32", ++ ls7a_pm_get_gpe0_blk, ++ NULL, NULL, pm); ++ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN, ++ &gpe0_len, OBJ_PROP_FLAG_READ); ++ object_property_add_bool(obj, "memory-hotplug-support", ++ ls7a_pm_get_memory_hotplug_support, ++ ls7a_pm_set_memory_hotplug_support); ++ object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8", ++ ls7a_pm_get_disable_s3, ++ ls7a_pm_set_disable_s3, ++ NULL, pm); ++ object_property_add(obj, ACPI_PM_PROP_S4_DISABLED, "uint8", ++ ls7a_pm_get_disable_s4, ++ ls7a_pm_set_disable_s4, ++ NULL, pm); ++ object_property_add(obj, ACPI_PM_PROP_S4_VAL, "uint8", ++ ls7a_pm_get_s4_val, ++ ls7a_pm_set_s4_val, ++ NULL, pm); ++} ++ ++void ls7a_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); ++ ++ if (ls7a->pm.acpi_memory_hotplug.is_enabled && ++ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { ++ nvdimm_acpi_plug_cb(hotplug_dev, dev); ++ } else { ++ acpi_memory_plug_cb(hotplug_dev, &ls7a->pm.acpi_memory_hotplug, ++ dev, errp); ++ } ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_plug_cb(hotplug_dev, &ls7a->pm.cpuhp_state, dev, errp); ++ } else { ++ error_setg(errp, "acpi: device plug request for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++} ++ ++void ls7a_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); ++ ++ if (ls7a->pm.acpi_memory_hotplug.is_enabled && ++ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ acpi_memory_unplug_request_cb(hotplug_dev, ++ &ls7a->pm.acpi_memory_hotplug, dev, ++ errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_unplug_request_cb(hotplug_dev, &ls7a->pm.cpuhp_state, ++ dev, errp); ++ } else { ++ error_setg(errp, "acpi: device unplug request for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++} ++ ++void ls7a_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); ++ ++ if (ls7a->pm.acpi_memory_hotplug.is_enabled && ++ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ acpi_memory_unplug_cb(&ls7a->pm.acpi_memory_hotplug, dev, errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_unplug_cb(&ls7a->pm.cpuhp_state, dev, errp); ++ } else { ++ error_setg(errp, "acpi: device unplug for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++} ++ ++void ls7a_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); ++ ++ acpi_memory_ospm_status(&ls7a->pm.acpi_memory_hotplug, list); ++ acpi_cpu_ospm_status(&ls7a->pm.cpuhp_state, list); ++} ++ ++void ls7a_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); ++ ++ acpi_send_gpe_event(&ls7a->pm.acpi_regs, ls7a->pm.irq, ev); ++} ++ ++ ++ +diff --git a/hw/acpi/ls7a.c b/hw/acpi/ls7a.c +new file mode 100644 +index 0000000000..2de50ccb9c +--- /dev/null ++++ b/hw/acpi/ls7a.c +@@ -0,0 +1,598 @@ ++#include "qemu/osdep.h" ++#include "sysemu/sysemu.h" ++#include "hw/hw.h" ++#include "hw/irq.h" ++#include "hw/acpi/acpi.h" ++#include "hw/acpi/ls7a.h" ++#include "hw/nvram/fw_cfg.h" ++#include "qemu/config-file.h" ++#include "qapi/opts-visitor.h" ++#include "qapi/qapi-events-run-state.h" ++#include "qapi/error.h" ++#include "hw/mips/ls7a.h" ++#include "hw/mem/pc-dimm.h" ++#include "hw/mem/nvdimm.h" ++ ++static void ls7a_pm_update_sci_fn(ACPIREGS *regs) ++{ ++ LS7APCIPMRegs *pm = container_of(regs, LS7APCIPMRegs, acpi_regs); ++ acpi_update_sci(&pm->acpi_regs, pm->irq); ++} ++ ++static uint64_t ls7a_gpe_readb(void *opaque, hwaddr addr, unsigned width) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ return acpi_gpe_ioport_readb(&pm->acpi_regs, addr); ++} ++ ++static void ls7a_gpe_writeb(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val); ++ acpi_update_sci(&pm->acpi_regs, pm->irq); ++} ++ ++static const MemoryRegionOps ls7a_gpe_ops = { ++ .read = ls7a_gpe_readb, ++ .write = ls7a_gpe_writeb, ++ .valid.min_access_size = 1, ++ .valid.max_access_size = 8, ++ .impl.min_access_size = 1, ++ .impl.max_access_size = 1, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++#define VMSTATE_GPE_ARRAY(_field, _state) \ ++ { \ ++ .name = (stringify(_field)), \ ++ .version_id = 0, \ ++ .num = ACPI_GPE0_LEN, \ ++ .info = &vmstate_info_uint8, \ ++ .size = sizeof(uint8_t), \ ++ .flags = VMS_ARRAY | VMS_POINTER, \ ++ .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ ++ } ++ ++static uint64_t ls7a_reset_readw(void *opaque, hwaddr addr, unsigned width) ++{ ++ return 0; ++} ++ ++static void ls7a_reset_writew(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ if (val & 1) { ++ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); ++ return; ++ } ++} ++ ++static const MemoryRegionOps ls7a_reset_ops = { ++ .read = ls7a_reset_readw, ++ .write = ls7a_reset_writew, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static bool vmstate_test_use_memhp(void *opaque) ++{ ++ LS7APCIPMRegs *s = opaque; ++ return s->acpi_memory_hotplug.is_enabled; ++} ++ ++static const VMStateDescription vmstate_memhp_state = { ++ .name = "ls7a_pm/memhp", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .minimum_version_id_old = 1, ++ .needed = vmstate_test_use_memhp, ++ .fields = (VMStateField[]) { ++ VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, LS7APCIPMRegs), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static const VMStateDescription vmstate_cpuhp_state = { ++ .name = "ls7a_pm/cpuhp", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .minimum_version_id_old = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_CPU_HOTPLUG(cpuhp_state, LS7APCIPMRegs), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++const VMStateDescription vmstate_ls7a_pm = { ++ .name = "ls7a_pm", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT16(acpi_regs.pm1.evt.sts, LS7APCIPMRegs), ++ VMSTATE_UINT16(acpi_regs.pm1.evt.en, LS7APCIPMRegs), ++ VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, LS7APCIPMRegs), ++ VMSTATE_TIMER_PTR(acpi_regs.tmr.timer, LS7APCIPMRegs), ++ VMSTATE_INT64(acpi_regs.tmr.overflow_time, LS7APCIPMRegs), ++ VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, LS7APCIPMRegs), ++ VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, LS7APCIPMRegs), ++ VMSTATE_END_OF_LIST() ++ }, ++ .subsections = (const VMStateDescription * []) { ++ &vmstate_memhp_state, ++ &vmstate_cpuhp_state, ++ NULL ++ } ++}; ++ ++static inline int64_t acpi_pm_tmr_get_clock(void) ++{ ++ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY, ++ NANOSECONDS_PER_SECOND); ++} ++ ++static uint32_t acpi_pm_tmr_get(ACPIREGS *ar) ++{ ++ uint32_t d = acpi_pm_tmr_get_clock(); ++ return d & 0xffffff; ++} ++ ++static void acpi_pm_tmr_timer(void *opaque) ++{ ++ ACPIREGS *ar = opaque; ++ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_PMTIMER, NULL); ++ ar->tmr.update_sci(ar); ++} ++ ++static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width) ++{ ++ return acpi_pm_tmr_get(opaque); ++} ++ ++static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ /* nothing */ ++} ++ ++static const MemoryRegionOps acpi_pm_tmr_ops = { ++ .read = acpi_pm_tmr_read, ++ .write = acpi_pm_tmr_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void ls7a_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, ++ MemoryRegion *parent, uint64_t offset) ++{ ++ ar->tmr.update_sci = update_sci; ++ ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar); ++ memory_region_init_io(&ar->tmr.io, memory_region_owner(parent), ++ &acpi_pm_tmr_ops, ar, "acpi-tmr", 4); ++ memory_region_add_subregion(parent, offset, &ar->tmr.io); ++} ++ ++static void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val) ++{ ++ uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar); ++ if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) { ++ /* if TMRSTS is reset, then compute the new overflow time */ ++ acpi_pm_tmr_calc_overflow_time(ar); ++ } ++ ar->pm1.evt.sts &= ~val; ++} ++ ++static uint64_t acpi_pm_evt_read(void *opaque, hwaddr addr, unsigned width) ++{ ++ ACPIREGS *ar = opaque; ++ switch (addr) { ++ case 0: ++ return acpi_pm1_evt_get_sts(ar); ++ case 4: ++ return ar->pm1.evt.en; ++ default: ++ return 0; ++ } ++} ++ ++static void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val) ++{ ++ ar->pm1.evt.en = val; ++ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, ++ val & ACPI_BITMASK_RT_CLOCK_ENABLE); ++ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, ++ val & ACPI_BITMASK_TIMER_ENABLE); ++} ++ ++static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ ACPIREGS *ar = opaque; ++ switch (addr) { ++ case 0: ++ acpi_pm1_evt_write_sts(ar, val); ++ ar->pm1.evt.update_sci(ar); ++ break; ++ case 4: ++ acpi_pm1_evt_write_en(ar, val); ++ ar->pm1.evt.update_sci(ar); ++ break; ++ } ++} ++ ++static const MemoryRegionOps acpi_pm_evt_ops = { ++ .read = acpi_pm_evt_read, ++ .write = acpi_pm_evt_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void ls7a_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, ++ MemoryRegion *parent, uint64_t offset) ++{ ++ ar->pm1.evt.update_sci = update_sci; ++ memory_region_init_io(&ar->pm1.evt.io, memory_region_owner(parent), ++ &acpi_pm_evt_ops, ar, "acpi-evt", 8); ++ memory_region_add_subregion(parent, offset, &ar->pm1.evt.io); ++} ++ ++static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width) ++{ ++ ACPIREGS *ar = opaque; ++ return ar->pm1.cnt.cnt; ++} ++ ++/* ACPI PM1aCNT */ ++static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val) ++{ ++ ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE); ++ ++ if (val & ACPI_BITMASK_SLEEP_ENABLE) { ++ /* change suspend type */ ++ uint16_t sus_typ = (val >> 10) & 7; ++ switch (sus_typ) { ++ case 0: /* soft power off */ ++ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); ++ break; ++ case 1: ++ qemu_system_suspend_request(); ++ break; ++ default: ++ if (sus_typ == ar->pm1.cnt.s4_val) { /* S4 request */ ++ qapi_event_send_suspend_disk(); ++ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); ++ } ++ break; ++ } ++ } ++} ++ ++static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ acpi_pm1_cnt_write(opaque, val); ++} ++ ++static const MemoryRegionOps acpi_pm_cnt_ops = { ++ .read = acpi_pm_cnt_read, ++ .write = acpi_pm_cnt_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void acpi_notify_wakeup(Notifier *notifier, void *data) ++{ ++ ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup); ++ WakeupReason *reason = data; ++ ++ switch (*reason) { ++ case QEMU_WAKEUP_REASON_RTC: ++ ar->pm1.evt.sts |= ++ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS); ++ break; ++ case QEMU_WAKEUP_REASON_PMTIMER: ++ ar->pm1.evt.sts |= ++ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS); ++ break; ++ case QEMU_WAKEUP_REASON_OTHER: ++ /* ACPI_BITMASK_WAKE_STATUS should be set on resume. ++ * Pretend that resume was caused by power button */ ++ ar->pm1.evt.sts |= ++ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void ls7a_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, ++ bool disable_s3, bool disable_s4, uint8_t s4_val, uint64_t offset) ++{ ++ FWCfgState *fw_cfg; ++ ++ ar->pm1.cnt.s4_val = s4_val; ++ ar->wakeup.notify = acpi_notify_wakeup; ++ qemu_register_wakeup_notifier(&ar->wakeup); ++ memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent), ++ &acpi_pm_cnt_ops, ar, "acpi-cnt", 4); ++ memory_region_add_subregion(parent, offset, &ar->pm1.cnt.io); ++ ++ fw_cfg = fw_cfg_find(); ++ if (fw_cfg) { ++ uint8_t suspend[6] = {128, 0, 0, 129, 128, 128}; ++ suspend[3] = 1 | ((!disable_s3) << 7); ++ suspend[4] = s4_val | ((!disable_s4) << 7); ++ fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6); ++ } ++} ++ ++static void ls7a_pm_reset(void *opaque) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ ++ acpi_pm1_evt_reset(&pm->acpi_regs); ++ acpi_pm1_cnt_reset(&pm->acpi_regs); ++ acpi_pm_tmr_reset(&pm->acpi_regs); ++ acpi_gpe_reset(&pm->acpi_regs); ++ ++ acpi_update_sci(&pm->acpi_regs, pm->irq); ++} ++ ++static void pm_powerdown_req(Notifier *n, void *opaque) ++{ ++ LS7APCIPMRegs *pm = container_of(n, LS7APCIPMRegs, powerdown_notifier); ++ ++ acpi_pm1_evt_power_down(&pm->acpi_regs); ++} ++ ++void ls7a_pm_init(LS7APCIPMRegs *pm, qemu_irq *pic) ++{ ++ unsigned long base, gpe_len, acpi_aci_irq; ++ ++ /* ls7a board acpi hardware info, including ++ * acpi system io base address ++ * acpi gpe length ++ * acpi sci irq number ++ */ ++ base = ACPI_IO_BASE; ++ gpe_len = ACPI_GPE0_LEN; ++ acpi_aci_irq = ACPI_SCI_IRQ; ++ ++ pm->irq = pic[acpi_aci_irq - 64]; ++ memory_region_init(&pm->iomem, NULL, "ls7a_pm", ACPI_IO_SIZE); ++ memory_region_add_subregion(get_system_memory(), base, &pm->iomem); ++ ++ cpu_hotplug_hw_init(get_system_memory(), NULL, &pm->cpuhp_state, CPU_HOTPLUG_BASE); ++ ++ ls7a_pm_tmr_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, LS7A_PM_TMR_BLK); ++ ls7a_pm1_evt_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, LS7A_PM_EVT_BLK); ++ ls7a_pm1_cnt_init(&pm->acpi_regs, &pm->iomem, false, false, 2, LS7A_PM_CNT_BLK); ++ ++ acpi_gpe_init(&pm->acpi_regs, gpe_len); ++ memory_region_init_io(&pm->iomem_gpe, NULL, &ls7a_gpe_ops, pm, ++ "acpi-gpe0", gpe_len); ++ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_STS_REG, &pm->iomem_gpe); ++ ++ memory_region_init_io(&pm->iomem_reset, NULL, &ls7a_reset_ops, pm, ++ "acpi-reset", 4); ++ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_RESET_REG, &pm->iomem_reset); ++ ++ qemu_register_reset(ls7a_pm_reset, pm); ++ ++ pm->powerdown_notifier.notify = pm_powerdown_req; ++ qemu_register_powerdown_notifier(&pm->powerdown_notifier); ++ ++ if (pm->acpi_memory_hotplug.is_enabled) { ++ acpi_memory_hotplug_init(get_system_memory(), NULL, ++ &pm->acpi_memory_hotplug, MEMORY_HOTPLUG_BASE); ++ } ++} ++ ++ ++static void ls7a_pm_get_gpe0_blk(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ uint64_t value = ACPI_IO_BASE + LS7A_GPE0_STS_REG; ++ ++ visit_type_uint64(v, name, &value, errp); ++} ++ ++static bool ls7a_pm_get_memory_hotplug_support(Object *obj, Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(obj); ++ ++ return ls7a->pm.acpi_memory_hotplug.is_enabled; ++} ++ ++static void ls7a_pm_set_memory_hotplug_support(Object *obj, bool value, ++ Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(obj); ++ ++ ls7a->pm.acpi_memory_hotplug.is_enabled = value; ++} ++ ++static void ls7a_pm_get_disable_s3(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ uint8_t value = pm->disable_s3; ++ ++ visit_type_uint8(v, name, &value, errp); ++} ++ ++static void ls7a_pm_set_disable_s3(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ Error *local_err = NULL; ++ uint8_t value; ++ ++ visit_type_uint8(v, name, &value, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ pm->disable_s3 = value; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void ls7a_pm_get_disable_s4(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ uint8_t value = pm->disable_s4; ++ ++ visit_type_uint8(v, name, &value, errp); ++} ++ ++static void ls7a_pm_set_disable_s4(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ Error *local_err = NULL; ++ uint8_t value; ++ ++ visit_type_uint8(v, name, &value, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ pm->disable_s4 = value; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void ls7a_pm_get_s4_val(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ uint8_t value = pm->s4_val; ++ ++ visit_type_uint8(v, name, &value, errp); ++} ++ ++static void ls7a_pm_set_s4_val(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ Error *local_err = NULL; ++ uint8_t value; ++ ++ visit_type_uint8(v, name, &value, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ pm->s4_val = value; ++out: ++ error_propagate(errp, local_err); ++} ++ ++void ls7a_pm_add_properties(Object *obj, LS7APCIPMRegs *pm, Error **errp) ++{ ++ static const uint32_t gpe0_len = ACPI_GPE0_LEN; ++ pm->acpi_memory_hotplug.is_enabled = true; ++ pm->disable_s3 = 0; ++ pm->disable_s4 = 0; ++ pm->s4_val = 2; ++ ++ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE, ++ &pm->pm_io_base, OBJ_PROP_FLAG_READ); ++ object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32", ++ ls7a_pm_get_gpe0_blk, ++ NULL, NULL, pm); ++ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN, ++ &gpe0_len, OBJ_PROP_FLAG_READ); ++ object_property_add_bool(obj, "memory-hotplug-support", ++ ls7a_pm_get_memory_hotplug_support, ++ ls7a_pm_set_memory_hotplug_support); ++ object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8", ++ ls7a_pm_get_disable_s3, ++ ls7a_pm_set_disable_s3, ++ NULL, pm); ++ object_property_add(obj, ACPI_PM_PROP_S4_DISABLED, "uint8", ++ ls7a_pm_get_disable_s4, ++ ls7a_pm_set_disable_s4, ++ NULL, pm); ++ object_property_add(obj, ACPI_PM_PROP_S4_VAL, "uint8", ++ ls7a_pm_get_s4_val, ++ ls7a_pm_set_s4_val, ++ NULL, pm); ++} ++ ++void ls7a_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); ++ ++ if (ls7a->pm.acpi_memory_hotplug.is_enabled && ++ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { ++ nvdimm_acpi_plug_cb(hotplug_dev, dev); ++ } else { ++ acpi_memory_plug_cb(hotplug_dev, &ls7a->pm.acpi_memory_hotplug, ++ dev, errp); ++ } ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_plug_cb(hotplug_dev, &ls7a->pm.cpuhp_state, dev, errp); ++ } else { ++ error_setg(errp, "acpi: device plug request for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++} ++ ++void ls7a_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); ++ ++ if (ls7a->pm.acpi_memory_hotplug.is_enabled && ++ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ acpi_memory_unplug_request_cb(hotplug_dev, ++ &ls7a->pm.acpi_memory_hotplug, dev, ++ errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_unplug_request_cb(hotplug_dev, &ls7a->pm.cpuhp_state, ++ dev, errp); ++ } else { ++ error_setg(errp, "acpi: device unplug request for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++} ++ ++void ls7a_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); ++ ++ if (ls7a->pm.acpi_memory_hotplug.is_enabled && ++ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ acpi_memory_unplug_cb(&ls7a->pm.acpi_memory_hotplug, dev, errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_unplug_cb(&ls7a->pm.cpuhp_state, dev, errp); ++ } else { ++ error_setg(errp, "acpi: device unplug for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++} ++ ++void ls7a_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); ++ ++ acpi_memory_ospm_status(&ls7a->pm.acpi_memory_hotplug, list); ++ acpi_cpu_ospm_status(&ls7a->pm.cpuhp_state, list); ++} ++ ++void ls7a_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); ++ ++ acpi_send_gpe_event(&ls7a->pm.acpi_regs, ls7a->pm.irq, ev); ++} ++ ++ ++ +diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build +index adf6347bc4..5fe4cfa4f1 100644 +--- a/hw/acpi/meson.build ++++ b/hw/acpi/meson.build +@@ -6,6 +6,7 @@ acpi_ss.add(files( + 'core.c', + 'utils.c', + )) ++acpi_ss.add(when: 'CONFIG_ACPI_LOONGARCH', if_true: files('larch_7a.c')) + acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_true: files('cpu.c', 'cpu_hotplug.c')) + acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_false: files('acpi-cpu-hotplug-stub.c')) + acpi_ss.add(when: 'CONFIG_ACPI_MEMORY_HOTPLUG', if_true: files('memory_hotplug.c')) +diff --git a/include/hw/acpi/ls7a.h b/include/hw/acpi/ls7a.h +new file mode 100644 +index 0000000000..4401515c7b +--- /dev/null ++++ b/include/hw/acpi/ls7a.h +@@ -0,0 +1,80 @@ ++/* ++ * QEMU GMCH/LS7A PCI PM Emulation ++ * ++ * Copyright (c) 2009 Isaku Yamahata ++ * VA Linux Systems Japan K.K. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see ++ */ ++ ++#ifndef HW_ACPI_LS7A_H ++#define HW_ACPI_LS7A_H ++ ++#include "hw/acpi/acpi.h" ++#include "hw/acpi/cpu_hotplug.h" ++#include "hw/acpi/cpu.h" ++#include "hw/acpi/memory_hotplug.h" ++#include "hw/acpi/acpi_dev_interface.h" ++#include "hw/acpi/tco.h" ++ ++#define CPU_HOTPLUG_BASE 0x1e000000 ++#define MEMORY_HOTPLUG_BASE 0x1e00000c ++ ++typedef struct LS7APCIPMRegs { ++ /* ++ * In ls7a spec says that pm1_cnt register is 32bit width and ++ * that the upper 16bits are reserved and unused. ++ * PM1a_CNT_BLK = 2 in FADT so it is defined as uint16_t. ++ */ ++ ACPIREGS acpi_regs; ++ ++ MemoryRegion iomem; ++ MemoryRegion iomem_gpe; ++ MemoryRegion iomem_smi; ++ MemoryRegion iomem_reset; ++ ++ qemu_irq irq; /* SCI */ ++ ++ uint32_t pm_io_base; ++ Notifier powerdown_notifier; ++ ++ bool cpu_hotplug_legacy; ++ AcpiCpuHotplug gpe_cpu; ++ CPUHotplugState cpuhp_state; ++ ++ MemHotplugState acpi_memory_hotplug; ++ ++ uint8_t disable_s3; ++ uint8_t disable_s4; ++ uint8_t s4_val; ++} LS7APCIPMRegs; ++ ++void ls7a_pm_init(LS7APCIPMRegs *ls7a, qemu_irq *sci_irq); ++ ++void ls7a_pm_iospace_update(LS7APCIPMRegs *pm, uint32_t pm_io_base); ++extern const VMStateDescription vmstate_ls7a_pm; ++ ++void ls7a_pm_add_properties(Object *obj, LS7APCIPMRegs *pm, Error **errp); ++ ++void ls7a_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp); ++void ls7a_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp); ++void ls7a_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp); ++ ++void ls7a_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); ++ ++void ls7a_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev); ++#endif /* HW_ACPI_LS7A_H */ +-- +2.27.0 + diff --git a/0002-Support-rtc.patch b/0002-Support-rtc.patch new file mode 100644 index 0000000..082fcdf --- /dev/null +++ b/0002-Support-rtc.patch @@ -0,0 +1,370 @@ +From befa5ef7576fdbe2e729203538b066e5f87c3b8f Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Fri, 19 Aug 2022 23:15:49 -0400 +Subject: [PATCH 2/8] Support rtc. + +Change-Id: Idd50274dd2a6c00b21ec0cd099f8d115ab4fa449 +Signed-off-by: lixianglai +--- + hw/timer/Kconfig | 2 + + hw/timer/ls7a_rtc.c | 325 +++++++++++++++++++++++++++++++++++++++++++ + hw/timer/meson.build | 1 + + 3 files changed, 328 insertions(+) + create mode 100644 hw/timer/ls7a_rtc.c + +diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig +index 010be7ed1f..b395c72d7d 100644 +--- a/hw/timer/Kconfig ++++ b/hw/timer/Kconfig +@@ -60,3 +60,5 @@ config STELLARIS_GPTM + + config AVR_TIMER16 + bool ++config LS7A_RTC ++ bool +diff --git a/hw/timer/ls7a_rtc.c b/hw/timer/ls7a_rtc.c +new file mode 100644 +index 0000000000..756f2fc9ce +--- /dev/null ++++ b/hw/timer/ls7a_rtc.c +@@ -0,0 +1,325 @@ ++#include "qemu/osdep.h" ++#include "hw/sysbus.h" ++#include "hw/irq.h" ++#include "include/hw/register.h" ++#include "qemu/timer.h" ++#include "sysemu/sysemu.h" ++#include "qemu/cutils.h" ++#include "qemu/log.h" ++#include "qemu-common.h" ++#include "migration/vmstate.h" ++ ++#ifdef DEBUG_LS7A_RTC ++#define DPRINTF (fmt, ...) \ ++do { printf("ls7a_rtc: " fmt , ## __VA_ARGS__); } while (0) ++#else ++#define DPRINTF (fmt, ...) do {} while (0) ++#endif ++ ++ ++#define SYS_TOYTRIM 0x20 ++#define SYS_TOYWRITE0 0x24 ++#define SYS_TOYWRITE1 0x28 ++#define SYS_TOYREAD0 0x2C ++#define SYS_TOYREAD1 0x30 ++#define SYS_TOYMATCH0 0x34 ++#define SYS_TOYMATCH1 0x38 ++#define SYS_TOYMATCH2 0x3C ++#define SYS_RTCCTRL 0x40 ++#define SYS_RTCTRIM 0x60 ++#define SYS_RTCWRTIE0 0x64 ++#define SYS_RTCREAD0 0x68 ++#define SYS_RTCMATCH0 0x6C ++#define SYS_RTCMATCH1 0x70 ++#define SYS_RTCMATCH2 0x74 ++ ++/** ++ ** shift bits and filed mask ++ **/ ++#define TOY_MON_MASK 0x3f ++#define TOY_DAY_MASK 0x1f ++#define TOY_HOUR_MASK 0x1f ++#define TOY_MIN_MASK 0x3f ++#define TOY_SEC_MASK 0x3f ++#define TOY_MSEC_MASK 0xf ++ ++#define TOY_MON_SHIFT 26 ++#define TOY_DAY_SHIFT 21 ++#define TOY_HOUR_SHIFT 16 ++#define TOY_MIN_SHIFT 10 ++#define TOY_SEC_SHIFT 4 ++#define TOY_MSEC_SHIFT 0 ++ ++#define TOY_MATCH_YEAR_MASK 0x3f ++#define TOY_MATCH_MON_MASK 0xf ++#define TOY_MATCH_DAY_MASK 0x1f ++#define TOY_MATCH_HOUR_MASK 0x1f ++#define TOY_MATCH_MIN_MASK 0x3f ++#define TOY_MATCH_SEC_MASK 0x3f ++ ++ ++#define TOY_MATCH_YEAR_SHIFT 26 ++#define TOY_MATCH_MON_SHIFT 22 ++#define TOY_MATCH_DAY_SHIFT 17 ++#define TOY_MATCH_HOUR_SHIFT 12 ++#define TOY_MATCH_MIN_SHIFT 6 ++#define TOY_MATCH_SEC_SHIFT 0 ++ ++#define TOY_ENABLE_BIT (1U << 11) ++ ++#define TYPE_LS7A_RTC "ls7a_rtc" ++#define LS7A_RTC(obj) OBJECT_CHECK(LS7A_RTCState, (obj), TYPE_LS7A_RTC) ++ ++typedef struct LS7A_RTCState { ++ SysBusDevice parent_obj; ++ ++ MemoryRegion iomem; ++ QEMUTimer *timer; ++ /* Needed to preserve the tick_count across migration, even if the ++ * absolute value of the rtc_clock is different on the source and ++ * destination. ++ */ ++ int64_t offset; ++ int64_t data; ++ int64_t save_alarm_offset; ++ int tidx; ++ uint32_t toymatch[3]; ++ uint32_t toytrim; ++ uint32_t cntrctl; ++ uint32_t rtctrim; ++ uint32_t rtccount; ++ uint32_t rtcmatch[3]; ++ qemu_irq toy_irq; ++} LS7A_RTCState; ++ ++enum { ++TOYEN = 1UL << 11, ++RTCEN = 1UL << 13, ++}; ++ ++static uint64_t ls7a_rtc_read(void *opaque, hwaddr addr, ++ unsigned size) ++{ ++ LS7A_RTCState *s = (LS7A_RTCState *)opaque; ++ struct tm tm; ++ unsigned int val; ++ ++ val = 0; ++ ++ switch (addr) { ++ case SYS_TOYREAD0: ++ qemu_get_timedate(&tm, s->offset); ++ val = (((tm.tm_mon + 1) & TOY_MON_MASK) << TOY_MON_SHIFT) ++ | (((tm.tm_mday) & TOY_DAY_MASK) << TOY_DAY_SHIFT) ++ | (((tm.tm_hour) & TOY_HOUR_MASK) << TOY_HOUR_SHIFT) ++ | (((tm.tm_min) & TOY_MIN_MASK) << TOY_MIN_SHIFT) ++ | (((tm.tm_sec) & TOY_SEC_MASK) << TOY_SEC_SHIFT) | 0x0; ++ break; ++ case SYS_TOYREAD1: ++ qemu_get_timedate(&tm, s->offset); ++ val = tm.tm_year; ++ break; ++ case SYS_TOYMATCH0: ++ val = s->toymatch[0]; ++ break; ++ case SYS_TOYMATCH1: ++ val = s->toymatch[1]; ++ break; ++ case SYS_TOYMATCH2: ++ val = s->toymatch[2]; ++ break; ++ case SYS_RTCCTRL: ++ val = s->cntrctl; ++ break; ++ case SYS_RTCREAD0: ++ val = s->rtccount; ++ break; ++ case SYS_RTCMATCH0: ++ val = s->rtcmatch[0]; ++ break; ++ case SYS_RTCMATCH1: ++ val = s->rtcmatch[1]; ++ break; ++ case SYS_RTCMATCH2: ++ val = s->rtcmatch[2]; ++ break; ++ default: ++ val = 0; ++ break; ++ } ++ return val; ++} ++ ++ ++static void ls7a_rtc_write(void *opaque, hwaddr addr, ++ uint64_t val, unsigned size) ++{ ++ LS7A_RTCState *s = (LS7A_RTCState *)opaque; ++ struct tm tm; ++ int64_t alarm_offset, year_diff, expire_time; ++ ++ switch (addr) { ++ case SYS_TOYWRITE0: ++ qemu_get_timedate(&tm, s->offset); ++ tm.tm_sec = (val >> TOY_SEC_SHIFT) & TOY_SEC_MASK; ++ tm.tm_min = (val >> TOY_MIN_SHIFT) & TOY_MIN_MASK; ++ tm.tm_hour = (val >> TOY_HOUR_SHIFT) & TOY_HOUR_MASK; ++ tm.tm_mday = ((val >> TOY_DAY_SHIFT) & TOY_DAY_MASK); ++ tm.tm_mon = ((val >> TOY_MON_SHIFT) & TOY_MON_MASK) - 1; ++ s->offset = qemu_timedate_diff(&tm); ++ break; ++ case SYS_TOYWRITE1: ++ qemu_get_timedate(&tm, s->offset); ++ tm.tm_year = val; ++ s->offset = qemu_timedate_diff(&tm); ++ break; ++ case SYS_TOYMATCH0: ++ s->toymatch[0] = val; ++ qemu_get_timedate(&tm, s->offset); ++ tm.tm_sec = (val >> TOY_MATCH_SEC_SHIFT) & TOY_MATCH_SEC_MASK; ++ tm.tm_min = (val >> TOY_MATCH_MIN_SHIFT) & TOY_MATCH_MIN_MASK; ++ tm.tm_hour = ((val >> TOY_MATCH_HOUR_SHIFT) & TOY_MATCH_HOUR_MASK); ++ tm.tm_mday = ((val >> TOY_MATCH_DAY_SHIFT) & TOY_MATCH_DAY_MASK); ++ tm.tm_mon = ((val >> TOY_MATCH_MON_SHIFT) & TOY_MATCH_MON_MASK) - 1; ++ year_diff = ((val >> TOY_MATCH_YEAR_SHIFT) & TOY_MATCH_YEAR_MASK); ++ year_diff = year_diff - (tm.tm_year & TOY_MATCH_YEAR_MASK); ++ tm.tm_year = tm.tm_year + year_diff; ++ alarm_offset = qemu_timedate_diff(&tm) - s->offset; ++ if ((alarm_offset < 0) && (alarm_offset > -5)) { ++ alarm_offset = 0; ++ } ++ expire_time = qemu_clock_get_ms(rtc_clock); ++ expire_time += ((alarm_offset * 1000) + 100); ++ timer_mod(s->timer, expire_time); ++ break; ++ case SYS_TOYMATCH1: ++ s->toymatch[1] = val; ++ break; ++ case SYS_TOYMATCH2: ++ s->toymatch[2] = val; ++ break; ++ case SYS_RTCCTRL: ++ s->cntrctl = val; ++ break; ++ case SYS_RTCWRTIE0: ++ s->rtccount = val; ++ break; ++ case SYS_RTCMATCH0: ++ s->rtcmatch[0] = val; ++ break; ++ case SYS_RTCMATCH1: ++ val = s->rtcmatch[1]; ++ break; ++ case SYS_RTCMATCH2: ++ val = s->rtcmatch[2]; ++ break; ++ default: ++ break; ++ } ++} ++ ++static const MemoryRegionOps ls7a_rtc_ops = { ++ .read = ls7a_rtc_read, ++ .write = ls7a_rtc_write, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++ .valid = { ++ .min_access_size = 4, ++ .max_access_size = 4, ++ }, ++ ++}; ++ ++static void toy_timer(void *opaque) ++{ ++ LS7A_RTCState *s = (LS7A_RTCState *) opaque; ++ ++ if (s->cntrctl & TOY_ENABLE_BIT) { ++ qemu_irq_pulse(s->toy_irq); ++ } ++} ++ ++static void ls7a_rtc_realize(DeviceState *dev, Error **errp) ++{ ++ SysBusDevice *sbd = SYS_BUS_DEVICE(dev); ++ LS7A_RTCState *d = LS7A_RTC(sbd); ++ memory_region_init_io(&d->iomem, NULL, &ls7a_rtc_ops, ++ (void *)d, "ls7a_rtc", 0x100); ++ ++ sysbus_init_irq(sbd, &d->toy_irq); ++ ++ sysbus_init_mmio(sbd, &d->iomem); ++ d->timer = timer_new_ms(rtc_clock, toy_timer, d); ++ timer_mod(d->timer, qemu_clock_get_ms(rtc_clock) + 100); ++ d->offset = 0; ++} ++ ++static int ls7a_rtc_pre_save(void *opaque) ++{ ++ LS7A_RTCState *s = (LS7A_RTCState *)opaque; ++ struct tm tm; ++ int64_t year_diff, value; ++ ++ value = s->toymatch[0]; ++ qemu_get_timedate(&tm, s->offset); ++ tm.tm_sec = (value >> TOY_MATCH_SEC_SHIFT) & TOY_MATCH_SEC_MASK; ++ tm.tm_min = (value >> TOY_MATCH_MIN_SHIFT) & TOY_MATCH_MIN_MASK; ++ tm.tm_hour = ((value >> TOY_MATCH_HOUR_SHIFT) & TOY_MATCH_HOUR_MASK); ++ tm.tm_mday = ((value >> TOY_MATCH_DAY_SHIFT) & TOY_MATCH_DAY_MASK); ++ tm.tm_mon = ((value >> TOY_MATCH_MON_SHIFT) & TOY_MATCH_MON_MASK) - 1; ++ year_diff = ((value >> TOY_MATCH_YEAR_SHIFT) & TOY_MATCH_YEAR_MASK); ++ year_diff = year_diff - (tm.tm_year & TOY_MATCH_YEAR_MASK); ++ tm.tm_year = tm.tm_year + year_diff; ++ s->save_alarm_offset = qemu_timedate_diff(&tm) - s->offset; ++ ++ return 0; ++} ++ ++ ++static int ls7a_rtc_post_load(void *opaque, int version_id) ++{ ++ LS7A_RTCState *s = (LS7A_RTCState *)opaque; ++ int64_t expire_time; ++ ++ expire_time = qemu_clock_get_ms(rtc_clock) + (s->save_alarm_offset * 1000); ++ timer_mod(s->timer, expire_time); ++ ++ return 0; ++} ++ ++static const VMStateDescription vmstate_ls7a_rtc = { ++ .name = "ls7a_rtc", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .pre_save = ls7a_rtc_pre_save, ++ .post_load = ls7a_rtc_post_load, ++ .fields = (VMStateField[]) { ++ VMSTATE_INT64(offset, LS7A_RTCState), ++ VMSTATE_INT64(save_alarm_offset, LS7A_RTCState), ++ VMSTATE_UINT32(toymatch[0], LS7A_RTCState), ++ VMSTATE_UINT32(cntrctl, LS7A_RTCState), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++ ++static void ls7a_rtc_class_init(ObjectClass *klass, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(klass); ++ dc->vmsd = &vmstate_ls7a_rtc; ++ dc->realize = ls7a_rtc_realize; ++ dc->desc = "ls7a rtc"; ++} ++ ++static const TypeInfo ls7a_rtc_info = { ++ .name = TYPE_LS7A_RTC, ++ .parent = TYPE_SYS_BUS_DEVICE, ++ .instance_size = sizeof(LS7A_RTCState), ++ .class_init = ls7a_rtc_class_init, ++}; ++ ++static void ls7a_rtc_register_types(void) ++{ ++ type_register_static(&ls7a_rtc_info); ++} ++ ++type_init(ls7a_rtc_register_types) +diff --git a/hw/timer/meson.build b/hw/timer/meson.build +index 03092e2ceb..e841a2f6ee 100644 +--- a/hw/timer/meson.build ++++ b/hw/timer/meson.build +@@ -16,6 +16,7 @@ softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_mct.c')) + softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_pwm.c')) + softmmu_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_gptimer.c')) + softmmu_ss.add(when: 'CONFIG_HPET', if_true: files('hpet.c')) ++softmmu_ss.add(when: 'CONFIG_LS7A_RTC', if_true: files('ls7a_rtc.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')) +-- +2.27.0 + diff --git a/0003-Add-loongarch-machine.patch b/0003-Add-loongarch-machine.patch new file mode 100644 index 0000000..c1617ba --- /dev/null +++ b/0003-Add-loongarch-machine.patch @@ -0,0 +1,5752 @@ +From 2562504ad867de4a0539c261983c08cd5108bfe4 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Fri, 19 Aug 2022 23:39:00 -0400 +Subject: [PATCH 3/8] Add loongarch machine. + +Change-Id: I7e31f874c676b740269945d5e19c6bc836de6a99 +Signed-off-by: lixianglai +--- + hw/loongarch/Kconfig | 17 + + hw/loongarch/acpi-build.c | 783 ++++++++++++ + hw/loongarch/acpi-build.h | 16 + + hw/loongarch/apic.c | 675 +++++++++++ + hw/loongarch/ioapic.c | 422 +++++++ + hw/loongarch/iocsr.c | 219 ++++ + hw/loongarch/ipi.c | 267 +++++ + hw/loongarch/larch_3a.c | 2026 ++++++++++++++++++++++++++++++++ + hw/loongarch/larch_hotplug.c | 355 ++++++ + hw/loongarch/larch_int.c | 91 ++ + hw/loongarch/ls7a_nb.c | 352 ++++++ + hw/loongarch/meson.build | 15 + + include/hw/loongarch/bios.h | 5 + + include/hw/loongarch/cpudevs.h | 53 + + include/hw/loongarch/larch.h | 163 +++ + include/hw/loongarch/ls7a.h | 152 +++ + 16 files changed, 5611 insertions(+) + create mode 100644 hw/loongarch/Kconfig + create mode 100644 hw/loongarch/acpi-build.c + create mode 100644 hw/loongarch/acpi-build.h + create mode 100644 hw/loongarch/apic.c + create mode 100644 hw/loongarch/ioapic.c + create mode 100644 hw/loongarch/iocsr.c + create mode 100644 hw/loongarch/ipi.c + create mode 100644 hw/loongarch/larch_3a.c + create mode 100644 hw/loongarch/larch_hotplug.c + create mode 100644 hw/loongarch/larch_int.c + create mode 100644 hw/loongarch/ls7a_nb.c + create mode 100644 hw/loongarch/meson.build + create mode 100644 include/hw/loongarch/bios.h + create mode 100644 include/hw/loongarch/cpudevs.h + create mode 100644 include/hw/loongarch/larch.h + create mode 100644 include/hw/loongarch/ls7a.h + +diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig +new file mode 100644 +index 0000000000..3fe2677fda +--- /dev/null ++++ b/hw/loongarch/Kconfig +@@ -0,0 +1,17 @@ ++config LS7A_APIC ++ bool ++ ++config LS7A_RTC ++ bool ++ ++config LOONGSON3A ++ bool ++ ++config MEM_HOTPLUG ++ bool ++ ++config ACPI_LOONGARCH ++ bool ++ ++config E1000E_PCI ++ bool +diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c +new file mode 100644 +index 0000000000..6ba637be53 +--- /dev/null ++++ b/hw/loongarch/acpi-build.c +@@ -0,0 +1,783 @@ ++/* Support for generating ACPI tables and passing them to Guests ++ * ++ * Copyright (C) 2008-2010 Kevin O'Connor ++ * Copyright (C) 2006 Fabrice Bellard ++ * Copyright (C) 2013 Red Hat Inc ++ * ++ * Author: Michael S. Tsirkin ++ * ++ * 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 . ++ */ ++ ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include "qapi/qmp/qnum.h" ++#include "acpi-build.h" ++#include "qemu-common.h" ++#include "qemu/bitmap.h" ++#include "qemu/error-report.h" ++#include "hw/pci/pci.h" ++#include "hw/boards.h" ++#include "hw/core/cpu.h" ++#include "target/loongarch64/cpu.h" ++#include "hw/misc/pvpanic.h" ++#include "hw/timer/hpet.h" ++#include "hw/acpi/acpi-defs.h" ++#include "hw/acpi/acpi.h" ++#include "hw/acpi/cpu.h" ++#include "hw/nvram/fw_cfg.h" ++#include "hw/acpi/bios-linker-loader.h" ++#include "hw/loader.h" ++#include "hw/isa/isa.h" ++#include "hw/block/fdc.h" ++#include "hw/acpi/memory_hotplug.h" ++#include "sysemu/tpm.h" ++#include "hw/acpi/tpm.h" ++#include "hw/acpi/vmgenid.h" ++#include "sysemu/tpm_backend.h" ++#include "hw/rtc/mc146818rtc_regs.h" ++#include "sysemu/numa.h" ++#include "sysemu/runstate.h" ++#include "sysemu/reset.h" ++#include "migration/vmstate.h" ++#include "hw/mem/memory-device.h" ++#include "hw/acpi/utils.h" ++#include "hw/acpi/pci.h" ++/* Supported chipsets: */ ++#include "hw/acpi/aml-build.h" ++#include "hw/loongarch/larch.h" ++#include "hw/loongarch/ls7a.h" ++ ++#include "hw/acpi/ipmi.h" ++#include "hw/acpi/ls7a.h" ++ ++/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and ++ * -M pc-i440fx-2.0. Even if the actual amount of AML generated grows ++ * a little bit, there should be plenty of free space since the DSDT ++ * shrunk by ~1.5k between QEMU 2.0 and QEMU 2.1. ++ */ ++#define ACPI_BUILD_ALIGN_SIZE 0x1000 ++ ++#define ACPI_BUILD_TABLE_SIZE 0x20000 ++ ++/* #define DEBUG_ACPI_BUILD */ ++#ifdef DEBUG_ACPI_BUILD ++#define ACPI_BUILD_DPRINTF(fmt, ...) \ ++ do {printf("ACPI_BUILD: " fmt, ## __VA_ARGS__); } while (0) ++#else ++#define ACPI_BUILD_DPRINTF(fmt, ...) ++#endif ++ ++/* Default IOAPIC ID */ ++#define ACPI_BUILD_IOAPIC_ID 0x0 ++ ++/* PCI fw r3.0 MCFG table. */ ++/* Subtable */ ++ ++typedef struct AcpiMiscInfo { ++ bool is_piix4; ++ bool has_hpet; ++ TPMVersion tpm_version; ++ const unsigned char *dsdt_code; ++ unsigned dsdt_size; ++ uint16_t pvpanic_port; ++ uint16_t applesmc_io_base; ++} AcpiMiscInfo; ++ ++typedef struct AcpiBuildPciBusHotplugState { ++ GArray *device_table; ++ GArray *notify_table; ++ struct AcpiBuildPciBusHotplugState *parent; ++ bool pcihp_bridge_en; ++} AcpiBuildPciBusHotplugState; ++ ++static void init_common_fadt_data(AcpiFadtData *data) ++{ ++ AmlAddressSpace as = AML_AS_SYSTEM_MEMORY; ++ uint64_t base = LS7A_ACPI_REG_BASE; ++ AcpiFadtData fadt = { ++ .rev = 3, ++ .flags = ++ (1 << ACPI_FADT_F_WBINVD) | ++ (1 << ACPI_FADT_F_PROC_C1) | ++ (1 << ACPI_FADT_F_SLP_BUTTON) | ++ (1 << ACPI_FADT_F_TMR_VAL_EXT) | ++ (1 << ACPI_FADT_F_RESET_REG_SUP) , ++ .plvl2_lat = 0xfff /* C2 state not supported */, ++ .plvl3_lat = 0xfff /* C3 state not supported */, ++ .smi_cmd = 0x00, ++ .sci_int = ACPI_SCI_IRQ, ++ .acpi_enable_cmd = 0x00, ++ .acpi_disable_cmd = 0x00, ++ .pm1a_evt = { .space_id = as, .bit_width = 8 * 8, ++ .address = base + LS7A_PM_EVT_BLK }, ++ .pm1a_cnt = { .space_id = as, .bit_width = 4 * 8, ++ .address = base + LS7A_PM_CNT_BLK }, ++ .pm_tmr = { .space_id = as, .bit_width = 4 * 8, ++ .address = base + LS7A_PM_TMR_BLK }, ++ .gpe0_blk = { .space_id = as, .bit_width = 8 * 8, ++ .address = base + LS7A_GPE0_STS_REG}, ++ .reset_reg = { .space_id = as, .bit_width = 4 * 8, ++ .address = base + LS7A_GPE0_RESET_REG}, ++ .reset_val = 0x1, ++ }; ++ *data = fadt; ++} ++ ++static void acpi_align_size(GArray *blob, unsigned align) ++{ ++ /* Align size to multiple of given size. This reduces the chance ++ * we need to change size in the future (breaking cross version migration). ++ */ ++ g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align)); ++} ++ ++/* FACS */ ++static void ++build_facs(GArray *table_data) ++{ ++ const char *sig = "FACS"; ++ const uint8_t reserved[40] = {}; ++ ++ g_array_append_vals(table_data, sig, 4); /* Signature */ ++ build_append_int_noprefix(table_data, 64, 4); /* Length */ ++ build_append_int_noprefix(table_data, 0, 4); /* Hardware Signature */ ++ build_append_int_noprefix(table_data, 0, 4); /* Firmware Waking Vector */ ++ build_append_int_noprefix(table_data, 0, 4); /* Global Lock */ ++ build_append_int_noprefix(table_data, 0, 4); /* Flags */ ++ g_array_append_vals(table_data, reserved, 40); /* Reserved */ ++} ++ ++void ls7a_madt_cpu_entry(AcpiDeviceIf *adev, int uid, ++ const CPUArchIdList *apic_ids, GArray *entry, bool force_enabled) ++{ ++ uint32_t apic_id = apic_ids->cpus[uid].arch_id; ++ /* Flags – Local APIC Flags */ ++ uint32_t flags = apic_ids->cpus[uid].cpu != NULL || force_enabled ? ++ 1 /* Enabled */ : 0; ++ ++ /* Rev 1.0b, Table 5-13 Processor Local APIC Structure */ ++ build_append_int_noprefix(entry, 0, 1); /* Type */ ++ build_append_int_noprefix(entry, 8, 1); /* Length */ ++ build_append_int_noprefix(entry, uid, 1); /* ACPI Processor ID */ ++ build_append_int_noprefix(entry, apic_id, 1); /* APIC ID */ ++ build_append_int_noprefix(entry, flags, 4); /* Flags */ ++} ++static void build_ioapic(GArray *entry, uint8_t id, uint32_t addr, uint32_t irq) ++{ ++ /* Rev 1.0b, 5.2.8.2 IO APIC */ ++ build_append_int_noprefix(entry, 1, 1); /* Type */ ++ build_append_int_noprefix(entry, 12, 1); /* Length */ ++ build_append_int_noprefix(entry, id, 1); /* IO APIC ID */ ++ build_append_int_noprefix(entry, 0, 1); /* Reserved */ ++ build_append_int_noprefix(entry, addr, 4); /* IO APIC Address */ ++ build_append_int_noprefix(entry, irq, 4); /* System Vector Base */ ++} ++ ++static void ++build_madt(GArray *table_data, BIOSLinker *linker, LoongarchMachineState *lsms) ++{ ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ MachineClass *mc = MACHINE_GET_CLASS(lsms); ++ const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(lsms)); ++ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(lsms->acpi_dev); ++ AcpiDeviceIf *adev = ACPI_DEVICE_IF(lsms->acpi_dev); ++ int i; ++ AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lsms->oem_id, ++ .oem_table_id = lsms->oem_table_id}; ++ ++ acpi_table_begin(&table, table_data); ++ ++ /* Local APIC Address */ ++ build_append_int_noprefix(table_data, 0, 4); ++ build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */ ++ ++ ++ for (i = 0; i < apic_ids->len; i++) { ++ adevc->madt_cpu(adev, i, apic_ids, table_data, false); ++ } ++ ++ ++ build_ioapic(table_data, ACPI_BUILD_IOAPIC_ID, lsmc->ls7a_ioapic_reg_base, LOONGARCH_PCH_IRQ_BASE); ++ ++ /* Rev 1.0b, 5.2.8.3.3 Local APIC NMI */ ++ build_append_int_noprefix(table_data, 3, 1); /* Type */ ++ build_append_int_noprefix(table_data, 6, 1); /* Length */ ++ /* ACPI Processor ID */ ++ build_append_int_noprefix(table_data, 0xFF /* all processors */, 1); ++ build_append_int_noprefix(table_data, 0, 2); /* Flags */ ++ /* Local APIC INTI# */ ++ build_append_int_noprefix(table_data, 1 /* ACPI_LINT1 */, 1); ++ ++ /* Rev 1.0b, 5.2.8.3.3 Local APIC NMI */ ++ build_append_int_noprefix(table_data, 4, 1); /* Type */ ++ build_append_int_noprefix(table_data, 6, 1); /* Length */ ++ /* ACPI Processor ID */ ++ build_append_int_noprefix(table_data, 0xFF /* all processors */, 1); ++ build_append_int_noprefix(table_data, 0, 2); /* Flags */ ++ /* Local APIC INTI# */ ++ build_append_int_noprefix(table_data, 1 /* ACPI_LINT1 */, 1); ++ ++ ++ acpi_table_end(linker, &table); ++} ++ ++static void ++build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) ++{ ++ uint64_t i, mem_len, mem_base; ++ MachineClass *mc = MACHINE_GET_CLASS(machine); ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine); ++ int nb_numa_nodes = machine->numa_state->num_nodes; ++ NodeInfo *numa_info = machine->numa_state->nodes; ++ AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lsms->oem_id, ++ .oem_table_id = lsms->oem_table_id}; ++ ++ acpi_table_begin(&table, table_data); ++ build_append_int_noprefix(table_data, 1, 4); /* Reserved */ ++ build_append_int_noprefix(table_data, 0, 8); /* Reserved */ ++ ++ for (i = 0; i < apic_ids->len; ++i) { ++ /* 5.2.15.1 Processor Local APIC/SAPIC Affinity Structure */ ++ build_append_int_noprefix(table_data, 0, 1); /* Type */ ++ build_append_int_noprefix(table_data, 16, 1); /* Length */ ++ /* Proximity Domain [7:0] */ ++ build_append_int_noprefix(table_data, apic_ids->cpus[i].props.node_id, 1); ++ build_append_int_noprefix(table_data, apic_ids->cpus[i].arch_id, 1); /* APIC ID */ ++ /* Flags, Table 5-36 */ ++ build_append_int_noprefix(table_data, 1, 4); ++ build_append_int_noprefix(table_data, 0, 1); /* Local SAPIC EID */ ++ /* Proximity Domain [31:8] */ ++ build_append_int_noprefix(table_data, 0, 3); ++ build_append_int_noprefix(table_data, 0, 4); /* Reserved */ ++ } ++ ++ /* node0 */ ++ mem_base = (uint64_t)0; ++ mem_len = 0x10000000; ++ build_srat_memory(table_data, mem_base, mem_len, ++ 0, MEM_AFFINITY_ENABLED); ++ mem_base = 0x90000000; ++ if (!nb_numa_nodes) { ++ mem_len = machine->ram_size - 0x10000000; ++ } else { ++ mem_len = numa_info[0].node_mem - 0x10000000; ++ } ++ ++ build_srat_memory(table_data, mem_base, mem_len, ++ 0, MEM_AFFINITY_ENABLED); ++ mem_base += mem_len; ++ ++ /* node1 ~ nodemax */ ++ for (i = 1; i < nb_numa_nodes; ++i) { ++ mem_len = numa_info[i].node_mem; ++ build_srat_memory(table_data, mem_base, mem_len, ++ i, MEM_AFFINITY_ENABLED); ++ mem_base += mem_len; ++ } ++ ++ if (lsms->hotplug_memory_size) { ++ build_srat_memory(table_data, machine->device_memory->base, ++ lsms->hotplug_memory_size, 0, ++ MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); ++ } ++ ++ acpi_table_end(linker, &table); ++ ++} ++ ++typedef ++struct AcpiBuildState { ++ /* Copy of table in RAM (for patching). */ ++ MemoryRegion *table_mr; ++ /* Is table patched? */ ++ uint8_t patched; ++ void *rsdp; ++ MemoryRegion *rsdp_mr; ++ MemoryRegion *linker_mr; ++} AcpiBuildState; ++ ++static void build_ls7a_pci0_int(Aml *table) ++{ ++ Aml *sb_scope = aml_scope("_SB"); ++ Aml *pci0_scope = aml_scope("PCI0"); ++ Aml *prt_pkg = aml_varpackage(128); ++ int slot, pin; ++ ++ for (slot = 0; slot < PCI_SLOT_MAX; slot++) { ++ for (pin = 0; pin < PCI_NUM_PINS; pin++) { ++ Aml *pkg = aml_package(4); ++ aml_append(pkg, aml_int((slot << 16) | 0xFFFF)); ++ aml_append(pkg, aml_int(pin)); ++ aml_append(pkg, aml_int(0)); ++ aml_append(pkg, aml_int(LOONGARCH_PCH_IRQ_BASE + 16 + (slot * 4 + pin) % 16)); ++ aml_append(prt_pkg, pkg); ++ } ++ } ++ aml_append(pci0_scope, ++ aml_name_decl("_PRT", prt_pkg)); ++ ++ aml_append(sb_scope, pci0_scope); ++ ++ aml_append(table, sb_scope); ++} ++ ++static void build_dbg_aml(Aml *table) ++{ ++ Aml *field; ++ Aml *method; ++ Aml *while_ctx; ++ Aml *scope = aml_scope("\\"); ++ Aml *buf = aml_local(0); ++ Aml *len = aml_local(1); ++ Aml *idx = aml_local(2); ++ ++ aml_append(scope, ++ aml_operation_region("DBG", AML_SYSTEM_IO, aml_int(0x0402), 0x01)); ++ field = aml_field("DBG", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); ++ aml_append(field, aml_named_field("DBGB", 8)); ++ aml_append(scope, field); ++ ++ method = aml_method("DBUG", 1, AML_NOTSERIALIZED); ++ ++ aml_append(method, aml_to_hexstring(aml_arg(0), buf)); ++ aml_append(method, aml_to_buffer(buf, buf)); ++ aml_append(method, aml_subtract(aml_sizeof(buf), aml_int(1), len)); ++ aml_append(method, aml_store(aml_int(0), idx)); ++ ++ while_ctx = aml_while(aml_lless(idx, len)); ++ aml_append(while_ctx, ++ aml_store(aml_derefof(aml_index(buf, idx)), aml_name("DBGB"))); ++ aml_append(while_ctx, aml_increment(idx)); ++ aml_append(method, while_ctx); ++ ++ aml_append(method, aml_store(aml_int(0x0A), aml_name("DBGB"))); ++ aml_append(scope, method); ++ ++ aml_append(table, scope); ++} ++ ++static Aml *build_ls7a_osc_method(void) ++{ ++ Aml *if_ctx; ++ Aml *if_ctx2; ++ Aml *else_ctx; ++ Aml *method; ++ Aml *a_cwd1 = aml_name("CDW1"); ++ Aml *a_ctrl = aml_local(0); ++ ++ method = aml_method("_OSC", 4, AML_NOTSERIALIZED); ++ aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1")); ++ ++ if_ctx = aml_if(aml_equal( ++ aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766"))); ++ aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2")); ++ aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3")); ++ ++ aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl)); ++ ++ /* ++ * Always allow native PME, AER (no dependencies) ++ * Allow SHPC (PCI bridges can have SHPC controller) ++ */ ++ aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl)); ++ ++ if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1)))); ++ /* Unknown revision */ ++ aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1)); ++ aml_append(if_ctx, if_ctx2); ++ ++ if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl))); ++ /* Capabilities bits were masked */ ++ aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1)); ++ aml_append(if_ctx, if_ctx2); ++ ++ /* Update DWORD3 in the buffer */ ++ aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3"))); ++ aml_append(method, if_ctx); ++ ++ else_ctx = aml_else(); ++ /* Unrecognized UUID */ ++ aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1)); ++ aml_append(method, else_ctx); ++ ++ aml_append(method, aml_return(aml_arg(3))); ++ return method; ++} ++ ++static void build_ls7a_rtc_device_aml(Aml *table) ++{ ++ Aml *dev; ++ Aml *crs; ++ uint32_t rtc_irq = LS7A_RTC_IRQ; ++ ++ Aml *scope = aml_scope("_SB"); ++ dev = aml_device("RTC"); ++ aml_append(dev, aml_name_decl("_HID", aml_string("LOON0001"))); ++ crs = aml_resource_template(); ++ aml_append(crs, ++ aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, ++ AML_NON_CACHEABLE, AML_READ_WRITE, ++ 0, LS7A_RTC_REG_BASE, ++ LS7A_RTC_REG_BASE + LS7A_RTC_LEN - 1, 0, LS7A_RTC_LEN)); ++ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, ++ AML_EXCLUSIVE, &rtc_irq, 1)); ++ ++ aml_append(dev, aml_name_decl("_CRS", crs)); ++ aml_append(scope, dev); ++ aml_append(table, scope); ++} ++ ++static void build_ls7a_uart_device_aml(Aml *table) ++{ ++ Aml *dev; ++ Aml *crs; ++ Aml *pkg0, *pkg1, *pkg2; ++ uint32_t uart_irq = LS7A_UART_IRQ; ++ ++ Aml *scope = aml_scope("_SB"); ++ dev = aml_device("COMA"); ++ aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501"))); ++ aml_append(dev, aml_name_decl("_UID", aml_int(0))); ++ aml_append(dev, aml_name_decl("_CCA", aml_int(1))); ++ crs = aml_resource_template(); ++ aml_append(crs, ++ aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, ++ AML_NON_CACHEABLE, AML_READ_WRITE, ++ 0, LS7A_UART_BASE, LS7A_UART_BASE + LS7A_UART_LEN - 1, 0, 0x8)); ++ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, ++ AML_EXCLUSIVE, &uart_irq, 1)); ++ aml_append(dev, aml_name_decl("_CRS", crs)); ++ pkg0 = aml_package(0x2); ++ aml_append(pkg0, aml_int(0x01F78A40)); ++ aml_append(pkg0, aml_string("clock-frenquency")); ++ pkg1 = aml_package(0x1); ++ aml_append(pkg1, pkg0); ++ pkg2 = aml_package(0x2); ++ aml_append(pkg2, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301")); ++ aml_append(pkg2, pkg1); ++ ++ aml_append(dev, aml_name_decl("_DSD", pkg2)); ++ ++ aml_append(scope, dev); ++ aml_append(table, scope); ++} ++ ++static void ++build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) ++{ ++ Aml *dsdt, *sb_scope, *scope, *dev, *crs, *pkg; ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ uint32_t nr_mem = machine->ram_slots; ++ uint64_t base = LS7A_ACPI_REG_BASE; ++ int root_bus_limit = PCIE_MMCFG_BUS(LS_PCIECFG_SIZE - 1); ++ AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lsms->oem_id, ++ .oem_table_id = lsms->oem_table_id}; ++ ++ acpi_table_begin(&table, table_data); ++ dsdt = init_aml_allocator(); ++ ++ build_dbg_aml(dsdt); ++ ++ sb_scope = aml_scope("_SB"); ++ dev = aml_device("PCI0"); ++ aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); ++ aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); ++ aml_append(dev, aml_name_decl("_ADR", aml_int(0))); ++ aml_append(dev, aml_name_decl("_BBN", aml_int(0))); ++ aml_append(dev, aml_name_decl("_UID", aml_int(1))); ++ aml_append(dev, build_ls7a_osc_method()); ++ aml_append(sb_scope, dev); ++ aml_append(dsdt, sb_scope); ++ ++ build_ls7a_pci0_int(dsdt); ++ build_ls7a_rtc_device_aml(dsdt); ++ build_ls7a_uart_device_aml(dsdt); ++ ++ if (lsms->acpi_dev) { ++ CPUHotplugFeatures opts = { ++ .acpi_1_compatible = true, .has_legacy_cphp = false ++ }; ++ build_cpus_aml(dsdt, machine, opts, CPU_HOTPLUG_BASE, ++ "\\_SB.PCI0", "\\_GPE._E02"); ++ ++ build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0", ++ "\\_GPE._E03", AML_SYSTEM_MEMORY, ++ MEMORY_HOTPLUG_BASE); ++ } ++ ++ scope = aml_scope("_GPE"); ++ { ++ aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006"))); ++ } ++ aml_append(dsdt, scope); ++ ++ scope = aml_scope("\\_SB.PCI0"); ++ /* build PCI0._CRS */ ++ crs = aml_resource_template(); ++ aml_append(crs, ++ aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE, ++ 0x0000, 0x0, root_bus_limit, ++ 0x0000, root_bus_limit + 1)); ++ aml_append(crs, ++ aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED, ++ AML_POS_DECODE, AML_ENTIRE_RANGE, ++ 0x0000, 0x4000, 0xFFFF, 0x0000, 0xC000)); ++ aml_append(crs, ++ aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, ++ AML_CACHEABLE, AML_READ_WRITE, ++ 0, 0x40000000, 0x7FFFFFFF, 0, 0x40000000)); ++ aml_append(scope, aml_name_decl("_CRS", crs)); ++ ++ /* reserve GPE0 block resources */ ++ dev = aml_device("GPE0"); ++ aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06"))); ++ aml_append(dev, aml_name_decl("_UID", aml_string("GPE0 resources"))); ++ /* device present, functioning, decoding, not shown in UI */ ++ aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); ++ crs = aml_resource_template(); ++ aml_append(crs, ++ aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, ++ AML_CACHEABLE, AML_READ_WRITE, ++ 0, base + LS7A_GPE0_STS_REG, ++ base + LS7A_GPE0_STS_REG + 0x3, 0, 0x4)); ++ aml_append(dev, aml_name_decl("_CRS", crs)); ++ aml_append(scope, dev); ++ aml_append(dsdt, scope); ++ ++ scope = aml_scope("\\"); ++ pkg = aml_package(4); ++ aml_append(pkg, aml_int(7)); /* PM1a_CNT.SLP_TYP */ ++ aml_append(pkg, aml_int(7)); /* PM1b_CNT.SLP_TYP not impl. */ ++ aml_append(pkg, aml_int(0)); /* reserved */ ++ aml_append(pkg, aml_int(0)); /* reserved */ ++ aml_append(scope, aml_name_decl("_S5", pkg)); ++ aml_append(dsdt, scope); ++ ++ /* copy AML table into ACPI tables blob and patch header there */ ++ g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len); ++ acpi_table_end(linker, &table); ++ free_aml_allocator(); ++} ++ ++ ++static ++void acpi_build(AcpiBuildTables *tables, MachineState *machine) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ GArray *table_offsets; ++ AcpiFadtData fadt_data; ++ unsigned facs, rsdt, fadt, dsdt; ++ uint8_t *u; ++ size_t aml_len = 0; ++ GArray *tables_blob = tables->table_data; ++ ++ init_common_fadt_data(&fadt_data); ++ ++ table_offsets = g_array_new(false, true /* clear */, ++ sizeof(uint32_t)); ++ ACPI_BUILD_DPRINTF("init ACPI tables\n"); ++ ++ bios_linker_loader_alloc(tables->linker, ++ ACPI_BUILD_TABLE_FILE, tables_blob, ++ 64 /* Ensure FACS is aligned */, ++ false /* high memory */); ++ ++ /* ++ * FACS is pointed to by FADT. ++ * We place it first since it's the only table that has alignment ++ * requirements. ++ */ ++ facs = tables_blob->len; ++ build_facs(tables_blob); ++ ++ /* DSDT is pointed to by FADT */ ++ dsdt = tables_blob->len; ++ build_dsdt(tables_blob, tables->linker, MACHINE(qdev_get_machine())); ++ ++ /* Count the size of the DSDT and SSDT, we will need it for legacy ++ * sizing of ACPI tables. ++ */ ++ aml_len += tables_blob->len - dsdt; ++ ++ /* ACPI tables pointed to by RSDT */ ++ fadt = tables_blob->len; ++ acpi_add_table(table_offsets, tables_blob); ++ fadt_data.facs_tbl_offset = &facs; ++ fadt_data.dsdt_tbl_offset = &dsdt; ++ fadt_data.xdsdt_tbl_offset = &dsdt; ++ build_fadt(tables_blob, tables->linker, &fadt_data, ++ "LOONGS", "TP-R00"); ++ aml_len += tables_blob->len - fadt; ++ ++ acpi_add_table(table_offsets, tables_blob); ++ build_madt(tables_blob, tables->linker, lsms); ++ ++ acpi_add_table(table_offsets, tables_blob); ++ build_srat(tables_blob, tables->linker, machine); ++ if (machine->numa_state->have_numa_distance) { ++ acpi_add_table(table_offsets, tables_blob); ++ build_slit(tables_blob, tables->linker, machine, lsms->oem_id, ++ lsms->oem_table_id); ++ } ++ ++ /* Build mcfg */ ++ acpi_add_table(table_offsets, tables_blob); ++ { ++ AcpiMcfgInfo mcfg = { ++ .base = LS_PCIECFG_BASE, ++ .size = LS_PCIECFG_SIZE, ++ }; ++ build_mcfg(tables_blob, tables->linker, &mcfg, lsms->oem_id, ++ lsms->oem_table_id); ++ } ++ ++ /* Add tables supplied by user (if any) */ ++ for (u = acpi_table_first(); u; u = acpi_table_next(u)) { ++ unsigned len = acpi_table_len(u); ++ ++ acpi_add_table(table_offsets, tables_blob); ++ g_array_append_vals(tables_blob, u, len); ++ } ++ ++ /* RSDT is pointed to by RSDP */ ++ rsdt = tables_blob->len; ++ build_rsdt(tables_blob, tables->linker, table_offsets, ++ "LOONGS", "TP-R00"); ++ ++ /* RSDP is in FSEG memory, so allocate it separately */ ++ { ++ AcpiRsdpData rsdp_data = { ++ .revision = 0, ++ .oem_id = lsms->oem_id, ++ .xsdt_tbl_offset = NULL, ++ .rsdt_tbl_offset = &rsdt, ++ }; ++ build_rsdp(tables->rsdp, tables->linker, &rsdp_data); ++ } ++ acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE); ++ ++ /* Cleanup memory that's no longer used. */ ++ g_array_free(table_offsets, true); ++} ++ ++static void acpi_ram_update(MemoryRegion *mr, GArray *data) ++{ ++ uint32_t size = acpi_data_len(data); ++ ++ /* Make sure RAM size is correct - ++ in case it got changed e.g. by migration */ ++ memory_region_ram_resize(mr, size, &error_abort); ++ ++ memcpy(memory_region_get_ram_ptr(mr), data->data, size); ++ memory_region_set_dirty(mr, 0, size); ++} ++ ++static void acpi_build_update(void *build_opaque) ++{ ++ AcpiBuildState *build_state = build_opaque; ++ AcpiBuildTables tables; ++ ++ /* No state to update or already patched? Nothing to do. */ ++ if (!build_state || build_state->patched) { ++ return; ++ } ++ build_state->patched = 1; ++ ++ acpi_build_tables_init(&tables); ++ ++ acpi_build(&tables, MACHINE(qdev_get_machine())); ++ ++ acpi_ram_update(build_state->table_mr, tables.table_data); ++ ++ if (build_state->rsdp) { ++ memcpy(build_state->rsdp, tables.rsdp->data, ++ acpi_data_len(tables.rsdp)); ++ } else { ++ acpi_ram_update(build_state->rsdp_mr, tables.rsdp); ++ } ++ ++ acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob); ++ acpi_build_tables_cleanup(&tables, true); ++} ++ ++static void acpi_build_reset(void *build_opaque) ++{ ++ AcpiBuildState *build_state = build_opaque; ++ build_state->patched = 0; ++} ++ ++static const VMStateDescription vmstate_acpi_build = { ++ .name = "acpi_build", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT8(patched, AcpiBuildState), ++ VMSTATE_END_OF_LIST() ++ }, ++}; ++ ++void loongarch_acpi_setup(void) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); ++ AcpiBuildTables tables; ++ AcpiBuildState *build_state; ++ ++ if (!lsms->fw_cfg) { ++ ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n"); ++ return; ++ } ++ ++ if (!lsms->acpi_build_enabled) { ++ ACPI_BUILD_DPRINTF("ACPI build disabled. Bailing out.\n"); ++ return; ++ } ++ ++ if (!loongarch_is_acpi_enabled(lsms)) { ++ ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n"); ++ return; ++ } ++ ++ build_state = g_malloc0(sizeof *build_state); ++ ++ acpi_build_tables_init(&tables); ++ acpi_build(&tables, MACHINE(lsms)); ++ ++ /* Now expose it all to Guest */ ++ build_state->table_mr = acpi_add_rom_blob(acpi_build_update, build_state, ++ tables.table_data, ++ ACPI_BUILD_TABLE_FILE); ++ assert(build_state->table_mr != NULL); ++ ++ build_state->linker_mr = ++ acpi_add_rom_blob(acpi_build_update, build_state, tables.linker->cmd_blob, ++ "etc/table-loader"); ++ ++ fw_cfg_add_file(lsms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, ++ tables.tcpalog->data, acpi_data_len(tables.tcpalog)); ++ ++ build_state->rsdp = NULL; ++ build_state->rsdp_mr = acpi_add_rom_blob(acpi_build_update, build_state, tables.rsdp, ++ ACPI_BUILD_RSDP_FILE); ++ ++ qemu_register_reset(acpi_build_reset, build_state); ++ acpi_build_reset(build_state); ++ vmstate_register(NULL, 0, &vmstate_acpi_build, build_state); ++ ++ /* Cleanup tables but don't free the memory: we track it ++ * in build_state. ++ */ ++ acpi_build_tables_cleanup(&tables, false); ++} +diff --git a/hw/loongarch/acpi-build.h b/hw/loongarch/acpi-build.h +new file mode 100644 +index 0000000000..a914268bbe +--- /dev/null ++++ b/hw/loongarch/acpi-build.h +@@ -0,0 +1,16 @@ ++ ++#ifndef HW_LARCH_ACPI_BUILD_H ++#define HW_LARCH_ACPI_BUILD_H ++ ++#define EFI_ACPI_OEM_ID "LARCH" ++#define EFI_ACPI_OEM_TABLE_ID "LARCH" /* OEM table id 8 bytes long */ ++#define EFI_ACPI_OEM_REVISION 0x00000002 ++#define EFI_ACPI_CREATOR_ID "LINUX" ++#define EFI_ACPI_CREATOR_REVISION 0x01000013 ++ ++#define ACPI_COMPATIBLE_1_0 0 ++#define ACPI_COMPATIBLE_2_0 1 ++ ++void loongarch_acpi_setup(void); ++ ++#endif +diff --git a/hw/loongarch/apic.c b/hw/loongarch/apic.c +new file mode 100644 +index 0000000000..d6ba2a2cec +--- /dev/null ++++ b/hw/loongarch/apic.c +@@ -0,0 +1,675 @@ ++/* ++ * Loongarch 3A5000 interrupt controller emulation ++ * ++ * Copyright (C) 2020 Lu Zeng ++ * ++ * 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/boards.h" ++#include "hw/irq.h" ++#include "hw/loongarch/cpudevs.h" ++#include "hw/sysbus.h" ++#include "qemu/host-utils.h" ++#include "qemu/error-report.h" ++#include "sysemu/kvm.h" ++#include "hw/hw.h" ++#include "hw/irq.h" ++#include "target/loongarch64/cpu.h" ++#include "exec/address-spaces.h" ++#include "hw/loongarch/larch.h" ++#include "migration/vmstate.h" ++ ++#define DEBUG_APIC 0 ++ ++#define DPRINTF(fmt, ...) \ ++do { \ ++ if (DEBUG_APIC) { \ ++ fprintf(stderr, "APIC: " fmt , ## __VA_ARGS__); \ ++ } \ ++} while (0) ++ ++#define APIC_OFFSET 0x400 ++#define APIC_BASE (0x1f010000ULL) ++#define EXTIOI_NODETYPE_START (0x4a0 - APIC_OFFSET) ++#define EXTIOI_NODETYPE_END (0x4c0 - APIC_OFFSET) ++#define EXTIOI_IPMAP_START (0x4c0 - APIC_OFFSET) ++#define EXTIOI_IPMAP_END (0x4c8 - APIC_OFFSET) ++#define EXTIOI_ENABLE_START (0x600 - APIC_OFFSET) ++#define EXTIOI_ENABLE_END (0x620 - APIC_OFFSET) ++#define EXTIOI_BOUNCE_START (0x680 - APIC_OFFSET) ++#define EXTIOI_BOUNCE_END (0x6a0 - APIC_OFFSET) ++#define EXTIOI_ISR_START (0x700 - APIC_OFFSET) ++#define EXTIOI_ISR_END (0x720 - APIC_OFFSET) ++#define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET) ++#define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET) ++#define EXTIOI_COREISR_START (0x10000) ++#define EXTIOI_COREISR_END (EXTIOI_COREISR_START + 0x10000) ++ ++static int ext_irq_pre_save(void *opaque) ++{ ++#ifdef CONFIG_KVM ++ apicState *apic = opaque; ++ struct loongarch_kvm_irqchip *chip; ++ struct kvm_loongarch_ls3a_extirq_state *kstate; ++ int ret, length, i, vcpuid; ++#endif ++ if (!kvm_irqchip_in_kernel()) { ++ return 0; ++ } ++#ifdef CONFIG_KVM ++ length = sizeof(struct loongarch_kvm_irqchip) + ++ sizeof(struct kvm_loongarch_ls3a_extirq_state); ++ chip = g_malloc0(length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS3A_EXTIRQ; ++ chip->len = length; ++ ++ ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); ++ abort(); ++ } ++ ++ kstate = (struct kvm_loongarch_ls3a_extirq_state *)chip->data; ++ for (i = 0; i < EXTIOI_IRQS_BITMAP_SIZE; i++) { ++ apic->ext_en[i] = kstate->ext_en_r.reg_u8[i]; ++ apic->ext_bounce[i] = kstate->bounce_r.reg_u8[i]; ++ apic->ext_isr[i] = kstate->ext_isr_r.reg_u8[i]; ++ for (vcpuid = 0; vcpuid < MAX_CORES; vcpuid++) { ++ apic->ext_coreisr[vcpuid][i] = kstate->ext_core_isr_r.reg_u8[vcpuid][i]; ++ } ++ } ++ for (i = 0; i < EXTIOI_IRQS_IPMAP_SIZE; i++) { ++ apic->ext_ipmap[i] = kstate->ip_map_r.reg_u8[i]; ++ } ++ for (i = 0; i < EXTIOI_IRQS; i++) { ++ apic->ext_coremap[i] = kstate->core_map_r.reg_u8[i];; ++ } ++ for (i = 0; i < 16; i++) { ++ apic->ext_nodetype[i] = kstate->node_type_r.reg_u16[i]; ++ } ++ g_free(chip); ++#endif ++ return 0; ++} ++ ++static int ext_irq_post_load(void *opaque, int version) ++{ ++#ifdef CONFIG_KVM ++ apicState *apic = opaque; ++ struct loongarch_kvm_irqchip *chip; ++ struct kvm_loongarch_ls3a_extirq_state *kstate; ++ int ret, length, i, vcpuid; ++#endif ++ if (!kvm_irqchip_in_kernel()) { ++ return 0; ++ } ++#ifdef CONFIG_KVM ++ length = sizeof(struct loongarch_kvm_irqchip) + ++ sizeof(struct kvm_loongarch_ls3a_extirq_state); ++ chip = g_malloc0(length); ++ ++ chip->chip_id = KVM_IRQCHIP_LS3A_EXTIRQ; ++ chip->len = length; ++ ++ kstate = (struct kvm_loongarch_ls3a_extirq_state *)chip->data; ++ for (i = 0; i < EXTIOI_IRQS_BITMAP_SIZE; i++) { ++ kstate->ext_en_r.reg_u8[i] = apic->ext_en[i]; ++ kstate->bounce_r.reg_u8[i] = apic->ext_bounce[i]; ++ kstate->ext_isr_r.reg_u8[i] = apic->ext_isr[i]; ++ for (vcpuid = 0; vcpuid < MAX_CORES; vcpuid++) { ++ kstate->ext_core_isr_r.reg_u8[vcpuid][i] = apic->ext_coreisr[vcpuid][i]; ++ } ++ } ++ for (i = 0; i < EXTIOI_IRQS_IPMAP_SIZE; i++) { ++ kstate->ip_map_r.reg_u8[i] = apic->ext_ipmap[i]; ++ } ++ for (i = 0; i < EXTIOI_IRQS; i++) { ++ kstate->core_map_r.reg_u8[i] = apic->ext_coremap[i]; ++ } ++ for (i = 0; i < 16; i++) { ++ kstate->node_type_r.reg_u16[i] = apic->ext_nodetype[i]; ++ } ++ ++ ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_SET_IRQCHIP failed: %s\n", strerror(ret)); ++ abort(); ++ } ++ g_free(chip); ++#endif ++ return 0; ++} ++typedef struct nodeApicState { ++ unsigned long addr; ++ int nodeid; ++ apicState *apic; ++} nodeApicState; ++ ++static void ioapic_update_irq(void *opaque, int irq, int level) ++{ ++ apicState *s = opaque; ++ uint8_t ipnum, cpu, cpu_ipnum; ++ unsigned long found1, found2; ++ uint8_t reg_count, reg_bit; ++ ++ reg_count = irq / 32; ++ reg_bit = irq % 32; ++ ++ ipnum = s->ext_sw_ipmap[irq]; ++ cpu = s->ext_sw_coremap[irq]; ++ cpu_ipnum = cpu * LS3A_INTC_IP + ipnum; ++ if (level == 1) { ++ if (test_bit(reg_bit, ((void *)s->ext_en + 0x4 * reg_count)) == false) { ++ return; ++ } ++ ++ if (test_bit(reg_bit, ((void *)s->ext_isr + 0x4 * reg_count)) == false) { ++ return; ++ } ++ bitmap_set(((void *)s->ext_coreisr[cpu] + 0x4 * reg_count), reg_bit, 1); ++ found1 = find_next_bit(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), ++ EXTIOI_IRQS, 0); ++ bitmap_set(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), reg_bit, 1); ++ if (found1 >= EXTIOI_IRQS) { ++ qemu_set_irq(s->parent_irq[cpu][ipnum], level); ++ } ++ } else { ++ bitmap_clear(((void *)s->ext_isr + 0x4 * reg_count), reg_bit, 1); ++ bitmap_clear(((void *)s->ext_coreisr[cpu] + 0x4 * reg_count), reg_bit, 1); ++ found1 = find_next_bit(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), ++ EXTIOI_IRQS, 0); ++ found1 += reg_count * 32; ++ bitmap_clear(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), reg_bit, 1); ++ found2 = find_next_bit(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), ++ EXTIOI_IRQS, 0); ++ if ((found1 < EXTIOI_IRQS) && (found2 >= EXTIOI_IRQS)) { ++ qemu_set_irq(s->parent_irq[cpu][ipnum], level); ++ } ++ } ++} ++ ++static void ioapic_setirq(void *opaque, int irq, int level) ++{ ++ apicState *s = opaque; ++ uint8_t reg_count, reg_bit; ++ ++ reg_count = irq / 32; ++ reg_bit = irq % 32; ++ ++ if (level) { ++ bitmap_set(((void *)s->ext_isr + 0x4 * reg_count), reg_bit, 1); ++ } else { ++ bitmap_clear(((void *)s->ext_isr + 0x4 * reg_count), reg_bit, 1); ++ } ++ ++ ioapic_update_irq(s, irq, level); ++} ++ ++static uint32_t apic_readb(void *opaque, hwaddr addr) ++{ ++ nodeApicState *node; ++ apicState *state; ++ unsigned long off; ++ uint8_t ret; ++ int cpu; ++ ++ node = (nodeApicState *)opaque; ++ state = node->apic; ++ off = addr & 0xfffff; ++ ret = 0; ++ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { ++ off -= EXTIOI_ENABLE_START; ++ ret = *(uint8_t *)((void *)state->ext_en + off); ++ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { ++ off -= EXTIOI_BOUNCE_START; ++ ret = *(uint8_t *)((void *)state->ext_bounce + off); ++ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { ++ off -= EXTIOI_ISR_START; ++ ret = *(uint8_t *)((void *)state->ext_isr + off); ++ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { ++ off -= EXTIOI_COREISR_START; ++ cpu = (off >> 8) & 0xff; ++ ret = *(uint8_t *)((void *)state->ext_coreisr[cpu] + (off & 0x1f)); ++ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { ++ off -= EXTIOI_IPMAP_START; ++ ret = *(uint8_t *)((void *)state->ext_ipmap + off); ++ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { ++ off -= EXTIOI_COREMAP_START; ++ ret = *(uint8_t *)((void *)state->ext_coremap + off); ++ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { ++ off -= EXTIOI_NODETYPE_START; ++ ret = *(uint8_t *)((void *)state->ext_nodetype + off); ++ } ++ ++ DPRINTF("readb reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, ret); ++ return ret; ++} ++ ++static uint32_t apic_readw(void *opaque, hwaddr addr) ++{ ++ nodeApicState *node; ++ apicState *state; ++ unsigned long off; ++ uint16_t ret; ++ int cpu; ++ ++ node = (nodeApicState *)opaque; ++ state = node->apic; ++ off = addr & 0xfffff; ++ ret = 0; ++ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { ++ off -= EXTIOI_ENABLE_START; ++ ret = *(uint16_t *)((void *)state->ext_en + off); ++ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { ++ off -= EXTIOI_BOUNCE_START; ++ ret = *(uint16_t *)((void *)state->ext_bounce + off); ++ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { ++ off -= EXTIOI_ISR_START; ++ ret = *(uint16_t *)((void *)state->ext_isr + off); ++ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { ++ off -= EXTIOI_COREISR_START; ++ cpu = (off >> 8) & 0xff; ++ ret = *(uint16_t *)((void *)state->ext_coreisr[cpu] + (off & 0x1f)); ++ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { ++ off -= EXTIOI_IPMAP_START; ++ ret = *(uint16_t *)((void *)state->ext_ipmap + off); ++ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { ++ off -= EXTIOI_COREMAP_START; ++ ret = *(uint16_t *)((void *)state->ext_coremap + off); ++ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { ++ off -= EXTIOI_NODETYPE_START; ++ ret = *(uint16_t *)((void *)state->ext_nodetype + off); ++ } ++ ++ DPRINTF("readw reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, ret); ++ return ret; ++} ++ ++static uint32_t apic_readl(void *opaque, hwaddr addr) ++{ ++ nodeApicState *node; ++ apicState *state; ++ unsigned long off; ++ uint32_t ret; ++ int cpu; ++ ++ node = (nodeApicState *)opaque; ++ state = node->apic; ++ off = addr & 0xfffff; ++ ret = 0; ++ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { ++ off -= EXTIOI_ENABLE_START; ++ ret = *(uint32_t *)((void *)state->ext_en + off); ++ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { ++ off -= EXTIOI_BOUNCE_START; ++ ret = *(uint32_t *)((void *)state->ext_bounce + off); ++ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { ++ off -= EXTIOI_ISR_START; ++ ret = *(uint32_t *)((void *)state->ext_isr + off); ++ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { ++ off -= EXTIOI_COREISR_START; ++ cpu = (off >> 8) & 0xff; ++ ret = *(uint32_t *)((void *)state->ext_coreisr[cpu] + (off & 0x1f)); ++ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { ++ off -= EXTIOI_IPMAP_START; ++ ret = *(uint32_t *)((void *)state->ext_ipmap + off); ++ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { ++ off -= EXTIOI_COREMAP_START; ++ ret = *(uint32_t *)((void *)state->ext_coremap + off); ++ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { ++ off -= EXTIOI_NODETYPE_START; ++ ret = *(uint32_t *)((void *)state->ext_nodetype + off); ++ } ++ ++ DPRINTF("readl reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, ret); ++ return ret; ++ ++} ++ ++static void apic_writeb(void *opaque, hwaddr addr, uint32_t val) ++{ ++ nodeApicState *node; ++ apicState *state; ++ unsigned long off; ++ uint8_t old; ++ int cpu, i, ipnum, level, mask; ++ ++ node = (nodeApicState *)opaque; ++ state = node->apic; ++ off = addr & 0xfffff; ++ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { ++ off -= EXTIOI_ENABLE_START; ++ old = *(uint8_t *)((void *)state->ext_en + off); ++ if (old != val) { ++ *(uint8_t *)((void *)state->ext_en + off) = val; ++ old = old ^ val; ++ mask = 0x1; ++ for (i = 0; i < 8; i++) { ++ if (old & mask) { ++ level = !!(val & (0x1 << i)); ++ ioapic_update_irq(state, i + off * 8, level); ++ } ++ mask = mask << 1; ++ } ++ } ++ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { ++ off -= EXTIOI_BOUNCE_START; ++ *(uint8_t *)((void *)state->ext_bounce + off) = val; ++ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { ++ off -= EXTIOI_ISR_START; ++ old = *(uint8_t *)((void *)state->ext_isr + off); ++ *(uint8_t *)((void *)state->ext_isr + off) = old & ~val; ++ mask = 0x1; ++ for (i = 0; i < 8; i++) { ++ if ((old & mask) && (val & mask)) { ++ ioapic_update_irq(state, i + off * 8, 0); ++ } ++ mask = mask << 1; ++ } ++ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { ++ off -= EXTIOI_COREISR_START; ++ cpu = (off >> 8) & 0xff; ++ off = off & 0x1f; ++ old = *(uint8_t *)((void *)state->ext_coreisr[cpu] + off); ++ *(uint8_t *)((void *)state->ext_coreisr[cpu] + off) = old & ~val; ++ mask = 0x1; ++ for (i = 0; i < 8; i++) { ++ if ((old & mask) && (val & mask)) { ++ ioapic_update_irq(state, i + off * 8, 0); ++ } ++ mask = mask << 1; ++ } ++ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { ++ off -= EXTIOI_IPMAP_START; ++ val = val & 0xf; ++ *(uint8_t *)((void *)state->ext_ipmap + off) = val; ++ ipnum = 0; ++ for (i = 0; i < 4; i++) { ++ if (val & (0x1 << i)) { ++ ipnum = i; ++ break; ++ } ++ } ++ if (val) { ++ for (i = 0; i < 32; i++) { ++ cpu = off * 32 + i; ++ state->ext_sw_ipmap[cpu] = ipnum; ++ } ++ } ++ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { ++ off -= EXTIOI_COREMAP_START; ++ val = val & 0xff; ++ *(uint8_t *)((void *)state->ext_coremap + off) = val; ++ state->ext_sw_coremap[off] = val; ++ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { ++ off -= EXTIOI_NODETYPE_START; ++ *(uint8_t *)((void *)state->ext_nodetype + off) = val; ++ } ++ ++ DPRINTF("writeb reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, val); ++} ++ ++static void apic_writew(void *opaque, hwaddr addr, uint32_t val) ++{ ++ nodeApicState *node; ++ apicState *state; ++ unsigned long off; ++ uint16_t old; ++ int cpu, i, level, mask; ++ ++ node = (nodeApicState *)opaque; ++ state = node->apic; ++ off = addr & 0xfffff; ++ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { ++ off -= EXTIOI_ENABLE_START; ++ old = *(uint16_t *)((void *)state->ext_en + off); ++ if (old != val) { ++ *(uint16_t *)((void *)state->ext_en + off) = val; ++ old = old ^ val; ++ mask = 0x1; ++ for (i = 0; i < 16; i++) { ++ if (old & mask) { ++ level = !!(val & (0x1 << i)); ++ ioapic_update_irq(state, i + off * 8, level); ++ } ++ mask = mask << 1; ++ } ++ } ++ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { ++ off -= EXTIOI_BOUNCE_START; ++ *(uint16_t *)((void *)state->ext_bounce + off) = val; ++ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { ++ off -= EXTIOI_ISR_START; ++ old = *(uint16_t *)((void *)state->ext_isr + off); ++ *(uint16_t *)((void *)state->ext_isr + off) = old & ~val; ++ mask = 0x1; ++ for (i = 0; i < 16; i++) { ++ if ((old & mask) && (val & mask)) { ++ ioapic_update_irq(state, i + off * 8, 0); ++ } ++ mask = mask << 1; ++ } ++ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { ++ off -= EXTIOI_COREISR_START; ++ cpu = (off >> 8) & 0xff; ++ off = off & 0x1f; ++ old = *(uint16_t *)((void *)state->ext_coreisr[cpu] + off); ++ *(uint16_t *)((void *)state->ext_coreisr[cpu] + off) = old & ~val; ++ mask = 0x1; ++ for (i = 0; i < 16; i++) { ++ if ((old & mask) && (val & mask)) { ++ ioapic_update_irq(state, i + off * 8, 0); ++ } ++ mask = mask << 1; ++ } ++ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { ++ apic_writeb(opaque, addr, val & 0xff); ++ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); ++ ++ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { ++ apic_writeb(opaque, addr, val & 0xff); ++ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); ++ ++ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { ++ off -= EXTIOI_NODETYPE_START; ++ *(uint16_t *)((void *)state->ext_nodetype + off) = val; ++ } ++ ++ DPRINTF("writew reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, val); ++} ++ ++static void apic_writel(void *opaque, hwaddr addr, uint32_t val) ++{ ++ nodeApicState *node; ++ apicState *state; ++ unsigned long off; ++ uint32_t old; ++ int cpu, i, level, mask; ++ ++ node = (nodeApicState *)opaque; ++ state = node->apic; ++ off = addr & 0xfffff; ++ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { ++ off -= EXTIOI_ENABLE_START; ++ old = *(uint32_t *)((void *)state->ext_en + off); ++ if (old != val) { ++ *(uint32_t *)((void *)state->ext_en + off) = val; ++ old = old ^ val; ++ mask = 0x1; ++ for (i = 0; i < 32; i++) { ++ if (old & mask) { ++ level = !!(val & (0x1 << i)); ++ ioapic_update_irq(state, i + off * 8, level); ++ } ++ mask = mask << 1; ++ } ++ } ++ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { ++ off -= EXTIOI_BOUNCE_START; ++ *(uint32_t *)((void *)state->ext_bounce + off) = val; ++ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { ++ off -= EXTIOI_ISR_START; ++ old = *(uint32_t *)((void *)state->ext_isr + off); ++ *(uint32_t *)((void *)state->ext_isr + off) = old & ~val; ++ mask = 0x1; ++ for (i = 0; i < 32; i++) { ++ if ((old & mask) && (val & mask)) { ++ ioapic_update_irq(state, i + off * 8, 0); ++ } ++ mask = mask << 1; ++ } ++ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { ++ off -= EXTIOI_COREISR_START; ++ cpu = (off >> 8) & 0xff; ++ off = off & 0x1f; ++ old = *(uint32_t *)((void *)state->ext_coreisr[cpu] + off); ++ *(uint32_t *)((void *)state->ext_coreisr[cpu] + off) = old & ~val; ++ mask = 0x1; ++ for (i = 0; i < 32; i++) { ++ if ((old & mask) && (val & mask)) { ++ ioapic_update_irq(state, i + off * 8, 0); ++ } ++ mask = mask << 1; ++ } ++ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { ++ apic_writeb(opaque, addr, val & 0xff); ++ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); ++ apic_writeb(opaque, addr + 2, (val >> 16) & 0xff); ++ apic_writeb(opaque, addr + 3, (val >> 24) & 0xff); ++ ++ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { ++ apic_writeb(opaque, addr, val & 0xff); ++ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); ++ apic_writeb(opaque, addr + 2, (val >> 16) & 0xff); ++ apic_writeb(opaque, addr + 3, (val >> 24) & 0xff); ++ ++ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { ++ off -= EXTIOI_NODETYPE_START; ++ *(uint32_t *)((void *)state->ext_nodetype + off) = val; ++ } ++ ++ DPRINTF("writel reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, val); ++} ++ ++static uint64_t apic_readfn(void *opaque, hwaddr addr, ++ unsigned size) ++{ ++ switch (size) { ++ case 1: ++ return apic_readb(opaque, addr); ++ case 2: ++ return apic_readw(opaque, addr); ++ case 4: ++ return apic_readl(opaque, addr); ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static void apic_writefn(void *opaque, hwaddr addr, ++ uint64_t value, unsigned size) ++{ ++ switch (size) { ++ case 1: ++ apic_writeb(opaque, addr, value); ++ break; ++ case 2: ++ apic_writew(opaque, addr, value); ++ break; ++ case 4: ++ apic_writel(opaque, addr, value); ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static const VMStateDescription vmstate_apic = { ++ .name = "apic", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .pre_save = ext_irq_pre_save, ++ .post_load = ext_irq_post_load, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT8_ARRAY(ext_en, apicState, EXTIOI_IRQS_BITMAP_SIZE), ++ VMSTATE_UINT8_ARRAY(ext_bounce, apicState, EXTIOI_IRQS_BITMAP_SIZE), ++ VMSTATE_UINT8_ARRAY(ext_isr, apicState, EXTIOI_IRQS_BITMAP_SIZE), ++ VMSTATE_UINT8_2DARRAY(ext_coreisr, apicState, MAX_CORES, ++ EXTIOI_IRQS_BITMAP_SIZE), ++ VMSTATE_UINT8_ARRAY(ext_ipmap, apicState, EXTIOI_IRQS_IPMAP_SIZE), ++ VMSTATE_UINT8_ARRAY(ext_coremap, apicState, EXTIOI_IRQS), ++ VMSTATE_UINT16_ARRAY(ext_nodetype, apicState, 16), ++ VMSTATE_UINT64(ext_control, apicState), ++ VMSTATE_UINT8_ARRAY(ext_sw_ipmap, apicState, EXTIOI_IRQS), ++ VMSTATE_UINT8_ARRAY(ext_sw_coremap, apicState, EXTIOI_IRQS), ++ VMSTATE_UINT8_2DARRAY(ext_ipisr, apicState, MAX_CORES * LS3A_INTC_IP, ++ EXTIOI_IRQS_BITMAP_SIZE), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static const MemoryRegionOps apic_ops = { ++ .read = apic_readfn, ++ .write = apic_writefn, ++ .impl.min_access_size = 1, ++ .impl.max_access_size = 4, ++ .valid.min_access_size = 1, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++}; ++ ++int cpu_init_apic(LoongarchMachineState *ms, CPULOONGARCHState *env, int cpu) ++{ ++ apicState *apic; ++ nodeApicState *node; ++ MemoryRegion *iomem; ++ unsigned long base; ++ int pin; ++ char str[32]; ++ ++ if (ms->apic == NULL) { ++ apic = g_malloc0(sizeof(apicState)); ++ vmstate_register(NULL, 0, &vmstate_apic, apic); ++ apic->irq = qemu_allocate_irqs(ioapic_setirq, apic, EXTIOI_IRQS); ++ ++ for (pin = 0; pin < LS3A_INTC_IP; pin++) { ++ /* cpu_pin[9:2] <= intc_pin[7:0] */ ++ apic->parent_irq[cpu][pin] = env->irq[pin + 2]; ++ } ++ ms->apic = apic; ++ ++ if (cpu == 0) { ++ base = APIC_BASE; ++ node = g_malloc0(sizeof(nodeApicState)); ++ node->apic = ms->apic; ++ node->addr = base; ++ ++ iomem = g_new(MemoryRegion, 1); ++ sprintf(str, "apic%d", cpu); ++ /* extioi addr 0x1f010000~0x1f02ffff */ ++ memory_region_init_io(iomem, NULL, &apic_ops, node, str, 0x20000); ++ memory_region_add_subregion(get_system_memory(), base, iomem); ++ } ++ ++ } else { ++ if (cpu != 0) { ++ for (pin = 0; pin < LS3A_INTC_IP; pin++) { ++ ms->apic->parent_irq[cpu][pin] = env->irq[pin + 2]; ++ } ++ } ++ } ++ return 0; ++} ++ +diff --git a/hw/loongarch/ioapic.c b/hw/loongarch/ioapic.c +new file mode 100644 +index 0000000000..3de0ed88da +--- /dev/null ++++ b/hw/loongarch/ioapic.c +@@ -0,0 +1,422 @@ ++/* ++ * LS7A1000 Northbridge IOAPIC support ++ * ++ * Copyright (c) 2019 Loongarch Technology ++ * Authors: ++ * Zhu Chen ++ * ++ * 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 "hw/sysbus.h" ++#include "hw/irq.h" ++#include "qemu/log.h" ++#include "sysemu/kvm.h" ++#include "linux/kvm.h" ++#include "migration/vmstate.h" ++ ++#define DEBUG_LS7A_APIC 0 ++ ++#define DPRINTF(fmt, ...) \ ++do { \ ++ if (DEBUG_LS7A_APIC) { \ ++ fprintf(stderr, "IOAPIC: " fmt , ## __VA_ARGS__); \ ++ } \ ++} while (0) ++ ++#define TYPE_LS7A_APIC "ioapic" ++#define LS7A_APIC(obj) OBJECT_CHECK(LS7AApicState, (obj), TYPE_LS7A_APIC) ++ ++#define LS7A_IOAPIC_ROUTE_ENTRY_OFFSET 0x100 ++#define LS7A_IOAPIC_INT_ID_OFFSET 0x00 ++#define LS7A_INT_ID_VAL 0x7000000UL ++#define LS7A_INT_ID_VER 0x1f0001UL ++#define LS7A_IOAPIC_INT_MASK_OFFSET 0x20 ++#define LS7A_IOAPIC_INT_EDGE_OFFSET 0x60 ++#define LS7A_IOAPIC_INT_CLEAR_OFFSET 0x80 ++#define LS7A_IOAPIC_INT_STATUS_OFFSET 0x3a0 ++#define LS7A_IOAPIC_INT_POL_OFFSET 0x3e0 ++#define LS7A_IOAPIC_HTMSI_EN_OFFSET 0x40 ++#define LS7A_IOAPIC_HTMSI_VEC_OFFSET 0x200 ++#define LS7A_AUTO_CTRL0_OFFSET 0xc0 ++#define LS7A_AUTO_CTRL1_OFFSET 0xe0 ++ ++typedef struct LS7AApicState { ++ SysBusDevice parent_obj; ++ qemu_irq parent_irq[257]; ++ uint64_t int_id; ++ uint64_t int_mask; /*0x020 interrupt mask register*/ ++ uint64_t htmsi_en;/*0x040 1=msi*/ ++ uint64_t intedge; /*0x060 edge=1 level =0*/ ++ uint64_t intclr; /*0x080 for clean edge int,set 1 clean,set 0 is noused*/ ++ uint64_t auto_crtl0; /*0x0c0*/ ++ uint64_t auto_crtl1; /*0x0e0*/ ++ uint8_t route_entry[64]; /*0x100 - 0x140*/ ++ uint8_t htmsi_vector[64]; /*0x200 - 0x240*/ ++ uint64_t intisr_chip0; /*0x300*/ ++ uint64_t intisr_chip1;/*0x320*/ ++ uint64_t last_intirr; /* edge detection */ ++ uint64_t intirr; /* 0x380 interrupt request register */ ++ uint64_t intisr; /* 0x3a0 interrupt service register */ ++ uint64_t int_polarity; /*0x3e0 interrupt level polarity ++ selection register 0 for high level tirgger*/ ++ MemoryRegion iomem; ++} LS7AApicState; ++ ++static void update_irq(LS7AApicState *s) ++{ ++ int i; ++ if ((s->intirr & (~s->int_mask)) & (~s->htmsi_en)) { ++ DPRINTF("7a update irqline up\n"); ++ s->intisr = (s->intirr & (~s->int_mask) & (~s->htmsi_en)); ++ qemu_set_irq(s->parent_irq[256], 1); ++ } else { ++ DPRINTF("7a update irqline down\n"); ++ s->intisr &= (~s->htmsi_en); ++ qemu_set_irq(s->parent_irq[256], 0); ++ } ++ if (s->htmsi_en) { ++ for (i = 0; i < 64; i++) { ++ if ((((~s->intisr) & s->intirr) & s->htmsi_en) & (1ULL << i)) { ++ s->intisr |= 1ULL << i; ++ qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], 1); ++ } else if (((~(s->intisr | s->intirr)) & s->htmsi_en) & ++ (1ULL << i)) { ++ qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], 0); ++ } ++ } ++ } ++} ++ ++static void irq_handler(void *opaque, int irq, int level) ++{ ++ LS7AApicState *s = opaque; ++ ++ assert(irq < 64); ++ uint64_t mask = 1ULL << irq; ++ DPRINTF("------ %s irq %d %d\n", __func__, irq, level); ++ ++ if (s->intedge & mask) { ++ /* edge triggered */ ++ /*TODO*/ ++ } else { ++ /* level triggered */ ++ if (level) { ++ s->intirr |= mask; ++ } else { ++ s->intirr &= ~mask; ++ } ++ ++ } ++ update_irq(s); ++ ++} ++ ++static uint64_t ls7a_apic_reg_read(void *opaque, hwaddr addr, unsigned size) ++{ ++ LS7AApicState *a = opaque; ++ uint64_t val = 0; ++ uint64_t offset; ++ int64_t offset_tmp; ++ offset = addr & 0xfff; ++ if (8 == size) { ++ switch (offset) { ++ case LS7A_IOAPIC_INT_ID_OFFSET: ++ val = LS7A_INT_ID_VER; ++ val = (val << 32) + LS7A_INT_ID_VAL; ++ break; ++ case LS7A_IOAPIC_INT_MASK_OFFSET: ++ val = a->int_mask; ++ break; ++ case LS7A_IOAPIC_INT_STATUS_OFFSET: ++ val = a->intisr & (~a->int_mask); ++ break; ++ case LS7A_IOAPIC_INT_EDGE_OFFSET: ++ val = a->intedge; ++ break; ++ case LS7A_IOAPIC_INT_POL_OFFSET: ++ val = a->int_polarity; ++ break; ++ case LS7A_IOAPIC_HTMSI_EN_OFFSET: ++ val = a->htmsi_en; ++ break; ++ case LS7A_AUTO_CTRL0_OFFSET: ++ case LS7A_AUTO_CTRL1_OFFSET: ++ break; ++ default: ++ break; ++ } ++ } else if (1 == size) { ++ if (offset >= LS7A_IOAPIC_HTMSI_VEC_OFFSET) { ++ offset_tmp = offset - LS7A_IOAPIC_HTMSI_VEC_OFFSET; ++ if (offset_tmp >= 0 && offset_tmp < 64) { ++ val = a->htmsi_vector[offset_tmp]; ++ } ++ } else if (offset >= LS7A_IOAPIC_ROUTE_ENTRY_OFFSET) { ++ offset_tmp = offset - LS7A_IOAPIC_ROUTE_ENTRY_OFFSET; ++ if (offset_tmp >= 0 && offset_tmp < 64) { ++ val = a->route_entry[offset_tmp]; ++ DPRINTF("addr %lx val %lx\n", addr, val); ++ } ++ } ++ } ++ DPRINTF(TARGET_FMT_plx" val %lx\n", addr, val); ++ return val; ++} ++ ++static void ls7a_apic_reg_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) ++{ ++ LS7AApicState *a = opaque; ++ int64_t offset_tmp; ++ uint64_t offset; ++ offset = addr & 0xfff; ++ DPRINTF(TARGET_FMT_plx" size %d val %lx\n", addr, size, data); ++ if (8 == size) { ++ switch (offset) { ++ case LS7A_IOAPIC_INT_MASK_OFFSET: ++ a->int_mask = data; ++ update_irq(a); ++ break; ++ case LS7A_IOAPIC_INT_STATUS_OFFSET: ++ a->intisr = data; ++ break; ++ case LS7A_IOAPIC_INT_EDGE_OFFSET: ++ a->intedge = data; ++ break; ++ case LS7A_IOAPIC_INT_CLEAR_OFFSET: ++ a->intisr &= (~data); ++ update_irq(a); ++ break; ++ case LS7A_IOAPIC_INT_POL_OFFSET: ++ a->int_polarity = data; ++ break; ++ case LS7A_IOAPIC_HTMSI_EN_OFFSET: ++ a->htmsi_en = data; ++ break; ++ case LS7A_AUTO_CTRL0_OFFSET: ++ case LS7A_AUTO_CTRL1_OFFSET: ++ break; ++ default: ++ break; ++ } ++ } else if (1 == size) { ++ if (offset >= LS7A_IOAPIC_HTMSI_VEC_OFFSET) { ++ offset_tmp = offset - LS7A_IOAPIC_HTMSI_VEC_OFFSET; ++ if (offset_tmp >= 0 && offset_tmp < 64) { ++ a->htmsi_vector[offset_tmp] = (uint8_t)(data & 0xff); ++ } ++ } else if (offset >= LS7A_IOAPIC_ROUTE_ENTRY_OFFSET) { ++ offset_tmp = offset - LS7A_IOAPIC_ROUTE_ENTRY_OFFSET; ++ if (offset_tmp >= 0 && offset_tmp < 64) { ++ a->route_entry[offset_tmp] = (uint8_t)(data & 0xff); ++ } ++ } ++ } ++} ++ ++static const MemoryRegionOps ls7a_apic_ops = { ++ .read = ls7a_apic_reg_read, ++ .write = ls7a_apic_reg_write, ++ .valid = { ++ .min_access_size = 1, ++ .max_access_size = 8, ++ }, ++ .impl = { ++ .min_access_size = 1, ++ .max_access_size = 8, ++ }, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++}; ++ ++static int kvm_ls7a_pre_save(void *opaque) ++{ ++#ifdef CONFIG_KVM ++ LS7AApicState *s = opaque; ++ struct loongarch_kvm_irqchip *chip; ++ struct ls7a_ioapic_state *state; ++ int ret, i, length; ++ ++ if (!kvm_irqchip_in_kernel()) { ++ return 0; ++ } ++ ++ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct ls7a_ioapic_state); ++ chip = g_malloc0(length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS7A_IOAPIC; ++ chip->len = length; ++ ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); ++ abort(); ++ } ++ state = (struct ls7a_ioapic_state *)chip->data; ++ s->int_id = state->int_id; ++ s->int_mask = state->int_mask; ++ s->htmsi_en = state->htmsi_en; ++ s->intedge = state->intedge; ++ s->intclr = state->intclr; ++ s->auto_crtl0 = state->auto_crtl0; ++ s->auto_crtl1 = state->auto_crtl1; ++ for (i = 0; i < 64; i++) { ++ s->route_entry[i] = state->route_entry[i]; ++ s->htmsi_vector[i] = state->htmsi_vector[i]; ++ } ++ s->intisr_chip0 = state->intisr_chip0; ++ s->intisr_chip1 = state->intisr_chip1; ++ s->intirr = state->intirr; ++ s->intisr = state->intisr; ++ s->int_polarity = state->int_polarity; ++ g_free(chip); ++#endif ++ return 0; ++} ++ ++static int kvm_ls7a_post_load(void *opaque, int version) ++{ ++#ifdef CONFIG_KVM ++ LS7AApicState *s = opaque; ++ struct loongarch_kvm_irqchip *chip; ++ struct ls7a_ioapic_state *state; ++ int ret, i, length; ++ ++ if (!kvm_irqchip_in_kernel()) { ++ return 0; ++ } ++ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct ls7a_ioapic_state); ++ chip = g_malloc0(length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS7A_IOAPIC; ++ chip->len = length; ++ ++ state = (struct ls7a_ioapic_state *)chip->data; ++ state->int_id = s->int_id; ++ state->int_mask = s->int_mask; ++ state->htmsi_en = s->htmsi_en; ++ state->intedge = s->intedge; ++ state->intclr = s->intclr; ++ state->auto_crtl0 = s->auto_crtl0; ++ state->auto_crtl1 = s->auto_crtl1; ++ for (i = 0; i < 64; i++) { ++ state->route_entry[i] = s->route_entry[i]; ++ state->htmsi_vector[i] = s->htmsi_vector[i]; ++ } ++ state->intisr_chip0 = s->intisr_chip0; ++ state->intisr_chip1 = s->intisr_chip1; ++ state->last_intirr = 0; ++ state->intirr = s->intirr; ++ state->intisr = s->intisr; ++ state->int_polarity = s->int_polarity; ++ ++ ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); ++ abort(); ++ } ++ g_free(chip); ++#endif ++ return 0; ++} ++ ++static void ls7a_apic_reset(DeviceState *d) ++{ ++ LS7AApicState *s = LS7A_APIC(d); ++ int i; ++ ++ s->int_id = 0x001f000107000000; ++ s->int_mask = 0xffffffffffffffff; ++ s->htmsi_en = 0x0; ++ s->intedge = 0x0; ++ s->intclr = 0x0; ++ s->auto_crtl0 = 0x0; ++ s->auto_crtl1 = 0x0; ++ for (i = 0; i < 64; i++) { ++ s->route_entry[i] = 0x1; ++ s->htmsi_vector[i] = 0x0; ++ } ++ s->intisr_chip0 = 0x0; ++ s->intisr_chip1 = 0x0; ++ s->intirr = 0x0; ++ s->intisr = 0x0; ++ s->int_polarity = 0x0; ++ kvm_ls7a_post_load(s, 0); ++} ++ ++static void ls7a_apic_init(Object *obj) ++{ ++ DeviceState *dev = DEVICE(obj); ++ LS7AApicState *s = LS7A_APIC(obj); ++ SysBusDevice *sbd = SYS_BUS_DEVICE(obj); ++ int tmp; ++ memory_region_init_io(&s->iomem, obj, &ls7a_apic_ops, s, TYPE_LS7A_APIC, 0x1000); ++ sysbus_init_mmio(sbd, &s->iomem); ++ for (tmp = 0; tmp < 257; tmp++) { ++ sysbus_init_irq(sbd, &s->parent_irq[tmp]); ++ } ++ qdev_init_gpio_in(dev, irq_handler, 64); ++} ++ ++static const VMStateDescription vmstate_ls7a_apic = { ++ .name = TYPE_LS7A_APIC, ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .pre_save = kvm_ls7a_pre_save, ++ .post_load = kvm_ls7a_post_load, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT64(int_mask, LS7AApicState), ++ VMSTATE_UINT64(htmsi_en, LS7AApicState), ++ VMSTATE_UINT64(intedge, LS7AApicState), ++ VMSTATE_UINT64(intclr, LS7AApicState), ++ VMSTATE_UINT64(auto_crtl0, LS7AApicState), ++ VMSTATE_UINT64(auto_crtl1, LS7AApicState), ++ VMSTATE_UINT8_ARRAY(route_entry, LS7AApicState, 64), ++ VMSTATE_UINT8_ARRAY(htmsi_vector, LS7AApicState, 64), ++ VMSTATE_UINT64(intisr_chip0, LS7AApicState), ++ VMSTATE_UINT64(intisr_chip1, LS7AApicState), ++ VMSTATE_UINT64(last_intirr, LS7AApicState), ++ VMSTATE_UINT64(intirr, LS7AApicState), ++ VMSTATE_UINT64(intisr, LS7AApicState), ++ VMSTATE_UINT64(int_polarity, LS7AApicState), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static void ls7a_apic_class_init(ObjectClass *klass, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(klass); ++ ++ dc->reset = ls7a_apic_reset; ++ dc->vmsd = &vmstate_ls7a_apic; ++} ++ ++static const TypeInfo ls7a_apic_info = { ++ .name = TYPE_LS7A_APIC, ++ .parent = TYPE_SYS_BUS_DEVICE, ++ .instance_size = sizeof(LS7AApicState), ++ .instance_init = ls7a_apic_init, ++ .class_init = ls7a_apic_class_init, ++}; ++ ++static void ls7a_apic_register_types(void) ++{ ++ type_register_static(&ls7a_apic_info); ++} ++ ++type_init(ls7a_apic_register_types) +diff --git a/hw/loongarch/iocsr.c b/hw/loongarch/iocsr.c +new file mode 100644 +index 0000000000..14521c2d5c +--- /dev/null ++++ b/hw/loongarch/iocsr.c +@@ -0,0 +1,219 @@ ++/* ++ * LOONGARCH IOCSR support ++ * ++ * Copyright (c) 2021 Loongarch Technology ++ * ++ * 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 "hw/sysbus.h" ++#include "qemu/log.h" ++#include "sysemu/kvm.h" ++#include "linux/kvm.h" ++#include "migration/vmstate.h" ++#include "hw/boards.h" ++#include "hw/loongarch/larch.h" ++ ++#define BIT_ULL(nr) (1ULL << (nr)) ++#define LOONGARCH_IOCSR_FEATURES 0x8 ++#define IOCSRF_TEMP BIT_ULL(0) ++#define IOCSRF_NODECNT BIT_ULL(1) ++#define IOCSRF_MSI BIT_ULL(2) ++#define IOCSRF_EXTIOI BIT_ULL(3) ++#define IOCSRF_CSRIPI BIT_ULL(4) ++#define IOCSRF_FREQCSR BIT_ULL(5) ++#define IOCSRF_FREQSCALE BIT_ULL(6) ++#define IOCSRF_DVFSV1 BIT_ULL(7) ++#define IOCSRF_GMOD BIT_ULL(9) ++#define IOCSRF_VM BIT_ULL(11) ++#define LOONGARCH_IOCSR_VENDOR 0x10 ++#define LOONGARCH_IOCSR_CPUNAME 0x20 ++#define LOONGARCH_IOCSR_NODECNT 0x408 ++#define LOONGARCH_IOCSR_MISC_FUNC 0x420 ++#define IOCSR_MISC_FUNC_TIMER_RESET BIT_ULL(21) ++#define IOCSR_MISC_FUNC_EXT_IOI_EN BIT_ULL(48) ++ ++enum { ++ IOCSR_FEATURES, ++ IOCSR_VENDOR, ++ IOCSR_CPUNAME, ++ IOCSR_NODECNT, ++ IOCSR_MISC_FUNC, ++ IOCSR_MAX ++}; ++ ++static uint32_t iocsr_array[IOCSR_MAX] = { ++ [IOCSR_FEATURES] = LOONGARCH_IOCSR_FEATURES, ++ [IOCSR_VENDOR] = LOONGARCH_IOCSR_VENDOR, ++ [IOCSR_CPUNAME] = LOONGARCH_IOCSR_CPUNAME, ++ [IOCSR_NODECNT] = LOONGARCH_IOCSR_NODECNT, ++ [IOCSR_MISC_FUNC] = LOONGARCH_IOCSR_MISC_FUNC, ++}; ++ ++ ++#define TYPE_IOCSR "iocsr" ++#define IOCSR(obj) OBJECT_CHECK(IOCSRState, (obj), TYPE_IOCSR) ++ ++typedef struct IOCSRState { ++ SysBusDevice parent_obj; ++ uint64_t iocsr_val[IOCSR_MAX]; ++} IOCSRState; ++ ++IOCSRState iocsr_init = { ++ .iocsr_val = { ++ IOCSRF_NODECNT | IOCSRF_MSI | IOCSRF_EXTIOI ++ | IOCSRF_CSRIPI | IOCSRF_GMOD | IOCSRF_VM, ++ 0x6e6f73676e6f6f4c, /* Loongson */ ++ 0x303030354133, /*3A5000*/ ++ 0x4, ++ 0x0, ++ } ++}; ++ ++static int kvm_iocsr_pre_save(void *opaque) ++{ ++#ifdef CONFIG_KVM ++ IOCSRState *s = opaque; ++ struct kvm_iocsr_entry entry; ++ int i = 0; ++ for (i = 0; i < IOCSR_MAX; i++) { ++ entry.addr = iocsr_array[i]; ++ kvm_vm_ioctl(kvm_state, KVM_LOONGARCH_GET_IOCSR, &entry); ++ s->iocsr_val[i] = entry.data; ++ } ++#endif ++ return 0; ++} ++ ++static int kvm_iocsr_post_load(void *opaque, int version) ++{ ++#ifdef CONFIG_KVM ++ IOCSRState *s = opaque; ++ struct kvm_iocsr_entry entry; ++ int i = 0; ++ ++ if (!kvm_enabled()) { ++ return 0; ++ } ++ ++ for (i = 0; i < IOCSR_MAX; i++) { ++ entry.addr = iocsr_array[i]; ++ entry.data = s->iocsr_val[i]; ++ kvm_vm_ioctl(kvm_state, KVM_LOONGARCH_SET_IOCSR, &entry); ++ } ++#endif ++ return 0; ++} ++ ++static void iocsr_reset(DeviceState *d) ++{ ++ IOCSRState *s = IOCSR(d); ++ int i; ++ ++ for (i = 0; i < IOCSR_MAX; i++) { ++ s->iocsr_val[i] = iocsr_init.iocsr_val[i]; ++ } ++ kvm_iocsr_post_load(s, 0); ++} ++static void init_vendor_cpuname(uint64_t *vendor, ++ uint64_t *cpu_name, char *cpuname) ++{ ++ int i = 0, len = 0; ++ char *index = NULL, *index_end = NULL; ++ char *vendor_c = (char *)vendor; ++ char *cpu_name_c = (char *)cpu_name; ++ ++ index = strstr(cpuname, "-"); ++ len = strlen(cpuname); ++ if ((index == NULL) || (len <= 0)) { ++ return ; ++ } ++ ++ *vendor = 0; ++ *cpu_name = 0; ++ index_end = cpuname + len; ++ ++ while (((cpuname + i) < index) && (i < sizeof(uint64_t))) { ++ vendor_c[i] = cpuname[i]; ++ i++; ++ } ++ ++ index += 1; ++ i = 0; ++ ++ while (((index + i) < index_end) && (i < sizeof(uint64_t))) { ++ cpu_name_c[i] = index[i]; ++ i++; ++ } ++ ++ return ; ++} ++ ++static void iocsr_instance_init(Object *obj) ++{ ++ IOCSRState *s = IOCSR(obj); ++ int i; ++ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ ++ init_vendor_cpuname((uint64_t *)&iocsr_init.iocsr_val[IOCSR_VENDOR], ++ (uint64_t *)&iocsr_init.iocsr_val[IOCSR_CPUNAME], ++ lsmc->cpu_name); ++ ++ for (i = 0; i < IOCSR_MAX; i++) { ++ s->iocsr_val[i] = iocsr_init.iocsr_val[i]; ++ } ++} ++ ++static const VMStateDescription vmstate_iocsr = { ++ .name = TYPE_IOCSR, ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .pre_save = kvm_iocsr_pre_save, ++ .post_load = kvm_iocsr_post_load, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT64_ARRAY(iocsr_val, IOCSRState, IOCSR_MAX), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static void iocsr_class_init(ObjectClass *klass, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(klass); ++ ++ dc->reset = iocsr_reset; ++ dc->vmsd = &vmstate_iocsr; ++ ++} ++ ++static const TypeInfo iocsr_info = { ++ .name = TYPE_IOCSR, ++ .parent = TYPE_SYS_BUS_DEVICE, ++ .instance_size = sizeof(IOCSRState), ++ .instance_init = iocsr_instance_init, ++ .class_init = iocsr_class_init, ++}; ++ ++static void iocsr_register_types(void) ++{ ++ type_register_static(&iocsr_info); ++} ++ ++type_init(iocsr_register_types) +diff --git a/hw/loongarch/ipi.c b/hw/loongarch/ipi.c +new file mode 100644 +index 0000000000..ade182abcc +--- /dev/null ++++ b/hw/loongarch/ipi.c +@@ -0,0 +1,267 @@ ++#include "qemu/osdep.h" ++#include "qemu/units.h" ++#include "qapi/error.h" ++#include "hw/hw.h" ++#include "hw/irq.h" ++#include "hw/loongarch/cpudevs.h" ++#include "sysemu/sysemu.h" ++#include "sysemu/cpus.h" ++#include "sysemu/kvm.h" ++#include "hw/core/cpu.h" ++#include "qemu/log.h" ++#include "hw/loongarch/bios.h" ++#include "elf.h" ++#include "linux/kvm.h" ++#include "hw/loongarch/larch.h" ++#include "hw/loongarch/ls7a.h" ++#include "migration/vmstate.h" ++ ++static int gipi_pre_save(void *opaque) ++{ ++#ifdef CONFIG_KVM ++ gipiState *state = opaque; ++ struct loongarch_gipiState *kstate; ++ struct loongarch_kvm_irqchip *chip; ++ int ret, i, j, length; ++#endif ++ ++ if (!kvm_irqchip_in_kernel()) { ++ return 0; ++ } ++ ++#ifdef CONFIG_KVM ++ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct loongarch_gipiState); ++ chip = g_malloc0(length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS3A_GIPI; ++ chip->len = length; ++ ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); ++ abort(); ++ } ++ ++ kstate = (struct loongarch_gipiState *)chip->data; ++ ++ for (i = 0; i < MAX_GIPI_CORE_NUM; i++) { ++ state->core[i].status = kstate->core[i].status; ++ state->core[i].en = kstate->core[i].en; ++ state->core[i].set = kstate->core[i].set; ++ state->core[i].clear = kstate->core[i].clear; ++ for (j = 0; j < MAX_GIPI_MBX_NUM; j++) { ++ state->core[i].buf[j] = kstate->core[i].buf[j]; ++ } ++ } ++ g_free(chip); ++#endif ++ ++ return 0; ++} ++ ++static int gipi_post_load(void *opaque, int version) ++{ ++#ifdef CONFIG_KVM ++ gipiState *state = opaque; ++ struct loongarch_gipiState *kstate; ++ struct loongarch_kvm_irqchip *chip; ++ int ret, i, j, length; ++#endif ++ ++ if (!kvm_irqchip_in_kernel()) { ++ return 0; ++ } ++ ++#ifdef CONFIG_KVM ++ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct loongarch_gipiState); ++ chip = g_malloc0(length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS3A_GIPI; ++ chip->len = length; ++ kstate = (struct loongarch_gipiState *)chip->data; ++ ++ for (i = 0; i < MAX_GIPI_CORE_NUM; i++) { ++ kstate->core[i].status = state->core[i].status; ++ kstate->core[i].en = state->core[i].en; ++ kstate->core[i].set = state->core[i].set; ++ kstate->core[i].clear = state->core[i].clear; ++ for (j = 0; j < MAX_GIPI_MBX_NUM; j++) { ++ kstate->core[i].buf[j] = state->core[i].buf[j]; ++ } ++ } ++ ++ ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); ++ abort(); ++ } ++ g_free(chip); ++#endif ++ ++ return 0; ++} ++ ++static const VMStateDescription vmstate_gipi_core = { ++ .name = "gipi-single", ++ .version_id = 0, ++ .minimum_version_id = 0, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT32(status, gipi_core), ++ VMSTATE_UINT32(en, gipi_core), ++ VMSTATE_UINT32(set, gipi_core), ++ VMSTATE_UINT32(clear, gipi_core), ++ VMSTATE_UINT64_ARRAY(buf, gipi_core, MAX_GIPI_MBX_NUM), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static const VMStateDescription vmstate_gipi = { ++ .name = "gipi", ++ .pre_save = gipi_pre_save, ++ .post_load = gipi_post_load, ++ .version_id = 0, ++ .minimum_version_id = 0, ++ .fields = (VMStateField[]) { ++ VMSTATE_STRUCT_ARRAY(core, gipiState, MAX_GIPI_CORE_NUM, 0, ++ vmstate_gipi_core, gipi_core), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++ ++static void gipi_writel(void *opaque, hwaddr addr, uint64_t val, unsigned size) ++{ ++ gipi_core *s = opaque; ++ gipi_core *ss; ++ void *pbuf; ++ uint32_t cpu, action_data, mailaddr; ++ LoongarchMachineState *ms = LoongarchMACHINE(qdev_get_machine()); ++ ++ if ((size != 4) && (size != 8)) { ++ hw_error("size not 4 and not 8"); ++ } ++ addr &= 0xff; ++ switch (addr) { ++ case CORE0_STATUS_OFF: ++ hw_error("CORE0_STATUS_OFF Can't be write\n"); ++ break; ++ case CORE0_EN_OFF: ++ s->en = val; ++ break; ++ case CORE0_IPI_SEND: ++ cpu = (val >> 16) & 0x3ff; ++ action_data = 1UL << (val & 0x1f); ++ ss = &ms->gipi->core[cpu]; ++ ss->status |= action_data; ++ if (ss->status != 0) { ++ qemu_irq_raise(ss->irq); ++ } ++ break; ++ case CORE0_MAIL_SEND: ++ cpu = (val >> 16) & 0x3ff; ++ mailaddr = (val >> 2) & 0x7; ++ ss = &ms->gipi->core[cpu]; ++ pbuf = (void *)ss->buf + mailaddr * 4; ++ *(unsigned int *)pbuf = (val >> 32); ++ break; ++ case CORE0_SET_OFF: ++ hw_error("CORE0_SET_OFF Can't be write\n"); ++ break; ++ case CORE0_CLEAR_OFF: ++ s->status ^= val; ++ if (s->status == 0) { ++ qemu_irq_lower(s->irq); ++ } ++ break; ++ case 0x20 ... 0x3c: ++ pbuf = (void *)s->buf + (addr - 0x20); ++ if (size == 1) { ++ *(unsigned char *)pbuf = (unsigned char)val; ++ } else if (size == 2) { ++ *(unsigned short *)pbuf = (unsigned short)val; ++ } else if (size == 4) { ++ *(unsigned int *)pbuf = (unsigned int)val; ++ } else if (size == 8) { ++ *(unsigned long *)pbuf = (unsigned long)val; ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static uint64_t gipi_readl(void *opaque, hwaddr addr, unsigned size) ++{ ++ gipi_core *s = opaque; ++ uint64_t ret = 0; ++ void *pbuf; ++ ++ addr &= 0xff; ++ if ((size != 4) && (size != 8)) { ++ hw_error("size not 4 and not 8 size:%d\n", size); ++ } ++ switch (addr) { ++ case CORE0_STATUS_OFF: ++ ret = s->status; ++ break; ++ case CORE0_EN_OFF: ++ ret = s->en; ++ break; ++ case CORE0_SET_OFF: ++ ret = 0; ++ break; ++ case CORE0_CLEAR_OFF: ++ ret = 0; ++ break; ++ case 0x20 ... 0x3c: ++ pbuf = (void *)s->buf + (addr - 0x20); ++ if (size == 1) { ++ ret = *(unsigned char *)pbuf; ++ } else if (size == 2) { ++ ret = *(unsigned short *)pbuf; ++ } else if (size == 4) { ++ ret = *(unsigned int *)pbuf; ++ } else if (size == 8) { ++ ret = *(unsigned long *)pbuf; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++static const MemoryRegionOps gipi_ops = { ++ .read = gipi_readl, ++ .write = gipi_writel, ++ .valid = { ++ .min_access_size = 4, ++ .max_access_size = 8, ++ }, ++ .impl = { ++ .min_access_size = 4, ++ .max_access_size = 8, ++ }, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++}; ++ ++int cpu_init_ipi(LoongarchMachineState *ms, qemu_irq parent, int cpu) ++{ ++ hwaddr addr; ++ MemoryRegion *region; ++ char str[32]; ++ ++ if (ms->gipi == NULL) { ++ ms->gipi = g_malloc0(sizeof(gipiState)); ++ vmstate_register(NULL, 0, &vmstate_gipi, ms->gipi); ++ } ++ ++ ms->gipi->core[cpu].irq = parent; ++ ++ addr = SMP_GIPI_MAILBOX | (cpu << 8); ++ region = g_new(MemoryRegion, 1); ++ sprintf(str, "gipi%d", cpu); ++ memory_region_init_io(region, NULL, &gipi_ops, &ms->gipi->core[cpu], str, 0x100); ++ memory_region_add_subregion(get_system_memory(), addr, region); ++ return 0; ++} +diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c +new file mode 100644 +index 0000000000..3db269274f +--- /dev/null ++++ b/hw/loongarch/larch_3a.c +@@ -0,0 +1,2026 @@ ++/* ++ * QEMU loongarch 3a develop board emulation ++ * ++ * Copyright (C) 2013-2014 qiaochong ++ * Copyright (C) 2016-2017 zhangshuangshuang ++ * ++ * 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/units.h" ++#include "qapi/error.h" ++#include "qemu/datadir.h" ++#include "hw/hw.h" ++#include "hw/loongarch/cpudevs.h" ++#include "hw/i386/pc.h" ++#include "hw/char/serial.h" ++#include "hw/isa/isa.h" ++#include "hw/qdev-core.h" ++#include "sysemu/sysemu.h" ++#include "sysemu/runstate.h" ++#include "sysemu/reset.h" ++#include "migration/vmstate.h" ++#include "sysemu/cpus.h" ++#include "hw/boards.h" ++#include "qemu/log.h" ++#include "hw/loongarch/bios.h" ++#include "hw/loader.h" ++#include "elf.h" ++#include "exec/address-spaces.h" ++#include "hw/ide.h" ++#include "hw/pci/pci_host.h" ++#include "hw/pci/msi.h" ++#include "linux/kvm.h" ++#include "sysemu/kvm.h" ++#include "sysemu/numa.h" ++#include "hw/rtc/mc146818rtc.h" ++#include "hw/irq.h" ++#include "net/net.h" ++#include "hw/timer/i8254.h" ++#include "hw/loongarch/larch.h" ++#include "hw/loongarch/ls7a.h" ++#include "hw/nvram/fw_cfg.h" ++#include "hw/firmware/smbios.h" ++#include "acpi-build.h" ++#include ++#include ++#include "sysemu/block-backend.h" ++#include "hw/block/flash.h" ++#include "sysemu/device_tree.h" ++#include "qapi/visitor.h" ++#include "qapi/qapi-visit-common.h" ++ ++#include ++ ++#define DMA64_SUPPORTED 0x2 ++#define MAX_IDE_BUS 2 ++ ++#define BOOTPARAM_PHYADDR 0x0ff00000ULL ++#define BOOTPARAM_ADDR (0x9000000000000000ULL + BOOTPARAM_PHYADDR) ++#define SMBIOS_PHYSICAL_ADDRESS 0x0fe00000 ++#define SMBIOS_SIZE_LIMIT 0x200000 ++#define RESERVED_SIZE_LIMIT 0x1100000 ++#define COMMAND_LINE_SIZE 4096 ++#define FW_CONF_ADDR 0x0fff0000 ++ ++#define PHYS_TO_VIRT(x) ((x) | 0x9000000000000000ULL) ++ ++#define TARGET_REALPAGE_MASK (TARGET_PAGE_MASK << 2) ++ ++#ifdef CONFIG_KVM ++#define LS_ISA_IO_SIZE 0x02000000 ++#define LS_ISA_MEM_SIZE 0x40000000 ++#else ++#define LS_ISA_IO_SIZE 0x00010000 ++#define LS_ISA_MEM_SIZE 0x01000000 ++#endif ++ ++#ifdef CONFIG_KVM ++#define align(x) (((x) + 63) & ~63) ++#else ++#define align(x) (((x) + 15) & ~15) ++#endif ++ ++#define DEBUG_LOONGARCH3A 0 ++#define FLASH_SECTOR_SIZE 4096 ++ ++#define DPRINTF(fmt, ...) \ ++ do { if (DEBUG_LOONGARCH3A) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0) ++ ++#define DEFINE_LS3A5K_MACHINE(suffix, name, optionfn) \ ++ static void ls3a5k_init_##suffix(MachineState *machine) \ ++ { \ ++ ls3a5k_init(machine); \ ++ } \ ++ DEFINE_LOONGARCH_MACHINE(suffix, name, ls3a5k_init_##suffix, optionfn) ++ ++struct efi_memory_map_loongarch { ++ uint16_t vers; /* version of efi_memory_map */ ++ uint32_t nr_map; /* number of memory_maps */ ++ uint32_t mem_freq; /* memory frequence */ ++ struct mem_map { ++ uint32_t node_id; /* node_id which memory attached to */ ++ uint32_t mem_type; /* system memory, pci memory, pci io, etc. */ ++ uint64_t mem_start; /* memory map start address */ ++ uint32_t mem_size; /* each memory_map size, not the total size */ ++ } map[128]; ++} __attribute__((packed)); ++ ++enum loongarch_cpu_type { ++ Loongson3 = 0x1, ++ Loongson3_comp = 0x2 ++}; ++ ++struct GlobalProperty loongarch_compat[] = { ++ { ++ .driver = "rtl8139", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "e1000", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "virtio-net-pci", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "qxl-vga", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "VGA", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "cirrus-vga", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "virtio-vga", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "vmware-svga", ++ .property = "romfile", ++ .value = "", ++ }, ++}; ++const size_t loongarch_compat_len = G_N_ELEMENTS(loongarch_compat); ++ ++/* ++ * Capability and feature descriptor structure for LOONGARCH CPU ++ */ ++struct efi_cpuinfo_loongarch { ++ uint16_t vers; /* version of efi_cpuinfo_loongarch */ ++ uint32_t processor_id; /* PRID, e.g. 6305, 6306 */ ++ enum loongarch_cpu_type cputype; /* 3A, 3B, etc. */ ++ uint32_t total_node; /* num of total numa nodes */ ++ uint16_t cpu_startup_core_id; /* Core id */ ++ uint16_t reserved_cores_mask; ++ uint32_t cpu_clock_freq; /* cpu_clock */ ++ uint32_t nr_cpus; ++} __attribute__((packed)); ++ ++#define MAX_UARTS 64 ++struct uart_device { ++ uint32_t iotype; /* see include/linux/serial_core.h */ ++ uint32_t uartclk; ++ uint32_t int_offset; ++ uint64_t uart_base; ++} __attribute__((packed)); ++ ++#define MAX_SENSORS 64 ++#define SENSOR_TEMPER 0x00000001 ++#define SENSOR_VOLTAGE 0x00000002 ++#define SENSOR_FAN 0x00000004 ++struct sensor_device { ++ char name[32]; /* a formal name */ ++ char label[64]; /* a flexible description */ ++ uint32_t type; /* SENSOR_* */ ++ uint32_t id; /* instance id of a sensor-class */ ++ uint32_t fan_policy; /* see arch/loongarch/include/ ++ asm/mach-loongarch/loongarch_hwmon.h */ ++ uint32_t fan_percent;/* only for constant speed policy */ ++ uint64_t base_addr; /* base address of device registers */ ++} __attribute__((packed)); ++ ++struct system_loongarch { ++ uint16_t vers; /* version of system_loongarch */ ++ uint32_t ccnuma_smp; /* 0: no numa; 1: has numa */ ++ uint32_t sing_double_channel;/* 1:single; 2:double */ ++ uint32_t nr_uarts; ++ struct uart_device uarts[MAX_UARTS]; ++ uint32_t nr_sensors; ++ struct sensor_device sensors[MAX_SENSORS]; ++ char has_ec; ++ char ec_name[32]; ++ uint64_t ec_base_addr; ++ char has_tcm; ++ char tcm_name[32]; ++ uint64_t tcm_base_addr; ++ uint64_t workarounds; /* see workarounds.h */ ++} __attribute__((packed)); ++ ++struct irq_source_routing_table { ++ uint16_t vers; ++ uint16_t size; ++ uint16_t rtr_bus; ++ uint16_t rtr_devfn; ++ uint32_t vendor; ++ uint32_t device; ++ uint32_t PIC_type; /* conform use HT or PCI to route to CPU-PIC */ ++ uint64_t ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ ++ uint64_t ht_enable; /* irqs used in this PIC */ ++ uint32_t node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */ ++ uint64_t pci_mem_start_addr; ++ uint64_t pci_mem_end_addr; ++ uint64_t pci_io_start_addr; ++ uint64_t pci_io_end_addr; ++ uint64_t pci_config_addr; ++ uint32_t dma_mask_bits; ++ uint16_t dma_noncoherent; ++} __attribute__((packed)); ++ ++struct interface_info { ++ uint16_t vers; /* version of the specificition */ ++ uint16_t size; ++ uint8_t flag; ++ char description[64]; ++} __attribute__((packed)); ++ ++#define MAX_RESOURCE_NUMBER 128 ++struct resource_loongarch { ++ uint64_t start; /* resource start address */ ++ uint64_t end; /* resource end address */ ++ char name[64]; ++ uint32_t flags; ++}; ++ ++struct archdev_data {}; /* arch specific additions */ ++ ++struct board_devices { ++ char name[64]; /* hold the device name */ ++ uint32_t num_resources; /* number of device_resource */ ++ /* for each device's resource */ ++ struct resource_loongarch resource[MAX_RESOURCE_NUMBER]; ++ /* arch specific additions */ ++ struct archdev_data archdata; ++}; ++ ++struct loongarch_special_attribute { ++ uint16_t vers; /* version of this special */ ++ char special_name[64]; /* special_atribute_name */ ++ uint32_t loongarch_special_type; /* type of special device */ ++ /* for each device's resource */ ++ struct resource_loongarch resource[MAX_RESOURCE_NUMBER]; ++}; ++ ++struct loongarch_params { ++ uint64_t memory_offset; /* efi_memory_map_loongarch struct offset */ ++ uint64_t cpu_offset; /* efi_cpuinfo_loongarch struct offset */ ++ uint64_t system_offset; /* system_loongarch struct offset */ ++ uint64_t irq_offset; /* irq_source_routing_table struct offset */ ++ uint64_t interface_offset; /* interface_info struct offset */ ++ uint64_t special_offset; /* loongarch_special_attribute struct offset */ ++ uint64_t boarddev_table_offset; /* board_devices offset */ ++}; ++ ++struct smbios_tables { ++ uint16_t vers; /* version of smbios */ ++ uint64_t vga_bios; /* vga_bios address */ ++ struct loongarch_params lp; ++}; ++ ++struct efi_reset_system_t { ++ uint64_t ResetCold; ++ uint64_t ResetWarm; ++ uint64_t ResetType; ++ uint64_t Shutdown; ++ uint64_t DoSuspend; /* NULL if not support */ ++}; ++ ++struct efi_loongarch { ++ uint64_t mps; /* MPS table */ ++ uint64_t acpi; /* ACPI table (IA64 ext 0.71) */ ++ uint64_t acpi20; /* ACPI table (ACPI 2.0) */ ++ struct smbios_tables smbios; /* SM BIOS table */ ++ uint64_t sal_systab; /* SAL system table */ ++ uint64_t boot_info; /* boot info table */ ++}; ++ ++struct boot_params { ++ struct efi_loongarch efi; ++ struct efi_reset_system_t reset_system; ++}; ++ ++static struct _loaderparams { ++ unsigned long ram_size; ++ const char *kernel_filename; ++ const char *kernel_cmdline; ++ const char *initrd_filename; ++ unsigned long a0, a1, a2; ++} loaderparams; ++ ++static struct _firmware_config { ++ unsigned long ram_size; ++ unsigned int mem_freq; ++ unsigned int cpu_nr; ++ unsigned int cpu_clock_freq; ++} fw_config; ++ ++struct la_memmap_entry { ++ uint64_t address; ++ uint64_t length; ++ uint32_t type; ++ uint32_t reserved; ++} ; ++ ++static void *boot_params_buf; ++static void *boot_params_p; ++static struct la_memmap_entry *la_memmap_table; ++static unsigned la_memmap_entries; ++ ++CPULOONGARCHState *cpu_states[LOONGARCH_MAX_VCPUS]; ++ ++struct kvm_cpucfg ls3a5k_cpucfgs = { ++ .cpucfg[LOONGARCH_CPUCFG0] = CPUCFG0_3A5000_PRID, ++ .cpucfg[LOONGARCH_CPUCFG1] = CPUCFG1_ISGR64 | CPUCFG1_PAGING | ++ CPUCFG1_IOCSR | CPUCFG1_PABITS | CPUCFG1_VABITS | CPUCFG1_UAL | ++ CPUCFG1_RI | CPUCFG1_XI | CPUCFG1_RPLV | CPUCFG1_HUGEPG | ++ CPUCFG1_IOCSRBRD, ++ .cpucfg[LOONGARCH_CPUCFG2] = CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP | ++ CPUCFG2_FPVERS | CPUCFG2_LSX | CPUCFG2_LASX | CPUCFG2_COMPLEX | ++ CPUCFG2_CRYPTO | CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | CPUCFG2_LSPW | ++ CPUCFG2_LAM, ++ .cpucfg[LOONGARCH_CPUCFG3] = CPUCFG3_CCDMA | CPUCFG3_SFB | CPUCFG3_UCACC | ++ CPUCFG3_LLEXC | CPUCFG3_SCDLY | CPUCFG3_LLDBAR | CPUCFG3_ITLBT | ++ CPUCFG3_ICACHET | CPUCFG3_SPW_LVL | CPUCFG3_SPW_HG_HF | CPUCFG3_RVA | ++ CPUCFG3_RVAMAX, ++ .cpucfg[LOONGARCH_CPUCFG4] = CCFREQ_100M, ++ .cpucfg[LOONGARCH_CPUCFG5] = CPUCFG5_CCMUL | CPUCFG5_CCDIV, ++ .cpucfg[LOONGARCH_CPUCFG6] = CPUCFG6_PMP | CPUCFG6_PAMVER | CPUCFG6_PMNUM | ++ CPUCFG6_PMBITS | CPUCFG6_UPM, ++ .cpucfg[LOONGARCH_CPUCFG16] = CPUCFG16_L1_IUPRE | CPUCFG16_L1_DPRE | ++ CPUCFG16_L2_IUPRE | CPUCFG16_L2_IUUNIFY | CPUCFG16_L2_IUPRIV | ++ CPUCFG16_L3_IUPRE | CPUCFG16_L3_IUUNIFY | CPUCFG16_L3_IUINCL, ++ .cpucfg[LOONGARCH_CPUCFG17] = CPUCFG17_L1I_WAYS_M | CPUCFG17_L1I_SETS_M | ++ CPUCFG17_L1I_SIZE_M, ++ .cpucfg[LOONGARCH_CPUCFG18] = CPUCFG18_L1D_WAYS_M | CPUCFG18_L1D_SETS_M | ++ CPUCFG18_L1D_SIZE_M, ++ .cpucfg[LOONGARCH_CPUCFG19] = CPUCFG19_L2_WAYS_M | CPUCFG19_L2_SETS_M | ++ CPUCFG19_L2_SIZE_M, ++ .cpucfg[LOONGARCH_CPUCFG20] = CPUCFG20_L3_WAYS_M | CPUCFG20_L3_SETS_M | ++ CPUCFG20_L3_SIZE_M, ++}; ++ ++bool loongarch_is_acpi_enabled(LoongarchMachineState *vms) ++{ ++ if (vms->acpi == ON_OFF_AUTO_OFF) { ++ return false; ++ } ++ return true; ++} ++static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(obj); ++ OnOffAuto acpi = lsms->acpi; ++ ++ visit_type_OnOffAuto(v, name, &acpi, errp); ++} ++ ++static void loongarch_set_acpi(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(obj); ++ ++ visit_type_OnOffAuto(v, name, &lsms->acpi, errp); ++} ++int la_memmap_add_entry(uint64_t address, uint64_t length, uint32_t type) ++{ ++ int i; ++ ++ for (i = 0; i < la_memmap_entries; i++) { ++ if (la_memmap_table[i].address == address) { ++ fprintf(stderr, "%s address:0x%lx length:0x%lx already exists\n", ++ __func__, address, length); ++ return 0; ++ } ++ } ++ ++ la_memmap_table = g_renew(struct la_memmap_entry, la_memmap_table, ++ la_memmap_entries + 1); ++ la_memmap_table[la_memmap_entries].address = cpu_to_le64(address); ++ la_memmap_table[la_memmap_entries].length = cpu_to_le64(length); ++ la_memmap_table[la_memmap_entries].type = cpu_to_le32(type); ++ la_memmap_entries++; ++ ++ return la_memmap_entries; ++} ++ ++static ram_addr_t get_hotplug_membase(ram_addr_t ram_size) ++{ ++ ram_addr_t sstart; ++ ++ if (ram_size <= 0x10000000) { ++ sstart = 0x90000000; ++ } else { ++ sstart = 0x90000000 + ROUND_UP((ram_size - 0x10000000), ++ LOONGARCH_HOTPLUG_MEM_ALIGN); ++ } ++ return sstart; ++} ++ ++static struct efi_memory_map_loongarch *init_memory_map(void *g_map) ++{ ++ struct efi_memory_map_loongarch *emap = g_map; ++ ++ emap->nr_map = 4; ++ emap->mem_freq = 266000000; ++ ++ emap->map[0].node_id = 0; ++ emap->map[0].mem_type = 1; ++ emap->map[0].mem_start = 0x0; ++#ifdef CONFIG_KVM ++ emap->map[0].mem_size = (loaderparams.ram_size > 0x10000000 ++ ? 256 : (loaderparams.ram_size >> 20)) - 18; ++#else ++ emap->map[0].mem_size = atoi(getenv("memsize")); ++#endif ++ ++ emap->map[1].node_id = 0; ++ emap->map[1].mem_type = 2; ++ emap->map[1].mem_start = 0x90000000; ++#ifdef CONFIG_KVM ++ emap->map[1].mem_size = (loaderparams.ram_size > 0x10000000 ++ ? (loaderparams.ram_size >> 20) - 256 : 0); ++#else ++ emap->map[1].mem_size = atoi(getenv("highmemsize")); ++#endif ++ ++ /* support for smbios */ ++ emap->map[2].node_id = 0; ++ emap->map[2].mem_type = 10; ++ emap->map[2].mem_start = SMBIOS_PHYSICAL_ADDRESS; ++ emap->map[2].mem_size = SMBIOS_SIZE_LIMIT >> 20; ++ ++ emap->map[3].node_id = 0; ++ emap->map[3].mem_type = 3; ++ emap->map[3].mem_start = 0xee00000; ++ emap->map[3].mem_size = RESERVED_SIZE_LIMIT >> 20; ++ ++ return emap; ++} ++ ++static uint64_t get_host_cpu_freq(void) ++{ ++ int fd = 0; ++ char buf[1024]; ++ uint64_t freq = 0, size = 0; ++ char *buf_p; ++ ++ fd = open("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", O_RDONLY); ++ if (fd == -1) { ++ fprintf(stderr, "/sys/devices/system/cpu/cpu0/cpufreq/ \ ++ cpuinfo_max_freq not exist!\n"); ++ fprintf(stderr, "Trying /proc/cpuinfo...\n"); ++ } else { ++ size = read(fd, buf, 16); ++ if (size == -1) { ++ fprintf(stderr, "read err...\n"); ++ } ++ close(fd); ++ freq = (uint64_t)atoi(buf); ++ return freq * 1000; ++ } ++ ++ fd = open("/proc/cpuinfo", O_RDONLY); ++ if (fd == -1) { ++ fprintf(stderr, "Failed to open /proc/cpuinfo!\n"); ++ return 0; ++ } ++ ++ size = read(fd, buf, 1024); ++ if (size == -1) { ++ fprintf(stderr, "read err...\n"); ++ } ++ close(fd); ++ ++ buf_p = strstr(buf, "MHz"); ++ if (buf_p) { ++ while (*buf_p != ':') { ++ buf_p++; ++ } ++ buf_p += 2; ++ } else { ++ buf_p = strstr(buf, "name"); ++ while (*buf_p != '@') { ++ buf_p++; ++ } ++ buf_p += 2; ++ } ++ ++ memcpy(buf, buf_p, 12); ++ buf_p = buf; ++ while ((*buf_p >= '0') && (*buf_p <= '9')) { ++ buf_p++; ++ } ++ *buf_p = '\0'; ++ ++ freq = (uint64_t)atoi(buf); ++ return freq * 1000 * 1000; ++} ++ ++static char *get_host_cpu_model_name(void) ++{ ++ int fd = 0; ++ int size = 0; ++ static char buf[1024]; ++ char *buf_p; ++ ++ fd = open("/proc/cpuinfo", O_RDONLY); ++ if (fd == -1) { ++ fprintf(stderr, "Failed to open /proc/cpuinfo!\n"); ++ return 0; ++ } ++ ++ size = read(fd, buf, 1024); ++ if (size == -1) { ++ fprintf(stderr, "read err...\n"); ++ } ++ close(fd); ++ buf_p = strstr(buf, "name"); ++ ++ while (*buf_p != ':') { ++ buf_p++; ++ } ++ buf_p = buf_p + 2; ++ memcpy(buf, buf_p, 40); ++ buf_p = buf; ++ while (*buf_p != '\n') { ++ buf_p++; ++ } ++ ++ *(buf_p) = '\0'; ++ ++ return buf; ++} ++ ++static void fw_conf_init(unsigned long ramsize) ++{ ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ int smp_cpus = ms->smp.cpus; ++ fw_config.ram_size = ramsize; ++ fw_config.mem_freq = 266000000; ++ fw_config.cpu_nr = smp_cpus ; ++ fw_config.cpu_clock_freq = get_host_cpu_freq(); ++} ++ ++static struct efi_cpuinfo_loongarch *init_cpu_info(void *g_cpuinfo_loongarch) ++{ ++ struct efi_cpuinfo_loongarch *c = g_cpuinfo_loongarch; ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ int smp_cpus = ms->smp.cpus; ++ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ ++ if (strstr(lsmc->cpu_name, "5000")) { ++ c->processor_id = 0x14c010; ++ } ++ c->cputype = Loongson3_comp; ++ c->cpu_clock_freq = get_host_cpu_freq(); ++ if (!c->cpu_clock_freq) { ++ c->cpu_clock_freq = 200000000; ++ } ++ c->total_node = 1; ++ c->nr_cpus = smp_cpus; ++ c->cpu_startup_core_id = 0; ++ c->reserved_cores_mask = 0xffff & (0xffff << smp_cpus); ++ ++ return c; ++} ++ ++static struct system_loongarch *init_system_loongarch(void *g_sysitem) ++{ ++ struct system_loongarch *s = g_sysitem; ++ ++ s->ccnuma_smp = 1; ++ s->ccnuma_smp = 0; ++ s->sing_double_channel = 1; ++ ++ return s; ++} ++ ++enum loongarch_irq_source_enum { ++ HT, I8259, UNKNOWN ++}; ++ ++static struct irq_source_routing_table *init_irq_source(void *g_irq_source) ++{ ++ struct irq_source_routing_table *irq_info = g_irq_source; ++ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ ++ irq_info->PIC_type = HT; ++ irq_info->ht_int_bit = 1 << 24; ++ irq_info->ht_enable = 0x0000d17b; ++ irq_info->node_id = 0; ++ ++ irq_info->pci_mem_start_addr = LS_ISA_MEM_BASE; ++ irq_info->pci_mem_end_addr = irq_info->pci_mem_start_addr + LS_ISA_MEM_SIZE - 1; ++ ++ if (strstr(lsmc->cpu_name, "5000")) { ++ irq_info->pci_io_start_addr = LS3A5K_ISA_IO_BASE; ++ } ++ irq_info->dma_noncoherent = 1; ++ return irq_info; ++} ++ ++static struct interface_info *init_interface_info(void *g_interface) ++{ ++ struct interface_info *inter = g_interface; ++ int flashsize = 0x80000; ++ ++ inter->vers = 0x0001; ++ inter->size = flashsize / 0x400; ++ inter->flag = 1; ++ ++ strcpy(inter->description, "PMON_Version_v2.1"); ++ ++ return inter; ++} ++ ++static struct board_devices *board_devices_info(void *g_board) ++{ ++ struct board_devices *bd = g_board; ++ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ ++ if (!strcmp(lsmc->bridge_name, "ls7a")) { ++ strcpy(bd->name, "Loongarch-3A-7A-1w-V1.03-demo"); ++ } ++ bd->num_resources = 10; ++ ++ return bd; ++} ++ ++static struct loongarch_special_attribute *init_special_info(void *g_special) ++{ ++ struct loongarch_special_attribute *special = g_special; ++ char update[11] = "2013-01-01"; ++ int VRAM_SIZE = 0x20000; ++ ++ strcpy(special->special_name, update); ++ special->resource[0].flags = 0; ++ special->resource[0].start = 0; ++ special->resource[0].end = VRAM_SIZE; ++ strcpy(special->resource[0].name, "SPMODULE"); ++ special->resource[0].flags |= DMA64_SUPPORTED; ++ ++ return special; ++} ++ ++static void init_loongarch_params(struct loongarch_params *lp) ++{ ++ void *p = boot_params_p; ++ ++ lp->memory_offset = (unsigned long long)init_memory_map(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct efi_memory_map_loongarch)); ++ ++ lp->cpu_offset = (unsigned long long)init_cpu_info(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct efi_cpuinfo_loongarch)); ++ ++ lp->system_offset = (unsigned long long)init_system_loongarch(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct system_loongarch)); ++ ++ lp->irq_offset = (unsigned long long)init_irq_source(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct irq_source_routing_table)); ++ ++ lp->interface_offset = (unsigned long long)init_interface_info(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct interface_info)); ++ ++ lp->boarddev_table_offset = (unsigned long long)board_devices_info(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct board_devices)); ++ ++ lp->special_offset = (unsigned long long)init_special_info(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct loongarch_special_attribute)); ++ ++ boot_params_p = p; ++} ++ ++static void init_smbios(struct smbios_tables *smbios) ++{ ++ smbios->vers = 1; ++ smbios->vga_bios = 1; ++ init_loongarch_params(&(smbios->lp)); ++} ++ ++static void init_efi(struct efi_loongarch *efi) ++{ ++ init_smbios(&(efi->smbios)); ++} ++ ++static int init_boot_param(struct boot_params *bp) ++{ ++ init_efi(&(bp->efi)); ++ ++ return 0; ++} ++ ++static unsigned int ls3a5k_aui_boot_code[] = { ++ 0x0380200d, /* ori $r13,$r0,0x8 */ ++ 0x0400002d, /* csrwr $r13,0x0 */ ++ 0x0401000e, /* csrrd $r14,0x40 */ ++ 0x0343fdce, /* andi $r14,$r14,0xff */ ++ 0x143fc02c, /* lu12i.w $r12,261889(0x1fe01) */ ++ 0x1600000c, /* lu32i.d $r12,0 */ ++ 0x0320018c, /* lu52i.d $r12,$r12,-1792(0x800) */ ++ 0x03400dcf, /* andi $r15,$r14,0x3 */ ++ 0x004121ef, /* slli.d $r15,$r15,0x8 */ ++ 0x00153d8c, /* or $r12,$r12,$r15 */ ++ 0x034031d0, /* andi $r16,$r14,0xc */ ++ 0x0041aa10, /* slli.d $r16,$r16,0x2a */ ++ 0x0015418c, /* or $r12,$r12,$r16 */ ++ 0x28808184, /* ld.w $r4,$r12,32(0x20) */ ++ 0x43fffc9f, /* beqz $r4,0 -4 */ ++ 0x28c08184, /* ld.d $r4,$r12,32(0x20) */ ++ 0x28c0a183, /* ld.d $r3,$r12,40(0x28) */ ++ 0x28c0c182, /* ld.d $r2,$r12,48(0x30) */ ++ 0x28c0e185, /* ld.d $r5,$r12,56(0x38) */ ++ 0x4c000080, /* jirl $r0,$r4,0 */ ++}; ++ ++static int set_bootparam_uefi(ram_addr_t initrd_offset, long initrd_size) ++{ ++ long params_size; ++ char memenv[32]; ++ char highmemenv[32]; ++ void *params_buf; ++ unsigned long *parg_env; ++ int ret = 0; ++ ++ /* Allocate params_buf for command line. */ ++ params_size = 0x100000; ++ params_buf = g_malloc0(params_size); ++ ++ /* ++ * Layout of params_buf looks like this: ++ * argv[0], argv[1], 0, env[0], env[1], ...env[i], 0, ++ * argv[0]'s data, argv[1]'s data, env[0]'data, ..., env[i]'s data, 0 ++ */ ++ parg_env = (void *)params_buf; ++ ++ ret = (3 + 1) * sizeof(target_ulong); ++ *parg_env++ = (BOOTPARAM_ADDR + ret); ++ ret += (1 + snprintf(params_buf + ret, COMMAND_LINE_SIZE - ret, "g")); ++ ++ /* argv1 */ ++ *parg_env++ = BOOTPARAM_ADDR + ret; ++ if (initrd_size > 0) ++ ret += (1 + snprintf(params_buf + ret, COMMAND_LINE_SIZE - ret, ++ "rd_start=0x%llx rd_size=%li %s", ++ PHYS_TO_VIRT((uint32_t)initrd_offset), ++ initrd_size, loaderparams.kernel_cmdline)); ++ else ++ ret += (1 + snprintf(params_buf + ret, COMMAND_LINE_SIZE - ret, "%s", ++ loaderparams.kernel_cmdline)); ++ ++ /* argv2 */ ++ *parg_env++ = 0; ++ ++ /* env */ ++ sprintf(memenv, "%lu", loaderparams.ram_size > 0x10000000 ++ ? 256 : (loaderparams.ram_size >> 20)); ++ sprintf(highmemenv, "%lu", loaderparams.ram_size > 0x10000000 ++ ? (loaderparams.ram_size >> 20) - 256 : 0); ++ ++ setenv("memsize", memenv, 1); ++ setenv("highmemsize", highmemenv, 1); ++ ++ ret = ((ret + 32) & ~31); ++ ++ boot_params_buf = (void *)(params_buf + ret); ++ boot_params_p = boot_params_buf + align(sizeof(struct boot_params)); ++ init_boot_param(boot_params_buf); ++ rom_add_blob_fixed("params", params_buf, params_size, ++ BOOTPARAM_PHYADDR); ++ loaderparams.a0 = 2; ++ loaderparams.a1 = BOOTPARAM_ADDR; ++ loaderparams.a2 = BOOTPARAM_ADDR + ret; ++ ++ return 0; ++} ++ ++static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) ++{ ++ return addr & 0x1fffffffll; ++} ++ ++static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg, ++ uint64_t highram_size, ++ uint64_t phyAddr_initrd) ++{ ++ int64_t entry, kernel_low, kernel_high; ++ long initrd_size = 0; ++ uint64_t initrd_offset = 0; ++ void *cmdline_buf; ++ int ret = 0; ++ ++ ret = load_elf(loaderparams.kernel_filename, NULL, cpu_loongarch_virt_to_phys, NULL, ++ (uint64_t *)&entry, (uint64_t *)&kernel_low, ++ (uint64_t *)&kernel_high, NULL, 0, EM_LOONGARCH, 1, 0); ++ ++ if(0 > ret) { ++ error_report("kernel image load error"); ++ exit(1); ++ } ++ ++ fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ENTRY, entry); ++ ++ if (loaderparams.initrd_filename) { ++ initrd_size = get_image_size(loaderparams.initrd_filename); ++ if (0 < initrd_size) { ++ if (initrd_size > highram_size) { ++ error_report("initrd size is too big, should below %ld MB", ++ highram_size / S_1MiB); ++ /*prevent write io memory address space*/ ++ exit(1); ++ } ++ initrd_offset = (phyAddr_initrd - initrd_size) & TARGET_REALPAGE_MASK; ++ initrd_size = load_image_targphys(loaderparams.initrd_filename, ++ initrd_offset, ++ loaderparams.ram_size - initrd_offset); ++ fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_offset); ++ fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); ++ } else { ++ error_report("initrd image size is error"); ++ } ++ } ++ ++ cmdline_buf = g_malloc0(COMMAND_LINE_SIZE); ++ if (initrd_size > 0) ++ ret = (1 + snprintf(cmdline_buf, COMMAND_LINE_SIZE, ++ "rd_start=0x%llx rd_size=%li %s", ++ PHYS_TO_VIRT(initrd_offset), ++ initrd_size, loaderparams.kernel_cmdline)); ++ else ++ ret = (1 + snprintf(cmdline_buf, COMMAND_LINE_SIZE, "%s", ++ loaderparams.kernel_cmdline)); ++ ++ fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, ret); ++ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, (const char *)cmdline_buf); ++ ++ return ; ++} ++ ++static int64_t load_kernel(void) ++{ ++ int64_t entry, kernel_low, kernel_high; ++ long initrd_size = 0; ++ ram_addr_t initrd_offset = 0; ++ ++ load_elf(loaderparams.kernel_filename, NULL, cpu_loongarch_virt_to_phys, NULL, ++ (uint64_t *)&entry, (uint64_t *)&kernel_low, ++ (uint64_t *)&kernel_high, NULL, 0, EM_LOONGARCH, 1, 0); ++ ++ if (loaderparams.initrd_filename) { ++ initrd_size = get_image_size(loaderparams.initrd_filename); ++ ++ if (initrd_size > 0) { ++ initrd_offset = (kernel_high * 4 + ~TARGET_REALPAGE_MASK) ++ & TARGET_REALPAGE_MASK; ++ initrd_size = load_image_targphys(loaderparams.initrd_filename, ++ initrd_offset, ++ loaderparams.ram_size - initrd_offset); ++ } ++ } ++ set_bootparam_uefi(initrd_offset, initrd_size); ++ ++ return entry; ++} ++ ++static void main_cpu_reset(void *opaque) ++{ ++ ResetData *s = (ResetData *)opaque; ++ CPULOONGARCHState *env = &s->cpu->env; ++ ++ cpu_reset(CPU(s->cpu)); ++ env->active_tc.PC = s->vector; ++ env->active_tc.gpr[4] = loaderparams.a0; ++ env->active_tc.gpr[5] = loaderparams.a1; ++ env->active_tc.gpr[6] = loaderparams.a2; ++} ++ ++void slave_cpu_reset(void *opaque) ++{ ++ ResetData *s = (ResetData *)opaque; ++ ++ cpu_reset(CPU(s->cpu)); ++} ++ ++ ++/* KVM_IRQ_LINE irq field index values */ ++#define KVM_LOONGARCH_IRQ_TYPE_SHIFT 24 ++#define KVM_LOONGARCH_IRQ_TYPE_MASK 0xff ++#define KVM_LOONGARCH_IRQ_VCPU_SHIFT 16 ++#define KVM_LOONGARCH_IRQ_VCPU_MASK 0xff ++#define KVM_LOONGARCH_IRQ_NUM_SHIFT 0 ++#define KVM_LOONGARCH_IRQ_NUM_MASK 0xffff ++ ++/* irq_type field */ ++#define KVM_LOONGARCH_IRQ_TYPE_CPU_IP 0 ++#define KVM_LOONGARCH_IRQ_TYPE_CPU_IO 1 ++#define KVM_LOONGARCH_IRQ_TYPE_HT 2 ++#define KVM_LOONGARCH_IRQ_TYPE_MSI 3 ++#define KVM_LOONGARCH_IRQ_TYPE_IOAPIC 4 ++ ++static void legacy_set_irq(void *opaque, int irq, int level) ++{ ++ qemu_irq *pic = opaque; ++ ++ qemu_set_irq(pic[irq], level); ++} ++ ++typedef struct ls3a_intctlstate { ++ uint8_t nodecounter_reg[0x100]; ++ uint8_t pm_reg[0x100]; ++ uint8_t msi_reg[0x8]; ++ CPULOONGARCHState **env; ++ DeviceState *apicdev; ++ qemu_irq *ioapic_irq; ++#ifdef CONFIG_KVM ++ struct loongarch_kvm_irqchip chip; ++#endif ++} ls3a_intctlstate; ++ ++typedef struct ls3a_func_args { ++ ls3a_intctlstate *state; ++ uint64_t base; ++ uint32_t mask; ++ uint8_t *mem; ++} ls3a_func_args; ++ ++static uint64_t ls3a_msi_mem_read(void *opaque, hwaddr addr, unsigned size) ++{ ++ return 0; ++} ++ ++static void ls3a_msi_mem_write(void *opaque, hwaddr addr, ++ uint64_t val, unsigned size) ++{ ++ struct kvm_msi msi; ++ apicState *apic; ++ ++ apic = (apicState *)opaque; ++ msi.address_lo = 0; ++ msi.address_hi = 0; ++ msi.data = val & 0xff; ++ msi.flags = 0; ++ memset(msi.pad, 0, sizeof(msi.pad)); ++ ++ if (kvm_irqchip_in_kernel()) { ++ kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi); ++ } else { ++ qemu_set_irq(apic->irq[msi.data], 1); ++ } ++} ++ ++ ++static const MemoryRegionOps ls3a_msi_ops = { ++ .read = ls3a_msi_mem_read, ++ .write = ls3a_msi_mem_write, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++}; ++ ++ ++static const VMStateDescription vmstate_ls3a_msi = { ++ .name = "ls3a-msi", ++ .version_id = 0, ++ .minimum_version_id = 0, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT8_ARRAY(msi_reg, ls3a_intctlstate, 0x8), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static void ioapic_handler(void *opaque, int irq, int level) ++{ ++ apicState *apic; ++ int kvm_irq; ++ ++ apic = (apicState *)opaque; ++ ++ if (kvm_irqchip_in_kernel()) { ++ kvm_irq = (KVM_LOONGARCH_IRQ_TYPE_IOAPIC << KVM_LOONGARCH_IRQ_TYPE_SHIFT) ++ | (0 << KVM_LOONGARCH_IRQ_VCPU_SHIFT) | irq; ++ kvm_set_irq(kvm_state, kvm_irq, !!level); ++ } else { ++ qemu_set_irq(apic->irq[irq], level); ++ } ++} ++ ++static void *ls3a_intctl_init(MachineState *machine, CPULOONGARCHState *env[]) ++{ ++ qemu_irq *irqhandler; ++ ls3a_intctlstate *s; ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ LoongarchMachineClass *mc = LoongarchMACHINE_GET_CLASS(lsms); ++ DeviceState *dev; ++ SysBusDevice *busdev; ++ MemoryRegion *address_space_mem = get_system_memory(); ++ MemoryRegion *iomem = NULL; ++ int i; ++ ++ s = g_malloc0(sizeof(ls3a_intctlstate)); ++ ++ if (!s) { ++ return NULL; ++ } ++ ++ /*Add MSI mmio memory*/ ++ iomem = g_new(MemoryRegion, 1); ++ memory_region_init_io(iomem, NULL, &ls3a_msi_ops, lsms->apic, ++ "ls3a_msi", 0x8); ++ memory_region_add_subregion(address_space_mem, ++ MSI_ADDR_LOW, iomem); ++ vmstate_register(NULL, 0, &vmstate_ls3a_msi, s); ++ ++ s->env = env; ++ ++ if (!strcmp(mc->bridge_name, "ls7a")) { ++ if (lsms->apic_xrupt_override) { ++ DPRINTF("irqchip in kernel %d\n", kvm_irqchip_in_kernel()); ++#ifdef CONFIG_KVM ++ if (kvm_has_gsi_routing()) { ++ for (i = 0; i < 32; ++i) { ++ kvm_irqchip_add_irq_route(kvm_state, i, 0, i); ++ } ++ kvm_gsi_routing_allowed = true; ++ } ++ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled(); ++#endif ++ } ++ ++ irqhandler = qemu_allocate_irqs(ioapic_handler, lsms->apic, 64); ++ dev = qdev_new("ioapic"); ++ busdev = SYS_BUS_DEVICE(dev); ++ sysbus_realize_and_unref(busdev, &error_fatal); ++ sysbus_mmio_map(busdev, 0, mc->ls7a_ioapic_reg_base); ++ s->ioapic_irq = irqhandler; ++ s->apicdev = dev; ++ return s->ioapic_irq; ++ } ++ return NULL; ++} ++ ++/* Network support */ ++static void network_init(PCIBus *pci_bus) ++{ ++ int i; ++ ++ for (i = 0; i < nb_nics; i++) { ++ NICInfo *nd = &nd_table[i]; ++ ++ if (!nd->model) { ++ nd->model = g_strdup("virtio-net-pci"); ++ } ++ ++ pci_nic_init_nofail(nd, pci_bus, nd->model, NULL); ++ } ++} ++ ++void loongarch_cpu_destroy(MachineState *machine, LOONGARCHCPU *cpu) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ unsigned int id; ++ int smp_cpus = machine->smp.cpus; ++ id = cpu->id; ++ qemu_unregister_reset(slave_cpu_reset, lsms->reset_info[id]); ++ g_free(lsms->reset_info[id]); ++ lsms->reset_info[id] = NULL; ++ ++ smp_cpus -= 1; ++ if (lsms->fw_cfg) { ++ fw_cfg_modify_i16(lsms->fw_cfg, FW_CFG_NB_CPUS, ++ (uint16_t)smp_cpus); ++ } ++ ++ qemu_del_vm_change_state_handler(cpu->cpuStateEntry); ++} ++ ++LOONGARCHCPU *loongarch_cpu_create(MachineState *machine, ++ LOONGARCHCPU *cpu, Error **errp) ++{ ++ CPULOONGARCHState *env; ++ unsigned int id; ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ int smp_cpus = machine->smp.cpus; ++ id = cpu->id; ++ env = &cpu->env; ++ cpu_states[id] = env; ++ env->CSR_TMID |= id; ++ ++ lsms = LoongarchMACHINE(machine); ++ lsms->reset_info[id] = g_malloc0(sizeof(ResetData)); ++ lsms->reset_info[id]->cpu = cpu; ++ lsms->reset_info[id]->vector = env->active_tc.PC; ++ qemu_register_reset(slave_cpu_reset, lsms->reset_info[id]); ++ ++ /* Init CPU internal devices */ ++ cpu_init_irq(cpu); ++ cpu_loongarch_clock_init(cpu); ++ ++ smp_cpus += 1; ++ if (lsms->fw_cfg) { ++ fw_cfg_modify_i16(lsms->fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); ++ } ++ cpu_init_ipi(lsms, env->irq[12], id); ++ cpu_init_apic(lsms, env, id); ++ ++ return cpu; ++} ++ ++static void fw_cfg_boot_set(void *opaque, const char *boot_device, ++ Error **errp) ++{ ++ fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); ++} ++ ++static FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, ++ LoongarchMachineState *lsms) ++{ ++ FWCfgState *fw_cfg; ++ uint64_t *numa_fw_cfg; ++ int i; ++ const CPUArchIdList *cpus; ++ MachineClass *mc = MACHINE_GET_CLASS(lsms); ++ MachineState *ms = MACHINE(OBJECT(lsms)); ++ int max_cpus = ms->smp.max_cpus; ++ int smp_cpus = ms->smp.cpus; ++ int nb_numa_nodes = ms->numa_state->num_nodes; ++ NodeInfo *numa_info = ms->numa_state->nodes; ++ ++ fw_cfg = fw_cfg_init_mem_wide(FW_CFG_ADDR + 8, FW_CFG_ADDR, 8, 0, NULL); ++ fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); ++ fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); ++ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); ++ ++ /* allocate memory for the NUMA channel: one (64bit) word for the number ++ * of nodes, one word for each VCPU->node and one word for each node to ++ * hold the amount of memory. ++ */ ++ numa_fw_cfg = g_new0(uint64_t, 1 + max_cpus + nb_numa_nodes); ++ numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes); ++ cpus = mc->possible_cpu_arch_ids(MACHINE(lsms)); ++ for (i = 0; i < cpus->len; i++) { ++ unsigned int apic_id = cpus->cpus[i].arch_id; ++ assert(apic_id < max_cpus); ++ numa_fw_cfg[apic_id + 1] = cpu_to_le64(cpus->cpus[i].props.node_id); ++ } ++ for (i = 0; i < nb_numa_nodes; i++) { ++ numa_fw_cfg[max_cpus + 1 + i] = ++ cpu_to_le64(numa_info[i].node_mem); ++ } ++ fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg, ++ (1 + max_cpus + nb_numa_nodes) * ++ sizeof(*numa_fw_cfg)); ++ ++ qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); ++ return fw_cfg; ++} ++ ++static void loongarch_build_smbios(LoongarchMachineState *lsms) ++{ ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ MachineState *ms = MACHINE(OBJECT(lsms)); ++ uint8_t *smbios_tables, *smbios_anchor; ++ size_t smbios_tables_len, smbios_anchor_len; ++ const char *product = "QEMU Virtual Machine"; ++ ms->smp.cores = 4; ++ ++ if (!lsms->fw_cfg) { ++ return; ++ } ++ ++ if (kvm_enabled()) { ++ if (strstr(lsmc->cpu_name, "5000")) { ++ product = "KVM"; ++ } ++ } else { ++ product = "Loongarch-3A5K-7A1000-TCG"; ++ } ++ ++ host_cpufreq = get_host_cpu_freq(); ++ ++ smbios_set_defaults("Loongson", product, lsmc->cpu_name, false, ++ true, NULL, NULL, SMBIOS_ENTRY_POINT_30); ++ ++ smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len, ++ &smbios_anchor, &smbios_anchor_len, &error_fatal); ++ ++ if (smbios_anchor) { ++ fw_cfg_add_file(lsms->fw_cfg, "etc/smbios/smbios-tables", ++ smbios_tables, smbios_tables_len); ++ fw_cfg_add_file(lsms->fw_cfg, "etc/smbios/smbios-anchor", ++ smbios_anchor, smbios_anchor_len); ++ } ++} ++ ++static ++void loongarch_machine_done(Notifier *notifier, void *data) ++{ ++ LoongarchMachineState *lsms = container_of(notifier, ++ LoongarchMachineState, machine_done); ++ loongarch_acpi_setup(); ++ loongarch_build_smbios(lsms); ++} ++ ++#ifdef CONFIG_TCG ++#define FEATURE_REG 0x1fe00008 ++#define VENDOR_REG 0x1fe00010 ++#define CPUNAME_REG 0x1fe00020 ++#define OTHER_FUNC_REG 0x1fe00420 ++#define _str(x) #x ++#define str(x) _str(x) ++#define SIMPLE_OPS(ADDR, SIZE) \ ++({\ ++ MemoryRegion *iomem = g_new(MemoryRegion, 1);\ ++ memory_region_init_io(iomem, NULL, &loongarch_qemu_ops, \ ++ (void *)ADDR, str(ADDR) , SIZE);\ ++ memory_region_add_subregion_overlap(address_space_mem, ADDR, iomem, 1);\ ++}) ++ ++static int reg180; ++ ++static void loongarch_qemu_write(void *opaque, hwaddr addr, ++ uint64_t val, unsigned size) ++{ ++ addr = ((hwaddr)(long)opaque) + addr; ++ addr = addr & 0xffffffff; ++ switch (addr) { ++ case 0x1fe00180: ++ reg180 = val; ++ break; ++ } ++} ++ ++static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size) ++{ ++ uint64_t feature = 0UL; ++ addr = ((hwaddr)(long)opaque) + addr; ++ addr = addr & 0xffffffff; ++ switch (addr) { ++ case 0x1fe00180: ++ return reg180; ++ case 0x1001041c: ++ return 0xa800; ++ case FEATURE_REG: ++ feature |= 1UL << 2 | 1UL << 3 | 1UL << 4 | 1UL << 11; ++ return feature ; ++ case VENDOR_REG: ++ return *(uint64_t *)"Loongson-3A5000"; ++ case CPUNAME_REG: ++ return *(uint64_t *)"3A5000"; ++ case 0x10013ffc: ++ return 0x80; ++ } ++ return 0; ++} ++ ++static const MemoryRegionOps loongarch_qemu_ops = { ++ .read = loongarch_qemu_read, ++ .write = loongarch_qemu_write, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++ .valid = { ++ .min_access_size = 4, ++ .max_access_size = 8, ++ }, ++ .impl = { ++ .min_access_size = 4, ++ .max_access_size = 8, ++ }, ++}; ++#endif ++ ++ ++static void loongarch_system_flash_cleanup_unused(LoongarchMachineState *lsms) ++{ ++ char *prop_name; ++ int i; ++ Object *dev_obj; ++ ++ for (i = 0; i < ARRAY_SIZE(lsms->flash); i++) { ++ dev_obj = OBJECT(lsms->flash[i]); ++ if (!object_property_get_bool(dev_obj, "realized", &error_abort)) { ++ prop_name = g_strdup_printf("pflash%d", i); ++ object_property_del(OBJECT(lsms), prop_name); ++ g_free(prop_name); ++ object_unparent(dev_obj); ++ lsms->flash[i] = NULL; ++ } ++ } ++} ++ ++ ++static bool loongarch_system_flash_init( LoongarchMachineState *lsms) ++{ ++ int i = 0; ++ int64_t size = 0; ++ PFlashCFI01 *pflash = NULL; ++ BlockBackend *pflash_blk; ++ ++ for(i = 0; i < ARRAY_SIZE(lsms->flash); i++) { ++ pflash_blk = NULL; ++ pflash = NULL; ++ ++ pflash = lsms->flash[i]; ++ pflash_cfi01_legacy_drive(pflash, ++ drive_get(IF_PFLASH, 0, i)); ++ ++ pflash_blk = pflash_cfi01_get_blk(pflash); ++ /*The pflash0 must be exist, or not support boot by pflash*/ ++ if(pflash_blk == NULL) { ++ if(i == 0) { ++ return false; ++ } else { ++ break; ++ } ++ } ++ ++ size = blk_getlength(pflash_blk); ++ if (size == 0 || size % FLASH_SECTOR_SIZE != 0) { ++ error_report("system firmware block device %s has invalid size " ++ "%" PRId64, ++ blk_name(pflash_blk), size); ++ error_report("its size must be a non-zero multiple of 0x%x", ++ FLASH_SECTOR_SIZE); ++ exit(1); ++ } ++ qdev_prop_set_uint32(DEVICE(pflash), "num-blocks", ++ size / FLASH_SECTOR_SIZE); ++ sysbus_realize_and_unref(SYS_BUS_DEVICE(pflash), &error_fatal); ++ if(i == 0) { ++ sysbus_mmio_map(SYS_BUS_DEVICE(pflash), 0, LS_BIOS_BASE); ++ } else { ++ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(pflash), 0, LS_BIOS_VAR_BASE, 1); ++ } ++ } ++ ++ return true; ++} ++static void ls3a5k_bios_init(LoongarchMachineState *lsms, ++ ram_addr_t ram_size, ++ uint64_t highram_size, ++ uint64_t phyAddr_initrd, ++ const char *kernel_filename, ++ const char *kernel_cmdline, ++ const char *initrd_filename) ++{ ++ MemoryRegion *bios; ++ bool fw_cfg_used = false; ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ char *filename; ++ int bios_size; ++ const char *bios_name; ++ ++ bios_name = MACHINE(lsms)->firmware; ++ if (kernel_filename) { ++ loaderparams.ram_size = ram_size; ++ loaderparams.kernel_filename = kernel_filename; ++ loaderparams.kernel_cmdline = kernel_cmdline; ++ loaderparams.initrd_filename = initrd_filename; ++ } ++ ++ if(loongarch_system_flash_init(lsms)) { ++ fw_cfg_used = true; ++ } else { ++ bios = g_new(MemoryRegion, 1); ++ memory_region_init_ram(bios, NULL, "loongarch.bios", LS_BIOS_SIZE, &error_fatal); ++ memory_region_set_readonly(bios, true); ++ memory_region_add_subregion(get_system_memory(), LS_BIOS_BASE, bios); ++ ++ /* BIOS load */ ++ if (bios_name) { ++ if (access(bios_name, R_OK) == 0) { ++ load_image_targphys(bios_name, LS_BIOS_BASE, LS_BIOS_SIZE); ++ } else { ++ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); ++ load_image_targphys(filename, LS_BIOS_BASE, LS_BIOS_SIZE); ++ g_free(filename); ++ } ++ fw_cfg_used = true; ++ } else { ++ if (strstr(lsmc->cpu_name, "5000")) { ++ bios_size = sizeof(ls3a5k_aui_boot_code); ++ rom_add_blob_fixed("bios", ls3a5k_aui_boot_code, bios_size, LS_BIOS_BASE); ++ } ++ ++ if (kernel_filename) { ++ lsms->reset_info[0]->vector = load_kernel(); ++ } else { ++ error_report("Please specify at lease one of -bios and -kernel"); ++ exit(1); ++ } ++ } ++ } ++ ++ loongarch_system_flash_cleanup_unused(lsms); ++ ++ if (fw_cfg_used) { ++ lsms->fw_cfg = loongarch_fw_cfg_init(ram_size, lsms); ++ rom_set_fw(lsms->fw_cfg); ++ fw_conf_init(ram_size); ++ rom_add_blob_fixed("fw_conf", (void *)&fw_config, ++ sizeof(fw_config), FW_CONF_ADDR); ++ ++ if (kernel_filename) { ++ fw_cfg_add_kernel_info(lsms->fw_cfg, highram_size, phyAddr_initrd); ++ } ++ } ++ ++ if (lsms->fw_cfg != NULL) { ++ fw_cfg_add_file(lsms->fw_cfg, "etc/memmap", ++ la_memmap_table, ++ sizeof(struct la_memmap_entry) * (la_memmap_entries)); ++ } ++ ++ return ; ++} ++static void create_fdt(LoongarchMachineState *lsms) ++{ ++ lsms->fdt = create_device_tree(&lsms->fdt_size); ++ if (!lsms->fdt) { ++ error_report("create_device_tree() failed"); ++ exit(1); ++ } ++ ++ /* Header */ ++ qemu_fdt_setprop_string(lsms->fdt, "/", "compatible", ++ "linux,dummy-loongson3"); ++ qemu_fdt_setprop_cell(lsms->fdt, "/", "#address-cells", 0x2); ++ qemu_fdt_setprop_cell(lsms->fdt, "/", "#size-cells", 0x2); ++} ++ ++static void fdt_add_cpu_nodes(const LoongarchMachineState *lsms) ++{ ++ int num; ++ const MachineState *ms = MACHINE(lsms); ++ int smp_cpus = ms->smp.cpus; ++ ++ qemu_fdt_add_subnode(lsms->fdt, "/cpus"); ++ qemu_fdt_setprop_cell(lsms->fdt, "/cpus", "#address-cells", 0x1); ++ qemu_fdt_setprop_cell(lsms->fdt, "/cpus", "#size-cells", 0x0); ++ ++ /* cpu nodes */ ++ for (num = smp_cpus - 1; num >= 0; num--) { ++ char *nodename = g_strdup_printf("/cpus/cpu@%d", num); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(qemu_get_cpu(num)); ++ ++ qemu_fdt_add_subnode(lsms->fdt, nodename); ++ qemu_fdt_setprop_string(lsms->fdt, nodename, "device_type", "cpu"); ++ qemu_fdt_setprop_string(lsms->fdt, nodename, "compatible", ++ cpu->dtb_compatible); ++ qemu_fdt_setprop_cell(lsms->fdt, nodename, "reg", num); ++ qemu_fdt_setprop_cell(lsms->fdt, nodename, "phandle", ++ qemu_fdt_alloc_phandle(lsms->fdt)); ++ g_free(nodename); ++ } ++ ++ /*cpu map */ ++ qemu_fdt_add_subnode(lsms->fdt, "/cpus/cpu-map"); ++ ++ for (num = smp_cpus - 1; num >= 0; num--) { ++ char *cpu_path = g_strdup_printf("/cpus/cpu@%d", num); ++ char *map_path; ++ ++ if (ms->smp.threads > 1) { ++ map_path = g_strdup_printf( ++ "/cpus/cpu-map/socket%d/core%d/thread%d", ++ num / (ms->smp.cores * ms->smp.threads), ++ (num / ms->smp.threads) % ms->smp.cores, ++ num % ms->smp.threads); ++ } else { ++ map_path = g_strdup_printf( ++ "/cpus/cpu-map/socket%d/core%d", ++ num / ms->smp.cores, ++ num % ms->smp.cores); ++ } ++ qemu_fdt_add_path(lsms->fdt, map_path); ++ qemu_fdt_setprop_phandle(lsms->fdt, map_path, "cpu", cpu_path); ++ ++ g_free(map_path); ++ g_free(cpu_path); ++ } ++} ++ ++static void fdt_add_fw_cfg_node(const LoongarchMachineState *lsms) ++{ ++ char *nodename; ++ hwaddr base = FW_CFG_ADDR; ++ ++ nodename = g_strdup_printf("/fw_cfg@%" PRIx64, base); ++ qemu_fdt_add_subnode(lsms->fdt, nodename); ++ qemu_fdt_setprop_string(lsms->fdt, nodename, ++ "compatible", "qemu,fw-cfg-mmio"); ++ qemu_fdt_setprop_sized_cells(lsms->fdt, nodename, "reg", ++ 2, base, 2, 0x8); ++ qemu_fdt_setprop(lsms->fdt, nodename, "dma-coherent", NULL, 0); ++ g_free(nodename); ++} ++ ++static void fdt_add_pcie_node(const LoongarchMachineState *lsms) ++{ ++ char *nodename; ++ hwaddr base_mmio = LS_ISA_MEM_BASE; ++ hwaddr size_mmio = LS_ISA_MEM_SIZE; ++ hwaddr base_pio = LS3A5K_ISA_IO_BASE; ++ hwaddr size_pio = LS_ISA_IO_SIZE; ++ hwaddr base_pcie = LS_PCIECFG_BASE; ++ hwaddr size_pcie = LS_PCIECFG_SIZE; ++ hwaddr base = base_pcie; ++ ++ nodename = g_strdup_printf("/pcie@%" PRIx64, base); ++ qemu_fdt_add_subnode(lsms->fdt, nodename); ++ qemu_fdt_setprop_string(lsms->fdt, nodename, ++ "compatible", "pci-host-ecam-generic"); ++ qemu_fdt_setprop_string(lsms->fdt, nodename, "device_type", "pci"); ++ qemu_fdt_setprop_cell(lsms->fdt, nodename, "#address-cells", 3); ++ qemu_fdt_setprop_cell(lsms->fdt, nodename, "#size-cells", 2); ++ qemu_fdt_setprop_cell(lsms->fdt, nodename, "linux,pci-domain", 0); ++ qemu_fdt_setprop_cells(lsms->fdt, nodename, "bus-range", 0, ++ PCIE_MMCFG_BUS(LS_PCIECFG_SIZE - 1)); ++ qemu_fdt_setprop(lsms->fdt, nodename, "dma-coherent", NULL, 0); ++ qemu_fdt_setprop_sized_cells(lsms->fdt, nodename, "reg", ++ 2, base_pcie, 2, size_pcie); ++ qemu_fdt_setprop_sized_cells(lsms->fdt, nodename, "ranges", ++ 1, FDT_PCI_RANGE_IOPORT, 2, 0, ++ 2, base_pio, 2, size_pio, ++ 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, ++ 2, base_mmio, 2, size_mmio); ++ g_free(nodename); ++ qemu_fdt_dumpdtb(lsms->fdt, lsms->fdt_size); ++} ++ ++static void ls3a5k_init(MachineState *args) ++{ ++ int i; ++ const char *cpu_model = args->cpu_type; ++ const char *kernel_filename = args->kernel_filename; ++ const char *kernel_cmdline = args->kernel_cmdline; ++ const char *initrd_filename = args->initrd_filename; ++ ++ ram_addr_t ram_size = args->ram_size; ++ MemoryRegion *address_space_mem = get_system_memory(); ++ ram_addr_t offset = 0; ++ MemoryRegion *isa_io = g_new(MemoryRegion, 1); ++ MemoryRegion *isa_mem = g_new(MemoryRegion, 1); ++ MachineState *machine = args; ++ MachineClass *mc = MACHINE_GET_CLASS(machine); ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ int smp_cpus = machine->smp.cpus; ++ int nb_numa_nodes = machine->numa_state->num_nodes; ++ NodeInfo *numa_info = machine->numa_state->nodes; ++ LOONGARCHCPU *cpu; ++ CPULOONGARCHState *env; ++ qemu_irq *ls7a_apic = NULL; ++ qemu_irq *pirq = NULL; ++ PCIBus *pci_bus = NULL; ++ char *ramName = NULL; ++ uint64_t lowram_size = 0, highram_size = 0, phyAddr = 0, ++ memmap_size = 0, highram_end_addr = 0; ++ ++ CPUArchIdList *possible_cpus; ++ if (strstr(lsmc->cpu_name, "5000")) { ++ if (strcmp(cpu_model, LOONGARCH_CPU_TYPE_NAME("Loongson-3A5000")) && ++ strcmp(cpu_model, LOONGARCH_CPU_TYPE_NAME("host"))) { ++ error_report("machine type %s does not match cpu type %s", ++ lsmc->cpu_name, cpu_model); ++ exit(1); ++ } ++ if (kvm_enabled()) { ++ kvm_vm_ioctl(kvm_state, KVM_LARCH_SET_CPUCFG, ls3a5k_cpucfgs); ++ } ++ } ++ ++ create_fdt(lsms); ++ ++ DPRINTF("isa 0x%lx\n", lsmc->isa_io_base); ++ DPRINTF("ht1lo 0x%lx\n", lsmc->ht1lo_pcicfg_base); ++ DPRINTF("cpu_name %s bridge_name %s\n", ++ lsmc->cpu_name, lsmc->bridge_name); ++ ++ /* init CPUs */ ++ mc->possible_cpu_arch_ids(machine); ++ possible_cpus = machine->possible_cpus; ++ ++ for (i = 0; i < smp_cpus; i++) { ++ Object *obj = NULL; ++ Error *local_err = NULL; ++ ++ obj = object_new(possible_cpus->cpus[i].type); ++ ++ object_property_set_uint(obj, "id", possible_cpus->cpus[i].arch_id, ++ &local_err); ++ object_property_set_bool(obj, "realized", true, &local_err); ++ ++ object_unref(obj); ++ error_propagate(&error_fatal, local_err); ++ ++ cpu = LOONGARCH_CPU(CPU(obj)); ++ if (cpu == NULL) { ++ fprintf(stderr, "Unable to find CPU definition\n"); ++ exit(1); ++ } ++ ++ env = &cpu->env; ++ cpu_states[i] = env; ++ env->CSR_TMID |= i; ++ ++ lsms->reset_info[i] = g_malloc0(sizeof(ResetData)); ++ lsms->reset_info[i]->cpu = cpu; ++ lsms->reset_info[i]->vector = env->active_tc.PC; ++ if (i == 0) { ++ qemu_register_reset(main_cpu_reset, lsms->reset_info[i]); ++ } else { ++ qemu_register_reset(slave_cpu_reset, lsms->reset_info[i]); ++ } ++ ++ /* Init CPU internal devices */ ++ cpu_init_irq(cpu); ++ cpu_loongarch_clock_init(cpu); ++ cpu_init_ipi(lsms, env->irq[12], i); ++ cpu_init_apic(lsms, env, i); ++ } ++ ++ lsms->hotpluged_cpu_num = 0; ++ fdt_add_cpu_nodes(lsms); ++ env = cpu_states[0]; ++ ++ /* node0 mem*/ ++ phyAddr = (uint64_t)0; ++ MemoryRegion *lowmem = g_new(MemoryRegion, 1); ++ ramName = g_strdup_printf("loongarch_ls3a.node%d.lowram", 0); ++ ++ lowram_size = MIN(ram_size, 256 * 0x100000); ++ memory_region_init_alias(lowmem, NULL, ramName, machine->ram, 0, lowram_size); ++ memory_region_add_subregion(address_space_mem, phyAddr, lowmem); ++ ++ offset += lowram_size; ++ if (nb_numa_nodes > 0) { ++ highram_size = numa_info[0].node_mem - S_256MiB; ++ if (numa_info[0].node_mem > S_1GiB) { ++ memmap_size = numa_info[0].node_mem - S_1GiB; ++ la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); ++ } ++ } else { ++ highram_size = ram_size - S_256MiB; ++ if (ram_size > S_1GiB) { ++ memmap_size = ram_size - S_1GiB; ++ la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); ++ } ++ } ++ ++ phyAddr = (uint64_t)0x90000000; ++ MemoryRegion *highmem = g_new(MemoryRegion, 1); ++ ramName = g_strdup_printf("loongarch_ls3a.node%d.highram", 0); ++ memory_region_init_alias(highmem, NULL, ramName, ++ machine->ram, offset, highram_size); ++ memory_region_add_subregion(address_space_mem, ++ phyAddr, highmem); ++ offset += highram_size; ++ phyAddr += highram_size; ++ ++ /* initrd address use high mem from high to low */ ++ highram_end_addr = phyAddr; ++ /* node1~ nodemax */ ++ for (i = 1; i < nb_numa_nodes; i++) { ++ MemoryRegion *nodemem = g_new(MemoryRegion, 1); ++ ramName = g_strdup_printf("loongarch_ls3a.node%d.ram", i); ++ memory_region_init_alias(nodemem, NULL, ramName, ++ machine->ram, offset, numa_info[i].node_mem); ++ memory_region_add_subregion(address_space_mem, ++ phyAddr, nodemem); ++ la_memmap_add_entry(phyAddr, numa_info[i].node_mem, SYSTEM_RAM); ++ offset += numa_info[i].node_mem; ++ phyAddr += numa_info[i].node_mem; ++ } ++ ++ fdt_add_fw_cfg_node(lsms); ++ ls3a5k_bios_init(lsms, ram_size, highram_size, highram_end_addr, ++ kernel_filename, kernel_cmdline, initrd_filename); ++ ++ lsms->machine_done.notify = loongarch_machine_done; ++ qemu_add_machine_init_done_notifier(&lsms->machine_done); ++ /*vmstate_register_ram_global(bios);*/ ++ ++ /* initialize hotplug memory address space */ ++ lsms->hotplug_memory_size = 0; ++ ++ /* always allocate the device memory information */ ++ machine->device_memory = g_malloc0(sizeof(*machine->device_memory)); ++ if (machine->ram_size < machine->maxram_size) { ++ int max_memslots; ++ ++ lsms->hotplug_memory_size = machine->maxram_size - machine->ram_size; ++ /* ++ * Limit the number of hotpluggable memory slots to half the number ++ * slots that KVM supports, leaving the other half for PCI and other ++ * devices. However ensure that number of slots doesn't drop below 32. ++ */ ++ max_memslots = LOONGARCH_MAX_RAM_SLOTS; ++ if (kvm_enabled()) { ++ max_memslots = kvm_get_max_memslots() / 2 ; ++ } ++ ++ if (machine->ram_slots == 0) ++ machine->ram_slots = lsms->hotplug_memory_size / ++ LOONGARCH_HOTPLUG_MEM_ALIGN; ++ ++ if (machine->ram_slots > max_memslots) { ++ error_report("Specified number of memory slots %" ++ PRIu64" exceeds max supported %d", ++ machine->ram_slots, max_memslots); ++ exit(1); ++ } ++ ++ lsms->ram_slots = machine->ram_slots; ++ ++ machine->device_memory->base = get_hotplug_membase(machine->ram_size); ++ memory_region_init(&machine->device_memory->mr, OBJECT(lsms), ++ "device-memory", lsms->hotplug_memory_size); ++ memory_region_add_subregion(get_system_memory(), ++ machine->device_memory->base, ++ &machine->device_memory->mr); ++ } ++ ++ memory_region_init_alias(isa_io, NULL, "isa-io", ++ get_system_io(), 0, LS_ISA_IO_SIZE); ++ memory_region_init(isa_mem, NULL, "isa-mem", LS_ISA_MEM_SIZE); ++ memory_region_add_subregion(get_system_memory(), lsmc->isa_io_base, isa_io); ++ memory_region_add_subregion(get_system_memory(), LS_ISA_MEM_BASE, isa_mem); ++ ++ if (!strcmp(lsmc->bridge_name, "ls7a")) { ++ /*Initialize the 7A IO interrupt subsystem*/ ++ DeviceState *ls7a_dev; ++ lsms->apic_xrupt_override = kvm_irqchip_in_kernel(); ++ ls7a_apic = ls3a_intctl_init(machine, cpu_states); ++ if (!ls7a_apic) { ++ perror("Init 7A APIC failed\n"); ++ exit(1); ++ } ++ pci_bus = ls7a_init(machine, ls7a_apic, &ls7a_dev); ++ ++ object_property_add_link(OBJECT(machine), ++ LOONGARCH_MACHINE_ACPI_DEVICE_PROP, ++ TYPE_HOTPLUG_HANDLER, ++ (Object **)&lsms->acpi_dev, ++ object_property_allow_set_link, ++ OBJ_PROP_LINK_STRONG); ++ object_property_set_link(OBJECT(machine), LOONGARCH_MACHINE_ACPI_DEVICE_PROP, ++ OBJECT(ls7a_dev), &error_abort); ++ ++#ifdef CONFIG_KVM ++ if (kvm_enabled()) { ++ kvm_direct_msi_allowed = (kvm_check_extension(kvm_state, ++ KVM_CAP_SIGNAL_MSI) > 0); ++ } else { ++ kvm_direct_msi_allowed = 0; ++ } ++ msi_nonbroken = kvm_direct_msi_allowed; ++#else ++ msi_nonbroken = true; ++#endif ++ sysbus_create_simple("ls7a_rtc", LS7A_RTC_REG_BASE, ++ ls7a_apic[LS7A_RTC_IRQ - LOONGARCH_PCH_IRQ_BASE]); ++ } ++ ++ /*Initialize the CPU serial device*/ ++ ++ if (serial_hd(0)) { ++ pirq = qemu_allocate_irqs(legacy_set_irq, ls7a_apic + ++ (LS7A_UART_IRQ - LOONGARCH_PCH_IRQ_BASE), 1); ++ serial_mm_init(address_space_mem, LS7A_UART_BASE, 0, pirq[0], ++ 115200, serial_hd(0), DEVICE_NATIVE_ENDIAN); ++ } ++ ++ /*network card*/ ++ network_init(pci_bus); ++ /* VGA setup. Don't bother loading the bios. */ ++ pci_vga_init(pci_bus); ++ ++ sysbus_realize_and_unref(SYS_BUS_DEVICE(qdev_new("iocsr")), &error_fatal); ++ ++#ifdef CONFIG_TCG ++ int nb_nodes = (smp_cpus - 1) / 4; ++ for (i = 0; i <= nb_nodes; i++) { ++ uint64_t off = (uint64_t)i << 44; ++ SIMPLE_OPS(((hwaddr)0x1fe00180 | off), 0x8); ++ SIMPLE_OPS(((hwaddr)0x1fe0019c | off), 0x8); ++ SIMPLE_OPS(((hwaddr)0x1fe001d0 | off), 0x8); ++ SIMPLE_OPS(((hwaddr)FEATURE_REG | off), 0x8); ++ SIMPLE_OPS(((hwaddr)VENDOR_REG | off), 0x8); ++ SIMPLE_OPS(((hwaddr)CPUNAME_REG | off), 0x8); ++ SIMPLE_OPS(((hwaddr)OTHER_FUNC_REG | off), 0x8); ++ } ++ ++ SIMPLE_OPS(0x1001041c, 0x4); ++ SIMPLE_OPS(0x10002000, 0x14); ++ SIMPLE_OPS(0x10013ffc, 0x4); ++#endif ++ ++ fdt_add_pcie_node(lsms); ++ ++ /* load fdt */ ++ MemoryRegion *fdt_rom = g_new(MemoryRegion, 1); ++ memory_region_init_rom(fdt_rom, NULL, "fdt", LS_FDT_SIZE, &error_fatal); ++ memory_region_add_subregion(get_system_memory(), LS_FDT_BASE, fdt_rom); ++ rom_add_blob_fixed("fdt", lsms->fdt, lsms->fdt_size, LS_FDT_BASE); ++} ++ ++static const CPUArchIdList *loongarch_possible_cpu_arch_ids(MachineState *ms) ++{ ++ int i; ++ int max_cpus = ms->smp.max_cpus; ++ ++ if (ms->possible_cpus) { ++ /* ++ * make sure that max_cpus hasn't changed since the first use, i.e. ++ * -smp hasn't been parsed after it ++ */ ++ assert(ms->possible_cpus->len == max_cpus); ++ return ms->possible_cpus; ++ } ++ ++ ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) + ++ sizeof(CPUArchId) * max_cpus); ++ ms->possible_cpus->len = max_cpus; ++ for (i = 0; i < ms->possible_cpus->len; i++) { ++ ms->possible_cpus->cpus[i].type = ms->cpu_type; ++ ms->possible_cpus->cpus[i].vcpus_count = 1; ++ ms->possible_cpus->cpus[i].props.has_core_id = true; ++ ms->possible_cpus->cpus[i].props.core_id = i; ++ ms->possible_cpus->cpus[i].arch_id = i; ++ } ++ return ms->possible_cpus; ++ ++} ++ ++static PFlashCFI01 *loongarch_pflash_create(LoongarchMachineState *lsms, ++ const char *name, ++ const char *alias_prop_name) ++{ ++ DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01); ++ ++ qdev_prop_set_uint64(dev, "sector-length", FLASH_SECTOR_SIZE); ++ qdev_prop_set_uint8(dev, "width", 1); ++ qdev_prop_set_string(dev, "name", name); ++ object_property_add_child(OBJECT(lsms), name, OBJECT(dev)); ++ object_property_add_alias(OBJECT(lsms), alias_prop_name, ++ OBJECT(dev), "drive"); ++ return PFLASH_CFI01(dev); ++} ++ ++ ++static void loongarch_system_flash_create(LoongarchMachineState *lsms) ++{ ++ lsms->flash[0] = loongarch_pflash_create(lsms, "system.flash0", ++ "pflash0"); ++ lsms->flash[1] = loongarch_pflash_create(lsms, "system.flash1", ++ "pflash1"); ++} ++ ++static void loongarch_machine_initfn(Object *obj) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(obj); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ lsms->acpi_build_enabled = lsmc->has_acpi_build; ++ loongarch_system_flash_create(lsms); ++ lsms->oem_id = g_strndup(EFI_ACPI_OEM_ID, 6); ++ lsms->oem_table_id = g_strndup(EFI_ACPI_OEM_TABLE_ID, 6); ++} ++ ++static void ls3a5k_ls7a_machine_options(MachineClass *m) ++{ ++ char *cpu_name = get_host_cpu_model_name(); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_CLASS(m); ++ m->desc = "Loongarch3a5k LS7A1000 machine"; ++ m->max_cpus = LOONGARCH_MAX_VCPUS; ++ m->alias = "loongson7a"; ++ m->is_default = 1; ++ lsmc->isa_io_base = LS3A5K_ISA_IO_BASE; ++ lsmc->ht1lo_pcicfg_base = LS3A5K_HT1LO_PCICFG_BASE; ++ lsmc->pciecfg_base = LS_PCIECFG_BASE; ++ lsmc->ls7a_ioapic_reg_base = LS3A5K_LS7A_IOAPIC_REG_BASE; ++ lsmc->node_shift = 44; ++ strncpy(lsmc->cpu_name, cpu_name, sizeof(lsmc->cpu_name) - 1); ++ lsmc->cpu_name[sizeof(lsmc->cpu_name) - 1] = 0; ++ strncpy(lsmc->bridge_name, "ls7a", sizeof(lsmc->bridge_name) - 1); ++ lsmc->bridge_name[sizeof(lsmc->bridge_name) - 1] = 0; ++ compat_props_add(m->compat_props, loongarch_compat, loongarch_compat_len); ++} ++ ++static void ls3a_board_reset(MachineState *ms) ++{ ++ qemu_devices_reset(); ++#ifdef CONFIG_KVM ++ struct loongarch_kvm_irqchip *chip; ++ int length; ++ ++ if (!kvm_enabled()) { ++ return; ++ } ++ length = sizeof(struct loongarch_kvm_irqchip) + ++ sizeof(struct loongarch_gipiState); ++ chip = g_malloc0(length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS3A_GIPI; ++ chip->len = length; ++ kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); ++ ++ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct ls7a_ioapic_state); ++ chip = g_realloc(chip, length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS7A_IOAPIC; ++ chip->len = length; ++ kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); ++ ++ g_free(chip); ++#endif ++} ++ ++static CpuInstanceProperties ls3a_cpu_index_to_props(MachineState *ms, unsigned cpu_index) ++{ ++ MachineClass *mc = MACHINE_GET_CLASS(ms); ++ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); ++ ++ assert(cpu_index < possible_cpus->len); ++ return possible_cpus->cpus[cpu_index].props; ++} ++ ++static int64_t ls3a_get_default_cpu_node_id(const MachineState *ms, int idx) ++{ ++ int nb_numa_nodes = ms->numa_state->num_nodes; ++ int smp_cores = ms->smp.cores; ++ return idx / smp_cores % nb_numa_nodes; ++} ++ ++static void loongarch_class_init(ObjectClass *oc, void *data) ++{ ++ MachineClass *mc = MACHINE_CLASS(oc); ++ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_CLASS(oc); ++ ++ lsmc->get_hotplug_handler = mc->get_hotplug_handler; ++ lsmc->has_acpi_build = true; ++ mc->get_hotplug_handler = loongarch_get_hotpug_handler; ++ mc->has_hotpluggable_cpus = true; ++ mc->cpu_index_to_instance_props = ls3a_cpu_index_to_props; ++ mc->possible_cpu_arch_ids = loongarch_possible_cpu_arch_ids; ++ mc->get_default_cpu_node_id = ls3a_get_default_cpu_node_id; ++ mc->default_ram_size = 1 * GiB; ++ mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("Loongson-3A5000"); ++ mc->default_ram_id = "loongarch_ls3a.ram"; ++ ++ mc->reset = ls3a_board_reset; ++ mc->max_cpus = LOONGARCH_MAX_VCPUS; ++ hc->pre_plug = loongarch_machine_device_pre_plug; ++ hc->plug = loongarch_machine_device_plug; ++ hc->unplug = longson_machine_device_unplug; ++ hc->unplug_request = loongarch_machine_device_unplug_request; ++ ++ object_class_property_add(oc, "acpi", "OnOffAuto", ++ loongarch_get_acpi, loongarch_set_acpi, ++ NULL, NULL); ++ object_class_property_set_description(oc, "acpi", ++ "Enable ACPI"); ++} ++ ++static const TypeInfo loongarch_info = { ++ .name = TYPE_LOONGARCH_MACHINE, ++ .parent = TYPE_MACHINE, ++ .abstract = true, ++ .instance_size = sizeof(LoongarchMachineState), ++ .instance_init = loongarch_machine_initfn, ++ .class_size = sizeof(LoongarchMachineClass), ++ .class_init = loongarch_class_init, ++ .interfaces = (InterfaceInfo[]) { ++ { TYPE_HOTPLUG_HANDLER }, ++ { } ++ }, ++ ++}; ++ ++static void loongarch_machine_register_types(void) ++{ ++ type_register_static(&loongarch_info); ++} ++ ++type_init(loongarch_machine_register_types) ++ ++DEFINE_LS3A5K_MACHINE(loongson7a_v1_0, "loongson7a_v1.0", ++ ls3a5k_ls7a_machine_options); +diff --git a/hw/loongarch/larch_hotplug.c b/hw/loongarch/larch_hotplug.c +new file mode 100644 +index 0000000000..7bce957124 +--- /dev/null ++++ b/hw/loongarch/larch_hotplug.c +@@ -0,0 +1,355 @@ ++/* ++ * Hotplug emulation on Loongarch system. ++ * ++ * Copyright (c) 2018 Loongarch Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++ ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include "qemu-common.h" ++#include "qemu/queue.h" ++#include "qemu/units.h" ++#include "qemu/cutils.h" ++#include "qemu/bcd.h" ++#include "hw/hotplug.h" ++#include "hw/loongarch/cpudevs.h" ++#include "hw/mem/memory-device.h" ++#include "sysemu/numa.h" ++#include "sysemu/cpus.h" ++#include "hw/loongarch/larch.h" ++#include "hw/cpu/core.h" ++#include "hw/nvram/fw_cfg.h" ++ ++/* find cpu slot in machine->possible_cpus by core_id */ ++static CPUArchId *loongarch_find_cpu_slot(MachineState *ms, uint32_t id, ++ int *idx) ++{ ++ int index = id; ++ ++ if (index >= ms->possible_cpus->len) { ++ return NULL; ++ } ++ if (idx) { ++ *idx = index; ++ } ++ return &ms->possible_cpus->cpus[index]; ++} ++ ++static void loongarch_memory_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ Error *local_err = NULL; ++ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); ++ HotplugHandlerClass *hhc; ++ uint64_t size; ++ ++ size = memory_device_get_region_size(MEMORY_DEVICE(dev), &error_abort); ++ if (size % LOONGARCH_HOTPLUG_MEM_ALIGN) { ++ error_setg(&local_err, "Hotplugged memory size must be a multiple of " ++ "%lld MB", LOONGARCH_HOTPLUG_MEM_ALIGN / MiB); ++ goto out; ++ } ++ ++ pc_dimm_plug(PC_DIMM(dev), MACHINE(lsms)); ++ ++ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); ++ hhc->plug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &error_abort); ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void loongarch_memory_unplug_request(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ Error *local_err = NULL; ++ HotplugHandlerClass *hhc; ++ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); ++ ++ if (!lsms->acpi_dev || !loongarch_is_acpi_enabled(lsms)) { ++ error_setg(&local_err, ++ "memory hotplug is not enabled: missing acpi device or acpi disabled"); ++ goto out; ++ } ++ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); ++ hhc->unplug_request(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); ++ ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void loongarch_cpu_unplug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ CPUArchId *found_cpu; ++ HotplugHandlerClass *hhc; ++ Error *local_err = NULL; ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); ++ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ ++ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); ++ hhc->unplug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); ++ ++ if (local_err) { ++ goto out; ++ } ++ ++ loongarch_cpu_destroy(machine, cpu); ++ ++ found_cpu = loongarch_find_cpu_slot(MACHINE(lsms), cpu->id, NULL); ++ found_cpu->cpu = NULL; ++ object_unparent(OBJECT(dev)); ++ lsms->hotpluged_cpu_num -= 1; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void loongarch_memory_unplug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ Error *local_err = NULL; ++ HotplugHandlerClass *hhc; ++ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); ++ ++ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); ++ hhc->unplug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); ++ ++ if (local_err) { ++ goto out; ++ } ++ ++ pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev)); ++ object_unparent(OBJECT(dev)); ++ ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void loongarch_cpu_pre_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ MachineState *ms = MACHINE(OBJECT(hotplug_dev)); ++ MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev); ++ LoongarchMachineState *lsms = LoongarchMACHINE(ms); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); ++ CPUArchId *cpu_slot; ++ Error *local_err = NULL; ++ int index; ++ int free_index = lsms->hotpluged_cpu_num + ms->smp.cpus; ++ int max_cpus = ms->smp.max_cpus; ++ ++ if (dev->hotplugged && !mc->has_hotpluggable_cpus) { ++ error_setg(&local_err, "CPU hotplug not supported for this machine"); ++ goto out; ++ } ++ ++ if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { ++ error_setg(errp, "Invalid CPU type, expected cpu type: '%s'", ++ ms->cpu_type); ++ return; ++ } ++ ++ /* if ID is not set, set it based on core properties */ ++ if (cpu->id == UNASSIGNED_CPU_ID) { ++ if ((cpu->core_id) > (max_cpus - 1)) { ++ error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u", ++ cpu->core_id, max_cpus - 1); ++ return; ++ } ++ ++ if (free_index > (max_cpus - 1)) { ++ error_setg(errp, "The maximum number of CPUs cannot exceed %u.", ++ max_cpus); ++ return; ++ } ++ ++ if (cpu->core_id != free_index) { ++ error_setg(errp, "Invalid CPU core-id: %u must be :%u", ++ cpu->core_id, free_index); ++ return; ++ } ++ ++ cpu->id = cpu->core_id; ++ } ++ ++ cpu_slot = loongarch_find_cpu_slot(MACHINE(hotplug_dev), cpu->id, &index); ++ if (!cpu_slot) { ++ error_setg(&local_err, "core id %d out of range", cpu->id); ++ goto out; ++ } ++ ++ if (cpu_slot->cpu) { ++ error_setg(&local_err, "core %d already populated", cpu->id); ++ goto out; ++ } ++ ++ numa_cpu_pre_plug(cpu_slot, dev, &local_err); ++ ++ return ; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void loongarch_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp) ++{ ++ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ PCDIMMDevice *dimm = PC_DIMM(dev); ++ Error *local_err = NULL; ++ uint64_t size; ++ ++ if (!lsms->acpi_dev || !loongarch_is_acpi_enabled(lsms)) { ++ error_setg(errp, ++ "memory hotplug is not enabled: missing acpi device or acpi disabled"); ++ return; ++ } ++ ++ size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &local_err); ++ if (local_err) { ++ error_propagate(errp, local_err); ++ return; ++ } ++ ++ if (size % LOONGARCH_HOTPLUG_MEM_ALIGN) { ++ error_setg(errp, "Hotplugged memory size must be a multiple of " ++ "%lld MB", LOONGARCH_HOTPLUG_MEM_ALIGN / MiB); ++ return; ++ } ++ ++ pc_dimm_pre_plug(dimm, MACHINE(hotplug_dev), NULL, errp); ++} ++ ++static void loongarch_cpu_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ CPUArchId *found_cpu; ++ HotplugHandlerClass *hhc; ++ Error *local_err = NULL; ++ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); ++ ++ if (lsms->acpi_dev) { ++ loongarch_cpu_create(machine, cpu, errp); ++ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); ++ hhc->plug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ } ++ ++ found_cpu = loongarch_find_cpu_slot(MACHINE(lsms), cpu->id, NULL); ++ found_cpu->cpu = OBJECT(dev); ++ lsms->hotpluged_cpu_num += 1; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void loongarch_cpu_unplug_request(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); ++ Error *local_err = NULL; ++ HotplugHandlerClass *hhc; ++ int idx = -1; ++ ++ if (!lsms->acpi_dev) { ++ error_setg(&local_err, "CPU hot unplug not supported without ACPI"); ++ goto out; ++ } ++ ++ loongarch_find_cpu_slot(MACHINE(lsms), cpu->id, &idx); ++ assert(idx != -1); ++ if (idx == 0) { ++ error_setg(&local_err, "Boot CPU is unpluggable"); ++ goto out; ++ } ++ ++ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); ++ hhc->unplug_request(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); ++ ++ if (local_err) { ++ goto out; ++ } ++ ++ out: ++ error_propagate(errp, local_err); ++} ++ ++void longson_machine_device_unplug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); ++ ++ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ loongarch_memory_unplug(hotplug_dev, dev, errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { ++ if (!mc->has_hotpluggable_cpus) { ++ error_setg(errp, "CPU hot unplug not supported on this machine"); ++ return; ++ } ++ loongarch_cpu_unplug(hotplug_dev, dev, errp); ++ } else { ++ error_setg(errp, "acpi: device unplug for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++ ++ return; ++} ++ ++void loongarch_machine_device_unplug_request(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ loongarch_memory_unplug_request(hotplug_dev, dev, errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { ++ loongarch_cpu_unplug_request(hotplug_dev, dev, errp); ++ } ++} ++ ++HotplugHandler *loongarch_get_hotpug_handler(MachineState *machine, ++ DeviceState *dev) ++{ ++ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || ++ object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { ++ return HOTPLUG_HANDLER(machine); ++ } ++ return NULL; ++} ++ ++void loongarch_machine_device_pre_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ loongarch_memory_pre_plug(hotplug_dev, dev, errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { ++ loongarch_cpu_pre_plug(hotplug_dev, dev, errp); ++ } ++} ++ ++void loongarch_machine_device_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ loongarch_memory_plug(hotplug_dev, dev, errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { ++ loongarch_cpu_plug(hotplug_dev, dev, errp); ++ } ++} ++ +diff --git a/hw/loongarch/larch_int.c b/hw/loongarch/larch_int.c +new file mode 100644 +index 0000000000..ca073a19cf +--- /dev/null ++++ b/hw/loongarch/larch_int.c +@@ -0,0 +1,91 @@ ++/* ++ * QEMU LOONGARCH interrupt support ++ * ++ * 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/main-loop.h" ++#include "hw/hw.h" ++#include "hw/irq.h" ++#include "hw/loongarch/cpudevs.h" ++#include "cpu.h" ++#include "sysemu/kvm.h" ++#include "kvm_larch.h" ++#ifdef CONFIG_KVM ++#include ++#endif ++ ++static void cpu_irq_request(void *opaque, int irq, int level) ++{ ++ LOONGARCHCPU *cpu = opaque; ++ CPULOONGARCHState *env = &cpu->env; ++ CPUState *cs = CPU(cpu); ++ bool locked = false; ++ ++ if (irq < 0 || irq > 13) { ++ return; ++ } ++ ++ /* Make sure locking works even if BQL is already held by the caller */ ++ if (!qemu_mutex_iothread_locked()) { ++ locked = true; ++ qemu_mutex_lock_iothread(); ++ } ++ ++ if (level) { ++ env->CSR_ESTAT |= 1 << irq; ++ } else { ++ env->CSR_ESTAT &= ~(1 << irq); ++ } ++ ++ if (kvm_enabled()) { ++ if (irq == 2) { ++ kvm_loongarch_set_interrupt(cpu, irq, level); ++ } else if (irq == 3) { ++ kvm_loongarch_set_interrupt(cpu, irq, level); ++ } else if (irq == 12) { ++ kvm_loongarch_set_ipi_interrupt(cpu, irq, level); ++ } ++ } ++ ++ if (env->CSR_ESTAT & CSR_ESTAT_IPMASK) { ++ cpu_interrupt(cs, CPU_INTERRUPT_HARD); ++ } else { ++ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); ++ } ++ ++ if (locked) { ++ qemu_mutex_unlock_iothread(); ++ } ++} ++ ++void cpu_init_irq(LOONGARCHCPU *cpu) ++{ ++ CPULOONGARCHState *env = &cpu->env; ++ qemu_irq *qi; ++ int i; ++ ++ qi = qemu_allocate_irqs(cpu_irq_request, loongarch_env_get_cpu(env), N_IRQS); ++ for (i = 0; i < N_IRQS; i++) { ++ env->irq[i] = qi[i]; ++ } ++} ++ ++ +diff --git a/hw/loongarch/ls7a_nb.c b/hw/loongarch/ls7a_nb.c +new file mode 100644 +index 0000000000..5a500fbd5a +--- /dev/null ++++ b/hw/loongarch/ls7a_nb.c +@@ -0,0 +1,352 @@ ++/* ++ * Loongarch 7A1000 north bridge support ++ * ++ * Copyright (c) 2019 Loongarch Technology ++ * Authors: ++ * Zhu Chen ++ * ++ * 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 "hw/hw.h" ++#include "hw/irq.h" ++#include "hw/sysbus.h" ++#include "hw/pci/pci.h" ++#include "hw/i386/pc.h" ++#include "hw/pci/pci_host.h" ++#include "hw/pci/pcie_host.h" ++#include "sysemu/sysemu.h" ++#include "exec/address-spaces.h" ++#include "qapi/error.h" ++#include "hw/loongarch/cpudevs.h" ++#include "hw/acpi/ls7a.h" ++#include "hw/i386/pc.h" ++#include "hw/isa/isa.h" ++#include "hw/boards.h" ++#include "qemu/log.h" ++#include "hw/loongarch/bios.h" ++#include "hw/loader.h" ++#include "elf.h" ++#include "exec/address-spaces.h" ++#include "exec/memory.h" ++#include "hw/pci/pci_bridge.h" ++#include "hw/pci/pci_bus.h" ++#include "linux/kvm.h" ++#include "sysemu/kvm.h" ++#include "sysemu/runstate.h" ++#include "sysemu/reset.h" ++#include "migration/vmstate.h" ++#include "hw/loongarch/larch.h" ++#include "hw/loongarch/ls7a.h" ++ ++#undef DEBUG_LS7A ++ ++#ifdef DEBUG_LS7A ++#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) ++#else ++#define DPRINTF(fmt, ...) ++#endif ++ ++static void ls7a_reset(void *opaque) ++{ ++ uint64_t wmask; ++ wmask = ~(-1); ++ ++ PCIDevice *dev = opaque; ++ pci_set_word(dev->config + PCI_VENDOR_ID, 0x0014); ++ pci_set_word(dev->wmask + PCI_VENDOR_ID, wmask & 0xffff); ++ pci_set_word(dev->cmask + PCI_VENDOR_ID, 0xffff); ++ pci_set_word(dev->config + PCI_DEVICE_ID, 0x7a00); ++ pci_set_word(dev->wmask + PCI_DEVICE_ID, wmask & 0xffff); ++ pci_set_word(dev->cmask + PCI_DEVICE_ID, 0xffff); ++ pci_set_word(dev->config + 0x4, 0x0000); ++ pci_set_word(dev->config + PCI_STATUS, 0x0010); ++ pci_set_word(dev->wmask + PCI_STATUS, wmask & 0xffff); ++ pci_set_word(dev->cmask + PCI_STATUS, 0xffff); ++ pci_set_byte(dev->config + PCI_REVISION_ID, 0x0); ++ pci_set_byte(dev->wmask + PCI_REVISION_ID, wmask & 0xff); ++ pci_set_byte(dev->cmask + PCI_REVISION_ID, 0xff); ++ pci_set_byte(dev->config + 0x9, 0x00); ++ pci_set_byte(dev->wmask + 0x9, wmask & 0xff); ++ pci_set_byte(dev->cmask + 0x9, 0xff); ++ pci_set_byte(dev->config + 0xa, 0x00); ++ pci_set_byte(dev->wmask + 0xa, wmask & 0xff); ++ pci_set_byte(dev->cmask + 0xa, 0xff); ++ pci_set_byte(dev->config + 0xb, 0x06); ++ pci_set_byte(dev->wmask + 0xb, wmask & 0xff); ++ pci_set_byte(dev->cmask + 0xb, 0xff); ++ pci_set_byte(dev->config + 0xc, 0x00); ++ pci_set_byte(dev->wmask + 0xc, wmask & 0xff); ++ pci_set_byte(dev->cmask + 0xc, 0xff); ++ pci_set_byte(dev->config + 0xe, 0x80); ++ pci_set_byte(dev->wmask + 0xe, wmask & 0xff); ++ pci_set_byte(dev->cmask + 0xe, 0xff); ++} ++ ++static const VMStateDescription vmstate_ls7a_pcie = { ++ .name = "LS7A_PCIE", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_PCI_DEVICE(dev, LS7APCIState), ++ VMSTATE_STRUCT(pm, LS7APCIState, 0, vmstate_ls7a_pm, LS7APCIPMRegs), ++ VMSTATE_UINT32_ARRAY(regs, LS7APCIState, LS7A_REGS), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static PCIINTxRoute ls7a_route_intx_pin_to_irq(void *opaque, int pin) ++{ ++ PCIINTxRoute route; ++ ++ route.irq = pin; ++ route.mode = PCI_INTX_ENABLED; ++ return route; ++} ++ ++static int pci_ls7a_map_irq(PCIDevice *d, int irq_num) ++{ ++ int irq; ++ ++ irq = 16 + ((PCI_SLOT(d->devfn) * 4 + irq_num) & 0xf); ++ return irq; ++} ++ ++static void pci_ls7a_set_irq(void *opaque, int irq_num, int level) ++{ ++ qemu_irq *pic = opaque; ++ DPRINTF("------ %s irq %d %d\n", __func__, irq_num, level); ++ qemu_set_irq(pic[irq_num], level); ++} ++ ++/* ++static int ls7a_pciehost_initfn(SysBusDevice *dev) ++{ ++ return 0; ++}*/ ++ ++static void ls7a_pcie_realize(PCIDevice *dev, Error **errp) ++{ ++ LS7APCIState *s = PCIE_LS7A(dev); ++ /* Ls7a North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" */ ++ pci_config_set_prog_interface(dev->config, 0x00); ++ ++ /* set the default value of north bridge pci config */ ++ qemu_register_reset(ls7a_reset, s); ++} ++ ++static void pci_ls7a_config_write(void *opaque, hwaddr addr, ++ uint64_t val, unsigned size) ++{ ++ hwaddr tmp_addr; ++ tmp_addr = addr & 0xffffff; ++ ++ pci_data_write(opaque, tmp_addr, val, size); ++} ++ ++static uint64_t pci_ls7a_config_read(void *opaque, ++ hwaddr addr, unsigned size) ++{ ++ uint64_t val; ++ hwaddr tmp_addr; ++ ++ tmp_addr = addr & 0xffffff; ++ val = pci_data_read(opaque, tmp_addr, size); ++ ++ if (addr & 0x3c) { ++ DPRINTF(TARGET_FMT_plx" val %lx\n", addr, val); ++ } ++ return val; ++} ++ ++static const MemoryRegionOps pci_ls7a_config_ops = { ++ .read = pci_ls7a_config_read, ++ .write = pci_ls7a_config_write, ++ /* Set to access 64bits data, because default to 32bits*/ ++ .valid = { ++ .min_access_size = 1, ++ .max_access_size = 4, ++ }, ++ /* Set to access 64bits data, because default to 32bits*/ ++ .impl = { ++ .min_access_size = 1, ++ .max_access_size = 4, ++ }, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++ ++}; ++ ++static AddressSpace *ls7a_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) ++{ ++ return &address_space_memory; ++} ++ ++static PCIBus *pci_ls7a_init(MachineState *machine, DeviceState *dev, ++ qemu_irq *pic) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ PCIExpressHost *e; ++ SysBusDevice *sysbus; ++ MemoryRegion *iomem = g_new(MemoryRegion, 1); ++ PCIHostState *phb; ++ ++ e = PCIE_HOST_BRIDGE(dev); ++ sysbus = SYS_BUS_DEVICE(e); ++ phb = PCI_HOST_BRIDGE(e); ++ phb->bus = pci_register_root_bus(dev, "pcie.0", pci_ls7a_set_irq, ++ pci_ls7a_map_irq, pic, ++ get_system_memory(), get_system_io(), ++ (1 << 3), 128, TYPE_PCIE_BUS); ++ pcie_host_mmcfg_update(e, true, lsmc->pciecfg_base, LS_PCIECFG_SIZE); ++ DPRINTF("------ %d\n", __LINE__); ++ ++ pci_bus_set_route_irq_fn(phb->bus, ls7a_route_intx_pin_to_irq); ++ memory_region_init_io(iomem, NULL, &pci_ls7a_config_ops, phb->bus, ++ "ls7a_pci_conf", HT1LO_PCICFG_SIZE); ++ sysbus_init_mmio(sysbus, iomem); ++ sysbus_mmio_map(sysbus, 0, lsmc->ht1lo_pcicfg_base); ++ ++ return phb->bus; ++} ++ ++PCIBus *ls7a_init(MachineState *machine, qemu_irq *pic, DeviceState **ls7a_dev) ++{ ++ DeviceState *dev; ++ PCIHostState *phb; ++ LS7APCIState *pbs; ++ PCIDevice *pcid; ++ PCIBus *pci_bus; ++ PCIExpressHost *e; ++ ++ /*1. init the HT PCI CFG*/ ++ DPRINTF("------ %d\n", __LINE__); ++ dev = qdev_new(TYPE_LS7A_PCIE_HOST_BRIDGE); ++ e = PCIE_HOST_BRIDGE(dev); ++ phb = PCI_HOST_BRIDGE(e); ++ ++ DPRINTF("------ %d\n", __LINE__); ++ pci_bus = pci_ls7a_init(machine, dev, pic); ++ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); ++ phb->bus = pci_bus; ++ /* set the pcihost pointer after rs780_pcihost_initfn is called */ ++ DPRINTF("------ %d\n", __LINE__); ++ pcid = pci_new(PCI_DEVFN(0, 0), TYPE_PCIE_LS7A); ++ pbs = PCIE_LS7A(pcid); ++ pbs->pciehost = LS7A_PCIE_HOST_BRIDGE(dev); ++ pbs->pciehost->pci_dev = pbs; ++ ++ if (ls7a_dev) { ++ *ls7a_dev = DEVICE(pcid); ++ } ++ ++ pci_realize_and_unref(pcid, phb->bus, &error_fatal); ++ ++ /* IOMMU */ ++ pci_setup_iommu(phb->bus, ls7a_pci_dma_iommu, NULL); ++ ++ ls7a_pm_init(&pbs->pm, pic); ++ DPRINTF("------ %d\n", __LINE__); ++ /*3. init the north bridge VGA,not do now*/ ++ return pci_bus; ++} ++ ++LS7APCIState *get_ls7a_type(Object *obj) ++{ ++ LS7APCIState *pbs; ++ ++ pbs = PCIE_LS7A(obj); ++ return pbs; ++} ++ ++static void ls7a_pcie_class_init(ObjectClass *klass, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(klass); ++ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); ++ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); ++ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(klass); ++ ++ k->realize = ls7a_pcie_realize; ++ k->vendor_id = 0x0014; ++ k->device_id = 0x7a00; ++ k->revision = 0x00; ++ k->class_id = PCI_CLASS_BRIDGE_HOST; ++ dc->desc = "LS7A1000 PCIE Host bridge"; ++ dc->vmsd = &vmstate_ls7a_pcie; ++ /* ++ * PCI-facing part of the host bridge, not usable without the ++ * host-facing part, which can't be device_add'ed, yet. ++ */ ++ dc->user_creatable = false; ++ hc->plug = ls7a_pm_device_plug_cb; ++ hc->unplug_request = ls7a_pm_device_unplug_request_cb; ++ hc->unplug = ls7a_pm_device_unplug_cb; ++ adevc->ospm_status = ls7a_pm_ospm_status; ++ adevc->send_event = ls7a_send_gpe; ++ adevc->madt_cpu = ls7a_madt_cpu_entry; ++} ++ ++static void ls7a_pci_add_properties(LS7APCIState *ls7a) ++{ ++ ls7a_pm_add_properties(OBJECT(ls7a), &ls7a->pm, NULL); ++} ++ ++static void ls7a_pci_initfn(Object *obj) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(obj); ++ ++ ls7a_pci_add_properties(ls7a); ++} ++ ++static const TypeInfo ls7a_pcie_device_info = { ++ .name = TYPE_PCIE_LS7A, ++ .parent = TYPE_PCI_DEVICE, ++ .instance_size = sizeof(LS7APCIState), ++ .class_init = ls7a_pcie_class_init, ++ .instance_init = ls7a_pci_initfn, ++ .interfaces = (InterfaceInfo[]) { ++ { TYPE_HOTPLUG_HANDLER }, ++ { TYPE_ACPI_DEVICE_IF }, ++ { INTERFACE_CONVENTIONAL_PCI_DEVICE }, ++ { }, ++ }, ++}; ++ ++static void ls7a_pciehost_class_init(ObjectClass *klass, void *data) ++{ ++ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); ++ k->parent_class.fw_name = "pci"; ++} ++ ++static const TypeInfo ls7a_pciehost_info = { ++ .name = TYPE_LS7A_PCIE_HOST_BRIDGE, ++ .parent = TYPE_PCIE_HOST_BRIDGE, ++ .instance_size = sizeof(LS7APCIEHost), ++ .class_init = ls7a_pciehost_class_init, ++}; ++ ++static void ls7a_register_types(void) ++{ ++ type_register_static(&ls7a_pciehost_info); ++ type_register_static(&ls7a_pcie_device_info); ++} ++ ++type_init(ls7a_register_types) +diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build +new file mode 100644 +index 0000000000..81ee99a028 +--- /dev/null ++++ b/hw/loongarch/meson.build +@@ -0,0 +1,15 @@ ++loongarch_ss = ss.source_set() ++loongarch_ss.add(files('larch_3a.c'), fdt) ++loongarch_ss.add(files( ++ 'larch_int.c', ++ 'larch_hotplug.c', ++ 'ls7a_nb.c', ++ 'ioapic.c', ++ 'acpi-build.c', ++ 'ipi.c', ++ 'apic.c', ++ 'iocsr.c', ++)) ++ ++hw_arch += {'loongarch64': loongarch_ss} ++ +diff --git a/include/hw/loongarch/bios.h b/include/hw/loongarch/bios.h +new file mode 100644 +index 0000000000..3677303bfa +--- /dev/null ++++ b/include/hw/loongarch/bios.h +@@ -0,0 +1,5 @@ ++#include "qemu/units.h" ++#include "cpu.h" ++ ++#define BIOS_SIZE (4 * MiB) ++#define BIOS_FILENAME "loongarch_bios.bin" +diff --git a/include/hw/loongarch/cpudevs.h b/include/hw/loongarch/cpudevs.h +new file mode 100644 +index 0000000000..c05ae7a7fc +--- /dev/null ++++ b/include/hw/loongarch/cpudevs.h +@@ -0,0 +1,53 @@ ++#ifndef HW_LOONGARCH_CPUDEVS_H ++#define HW_LOONGARCH_CPUDEVS_H ++ ++#include "target/loongarch64/cpu-qom.h" ++ ++/* Definitions for LOONGARCH CPU internal devices. */ ++#define MAX_GIPI_CORE_NUM 256 ++#define MAX_GIPI_MBX_NUM 4 ++ ++#define LS3A_INTC_IP 8 ++#define MAX_CORES 256 ++#define EXTIOI_IRQS (256) ++#define EXTIOI_IRQS_BITMAP_SIZE (256 / 8) ++/* map to ipnum per 32 irqs */ ++#define EXTIOI_IRQS_IPMAP_SIZE (256 / 32) ++ ++typedef struct gipi_core { ++ uint32_t status; ++ uint32_t en; ++ uint32_t set; ++ uint32_t clear; ++ uint64_t buf[MAX_GIPI_MBX_NUM]; ++ qemu_irq irq; ++} gipi_core; ++ ++typedef struct gipiState { ++ gipi_core core[MAX_GIPI_CORE_NUM]; ++} gipiState; ++ ++typedef struct apicState { ++ /* hardware state */ ++ uint8_t ext_en[EXTIOI_IRQS_BITMAP_SIZE]; ++ uint8_t ext_bounce[EXTIOI_IRQS_BITMAP_SIZE]; ++ uint8_t ext_isr[EXTIOI_IRQS_BITMAP_SIZE]; ++ uint8_t ext_coreisr[MAX_CORES][EXTIOI_IRQS_BITMAP_SIZE]; ++ uint8_t ext_ipmap[EXTIOI_IRQS_IPMAP_SIZE]; ++ uint8_t ext_coremap[EXTIOI_IRQS]; ++ uint16_t ext_nodetype[16]; ++ uint64_t ext_control; ++ ++ /* software state */ ++ uint8_t ext_sw_ipmap[EXTIOI_IRQS]; ++ uint8_t ext_sw_coremap[EXTIOI_IRQS]; ++ uint8_t ext_ipisr[MAX_CORES * LS3A_INTC_IP][EXTIOI_IRQS_BITMAP_SIZE]; ++ ++ qemu_irq parent_irq[MAX_CORES][LS3A_INTC_IP]; ++ qemu_irq *irq; ++} apicState; ++ ++void cpu_init_irq(LOONGARCHCPU *cpu); ++void cpu_loongarch_clock_init(LOONGARCHCPU *cpu); ++ ++#endif +diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h +new file mode 100644 +index 0000000000..0886ed52af +--- /dev/null ++++ b/include/hw/loongarch/larch.h +@@ -0,0 +1,163 @@ ++/* ++ * Hotplug emulation on Loongarch system. ++ * ++ * Copyright (c) 2018 Loongarch Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++ ++#ifndef HW_LOONGARCH_H ++#define HW_LOONGARCH_H ++ ++#include "target/loongarch64/cpu.h" ++#include "qemu-common.h" ++#include "exec/memory.h" ++#include "hw/mem/pc-dimm.h" ++#include "hw/hotplug.h" ++#include "hw/boards.h" ++#include "hw/acpi/acpi.h" ++#include "qemu/notify.h" ++#include "qemu/error-report.h" ++#include "qemu/queue.h" ++#include "hw/acpi/memory_hotplug.h" ++#include "hw/loongarch/cpudevs.h" ++#include "hw/block/flash.h" ++ ++#define LOONGARCH_MAX_VCPUS 256 ++#define LOONGARCH_MAX_PFLASH 2 ++/* 256MB alignment for hotplug memory region */ ++#define LOONGARCH_HOTPLUG_MEM_ALIGN (1ULL << 28) ++#define LOONGARCH_MAX_RAM_SLOTS 10 ++ ++/* Memory types: */ ++#define SYSTEM_RAM 1 ++#define SYSTEM_RAM_RESERVED 2 ++#define ACPI_TABLE 3 ++#define ACPI_NVS 4 ++#define SYSTEM_PMEM 5 ++ ++#define MAX_MEM_MAP 128 ++ ++typedef struct LoongarchMachineClass { ++ /*< private >*/ ++ MachineClass parent_class; ++ ++ /* Methods: */ ++ HotplugHandler *(*get_hotplug_handler)(MachineState *machine, ++ DeviceState *dev); ++ ++ bool has_acpi_build; ++ ++ /* save different cpu address*/ ++ uint64_t isa_io_base; ++ uint64_t ht_control_regs_base; ++ uint64_t hpet_mmio_addr; ++ uint64_t smbus_cfg_base; ++ uint64_t ht1lo_pcicfg_base; ++ uint64_t pciecfg_base; ++ uint64_t ls7a_ioapic_reg_base; ++ uint32_t node_shift; ++ char cpu_name[40]; ++ char bridge_name[16]; ++ ++} LoongarchMachineClass; ++ ++typedef struct ResetData { ++ LOONGARCHCPU *cpu; ++ uint64_t vector; ++} ResetData; ++ ++typedef struct LoongarchMachineState { ++ /*< private >*/ ++ MachineState parent_obj; ++ ++ /* */ ++ ram_addr_t hotplug_memory_size; ++ ++ /* State for other subsystems/APIs: */ ++ Notifier machine_done; ++ /* Pointers to devices and objects: */ ++ HotplugHandler *acpi_dev; ++ int ram_slots; ++ ResetData *reset_info[LOONGARCH_MAX_VCPUS]; ++ DeviceState *rtc; ++ gipiState *gipi; ++ apicState *apic; ++ ++ FWCfgState *fw_cfg; ++ bool acpi_build_enabled; ++ bool apic_xrupt_override; ++ CPUArchIdList *possible_cpus; ++ PFlashCFI01 *flash[LOONGARCH_MAX_PFLASH]; ++ void *fdt; ++ int fdt_size; ++ unsigned int hotpluged_cpu_num; ++ OnOffAuto acpi; ++ char *oem_id; ++ char *oem_table_id; ++} LoongarchMachineState; ++ ++#define LOONGARCH_MACHINE_ACPI_DEVICE_PROP "loongarch-acpi-device" ++#define TYPE_LOONGARCH_MACHINE "loongarch-machine" ++ ++#define LoongarchMACHINE(obj) \ ++ OBJECT_CHECK(LoongarchMachineState, (obj), TYPE_LOONGARCH_MACHINE) ++#define LoongarchMACHINE_GET_CLASS(obj) \ ++ OBJECT_GET_CLASS(LoongarchMachineClass, (obj), TYPE_LOONGARCH_MACHINE) ++#define LoongarchMACHINE_CLASS(klass) \ ++ OBJECT_CLASS_CHECK(LoongarchMachineClass, (klass), TYPE_LOONGARCH_MACHINE) ++ ++#define DEFINE_LOONGARCH_MACHINE(suffix, namestr, initfn, optsfn) \ ++ static void loongarch_machine_##suffix##_class_init(ObjectClass *oc, void *data) \ ++ { \ ++ MachineClass *mc = MACHINE_CLASS(oc); \ ++ optsfn(mc); \ ++ mc->init = initfn; \ ++ } \ ++ static const TypeInfo loongarch_machine_type_##suffix = { \ ++ .name = namestr TYPE_MACHINE_SUFFIX, \ ++ .parent = TYPE_LOONGARCH_MACHINE, \ ++ .class_init = loongarch_machine_##suffix##_class_init, \ ++ }; \ ++ static void loongarch_machine_init_##suffix(void) \ ++ { \ ++ type_register(&loongarch_machine_type_##suffix); \ ++ } \ ++ type_init(loongarch_machine_init_##suffix) ++ ++void loongarch_machine_device_unplug_request(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp); ++void longson_machine_device_unplug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp); ++HotplugHandler *loongarch_get_hotpug_handler(MachineState *machine, ++ DeviceState *dev); ++void loongarch_machine_device_pre_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp); ++void loongarch_machine_device_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp); ++ ++LOONGARCHCPU *loongarch_cpu_create(MachineState *machine, LOONGARCHCPU *cpu, ++ Error **errp); ++void loongarch_cpu_destroy(MachineState *machine, LOONGARCHCPU *cpu); ++int cpu_init_ipi(LoongarchMachineState *ms, qemu_irq parent, int cpu); ++int cpu_init_apic(LoongarchMachineState *ms, CPULOONGARCHState *env, int cpu); ++int la_memmap_add_entry(uint64_t address, uint64_t length, uint32_t type); ++bool loongarch_is_acpi_enabled(LoongarchMachineState *vms); ++ ++/* acpi-build.c */ ++void ls7a_madt_cpu_entry(AcpiDeviceIf *adev, int uid, ++ const CPUArchIdList *apic_ids, GArray *entry, bool force_enabled); ++void slave_cpu_reset(void *opaque); ++extern uint64_t host_cpufreq; ++#endif +diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h +new file mode 100644 +index 0000000000..686af763a0 +--- /dev/null ++++ b/include/hw/loongarch/ls7a.h +@@ -0,0 +1,152 @@ ++#ifndef HW_LS7A_H ++#define HW_LS7A_H ++ ++#include "hw/hw.h" ++#include "hw/isa/isa.h" ++#include "hw/sysbus.h" ++#include "hw/isa/apm.h" ++#include "hw/pci/pci.h" ++#include "hw/pci/pcie_host.h" ++#include "hw/pci/pci_bridge.h" ++#include "hw/acpi/acpi.h" ++#include "hw/acpi/ls7a.h" ++#include "hw/pci/pci_bus.h" ++ ++/* LS7A PCH Registers (Misc, Confreg) */ ++#define LS7A_PCH_REG_BASE 0x10000000UL ++#define LS3A5K_LS7A_IOAPIC_REG_BASE (LS7A_PCH_REG_BASE) ++#define LS7A_MISC_REG_BASE (LS7A_PCH_REG_BASE + 0x00080000) ++#define LS7A_ACPI_REG_BASE (LS7A_MISC_REG_BASE + 0x00050000) ++ ++#define LOONGARCH_PCH_IRQ_BASE 64 ++#define LS7A_UART_IRQ (LOONGARCH_PCH_IRQ_BASE + 2) ++#define LS7A_RTC_IRQ (LOONGARCH_PCH_IRQ_BASE + 3) ++#define LS7A_SCI_IRQ (LOONGARCH_PCH_IRQ_BASE + 4) ++#define LS7A_ACPI_IO_BASE 0x800 ++#define LS7A_ACPI_IO_SIZE 0x100 ++#define LS7A_PM_EVT_BLK (0x0C) /* 4 bytes */ ++#define LS7A_PM_CNT_BLK (0x14) /* 2 bytes */ ++#define LS7A_GPE0_STS_REG (0x28) /* 4 bytes */ ++#define LS7A_GPE0_ENA_REG (0x2C) /* 4 bytes */ ++#define LS7A_GPE0_RESET_REG (0x30) /* 4 bytes */ ++#define LS7A_PM_TMR_BLK (0x18) /* 4 bytes */ ++#define LS7A_GPE0_LEN (8) ++#define LS7A_RTC_REG_BASE (LS7A_MISC_REG_BASE + 0x00050100) ++#define LS7A_RTC_LEN (0x100) ++ ++#define ACPI_IO_BASE (LS7A_ACPI_REG_BASE) ++#define ACPI_GPE0_LEN (LS7A_GPE0_LEN) ++#define ACPI_IO_SIZE (LS7A_ACPI_IO_SIZE) ++#define ACPI_SCI_IRQ (LS7A_SCI_IRQ) ++ ++#define LS3A5K_ISA_IO_BASE 0x18000000UL ++#define LS_ISA_MEM_BASE 0x40000000 ++#define LS3A5K_HT1LO_PCICFG_BASE 0x1a000000 ++#define HT1LO_PCICFG_SIZE 0x02000000 ++#define LS_BIOS_BASE 0x1c000000 ++#define LS_BIOS_VAR_BASE 0x1c3a0000 ++#define LS_BIOS_SIZE (4 * 1024 * 1024) ++ ++#define FW_CFG_ADDR 0x1e020000 ++#define LS7A_REG_BASE 0x1FE00000 ++#define LS7A_PCICONFIG_BASE (LS7A_REG_BASE + 0x30) ++#define LS7A_PCICONFIG_SIZE (0x100) ++#define LS7A_INTERNAL_REG_BASE (LS7A_REG_BASE + 0x100) ++#define LS7A_INTERNAL_REG_SIZE (0xE0) ++#define LS7A_REGS (0xE0 >> 2) ++#define LS7A_UART_BASE 0x1fe001e0 ++#define LS7A_UART_LEN 0x8 ++ ++#define LS_FDT_BASE 0x1c400000 ++#define LS_FDT_SIZE 0x100000 ++ ++#define LS_PCIECFG_BASE 0x20000000 ++#define LS_PCIECFG_SIZE 0x08000000 ++#define MSI_ADDR_LOW 0x2FF00000 ++#define MSI_ADDR_HI 0x0 ++ ++#define SMP_GIPI_MAILBOX 0x1f000000ULL ++#define CORE0_STATUS_OFF 0x000 ++#define CORE0_EN_OFF 0x004 ++#define CORE0_SET_OFF 0x008 ++#define CORE0_CLEAR_OFF 0x00c ++#define CORE0_BUF_20 0x020 ++#define CORE0_BUF_28 0x028 ++#define CORE0_BUF_30 0x030 ++#define CORE0_BUF_38 0x038 ++#define CORE0_IPI_SEND 0x040 ++#define CORE0_MAIL_SEND 0x048 ++ ++#define INT_ROUTER_REGS_BASE 0x1fe01400UL ++#define INT_ROUTER_REGS_SIZE 0x100 ++#define INT_ROUTER_REGS_SYS_INT0 0x00 ++#define INT_ROUTER_REGS_SYS_INT1 0x01 ++#define INT_ROUTER_REGS_SYS_INT2 0x02 ++#define INT_ROUTER_REGS_SYS_INT3 0x03 ++#define INT_ROUTER_REGS_PCI_INT0 0x04 ++#define INT_ROUTER_REGS_PCI_INT1 0x05 ++#define INT_ROUTER_REGS_PCI_INT2 0x06 ++#define INT_ROUTER_REGS_PCI_INT3 0x07 ++#define INT_ROUTER_REGS_MATRIX_INT0 0x08 ++#define INT_ROUTER_REGS_MATRIX_INT1 0x09 ++#define INT_ROUTER_REGS_LPC_INT 0x0a ++#define INT_ROUTER_REGS_MC0 0x0b ++#define INT_ROUTER_REGS_MC1 0x0c ++#define INT_ROUTER_REGS_BARRIER 0x0d ++#define INT_ROUTER_REGS_THSENS_INT 0x0e ++#define INT_ROUTER_REGS_PCI_PERR 0x0f ++#define INT_ROUTER_REGS_HT0_INT0 0x10 ++#define INT_ROUTER_REGS_HT0_INT1 0x11 ++#define INT_ROUTER_REGS_HT0_INT2 0x12 ++#define INT_ROUTER_REGS_HT0_INT3 0x13 ++#define INT_ROUTER_REGS_HT0_INT4 0x14 ++#define INT_ROUTER_REGS_HT0_INT5 0x15 ++#define INT_ROUTER_REGS_HT0_INT6 0x16 ++#define INT_ROUTER_REGS_HT0_INT7 0x17 ++#define INT_ROUTER_REGS_HT1_INT0 0x18 ++#define INT_ROUTER_REGS_HT1_INT1 0x19 ++#define INT_ROUTER_REGS_HT1_INT2 0x1a ++#define INT_ROUTER_REGS_HT1_INT3 0x1b ++#define INT_ROUTER_REGS_HT1_INT4 0x1c ++#define INT_ROUTER_REGS_HT1_INT5 0x1d ++#define INT_ROUTER_REGS_HT1_INT6 0x1e ++#define INT_ROUTER_REGS_HT1_INT7 0x1f ++#define INT_ROUTER_REGS_ISR 0x20 ++#define INT_ROUTER_REGS_EN 0x24 ++#define INT_ROUTER_REGS_EN_SET 0x28 ++#define INT_ROUTER_REGS_EN_CLR 0x2c ++#define INT_ROUTER_REGS_EDGE 0x38 ++#define INT_ROUTER_REGS_CORE0_INTISR 0x40 ++#define INT_ROUTER_REGS_CORE1_INTISR 0x48 ++#define INT_ROUTER_REGS_CORE2_INTISR 0x50 ++#define INT_ROUTER_REGS_CORE3_INTISR 0x58 ++ ++typedef struct LS7APCIState LS7APCIState; ++typedef struct LS7APCIEHost { ++ PCIExpressHost parent_obj; ++ LS7APCIState *pci_dev; ++} LS7APCIEHost; ++ ++struct LS7APCIState { ++ PCIDevice dev; ++ ++ LS7APCIEHost *pciehost; ++ uint32_t regs[LS7A_REGS]; ++ ++ /* LS7A registers */ ++ MemoryRegion iomem; ++ LS7APCIPMRegs pm; ++}; ++ ++#define TYPE_LS7A_PCIE_HOST_BRIDGE "ls7a1000-pciehost" ++#define LS7A_PCIE_HOST_BRIDGE(obj) \ ++ OBJECT_CHECK(LS7APCIEHost, (obj), TYPE_LS7A_PCIE_HOST_BRIDGE) ++ ++#define TYPE_PCIE_LS7A "ls7a1000_pcie" ++#define PCIE_LS7A(obj) \ ++ OBJECT_CHECK(LS7APCIState, (obj), TYPE_PCIE_LS7A) ++ ++PCIBus *ls7a_init(MachineState *machine, qemu_irq *irq, DeviceState **ls7a_dev); ++LS7APCIState *get_ls7a_type(Object *obj); ++ ++#endif /* HW_LS7A_H */ +-- +2.27.0 + diff --git a/0004-Add-target-loongarch64.patch b/0004-Add-target-loongarch64.patch new file mode 100644 index 0000000..38e74c2 --- /dev/null +++ b/0004-Add-target-loongarch64.patch @@ -0,0 +1,15918 @@ +From 441bbe9ec5021bf56a929134a71cd85815ec3956 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Fri, 19 Aug 2022 23:44:33 -0400 +Subject: [PATCH 4/8] Add target/loongarch64. + +Change-Id: Idd3ed114968c4a1f1be5fe19dc279028775eb89d +Signed-off-by: lixianglai +--- + target/Kconfig | 1 + + target/loongarch64/Kconfig | 2 + + target/loongarch64/arch_dump.c | 175 ++ + target/loongarch64/cpu-csr.h | 869 ++++++++ + target/loongarch64/cpu-param.h | 30 + + target/loongarch64/cpu-qom.h | 54 + + target/loongarch64/cpu.c | 576 +++++ + target/loongarch64/cpu.h | 326 +++ + target/loongarch64/csr_helper.c | 704 ++++++ + target/loongarch64/fpu.c | 28 + + target/loongarch64/fpu_helper.c | 952 ++++++++ + target/loongarch64/fpu_helper.h | 129 ++ + target/loongarch64/gdbstub.c | 109 + + target/loongarch64/helper.c | 727 +++++++ + target/loongarch64/helper.h | 168 ++ + target/loongarch64/insn.decode | 514 +++++ + target/loongarch64/instmap.h | 216 ++ + target/loongarch64/internal.h | 184 ++ + target/loongarch64/kvm.c | 1622 ++++++++++++++ + target/loongarch64/kvm_larch.h | 41 + + target/loongarch64/larch-defs.h | 27 + + target/loongarch64/machine.c | 416 ++++ + target/loongarch64/meson.build | 35 + + target/loongarch64/op_helper.c | 533 +++++ + target/loongarch64/stabletimer.c | 122 ++ + target/loongarch64/tlb_helper.c | 729 +++++++ + target/loongarch64/trace-events | 3 + + target/loongarch64/trans.inc.c | 3472 ++++++++++++++++++++++++++++++ + target/loongarch64/translate.c | 2892 +++++++++++++++++++++++++ + target/meson.build | 1 + + 30 files changed, 15657 insertions(+) + create mode 100644 target/loongarch64/Kconfig + create mode 100644 target/loongarch64/arch_dump.c + create mode 100644 target/loongarch64/cpu-csr.h + create mode 100644 target/loongarch64/cpu-param.h + create mode 100644 target/loongarch64/cpu-qom.h + create mode 100644 target/loongarch64/cpu.c + create mode 100644 target/loongarch64/cpu.h + create mode 100644 target/loongarch64/csr_helper.c + create mode 100644 target/loongarch64/fpu.c + create mode 100644 target/loongarch64/fpu_helper.c + create mode 100644 target/loongarch64/fpu_helper.h + create mode 100644 target/loongarch64/gdbstub.c + create mode 100644 target/loongarch64/helper.c + create mode 100644 target/loongarch64/helper.h + create mode 100644 target/loongarch64/insn.decode + create mode 100644 target/loongarch64/instmap.h + create mode 100644 target/loongarch64/internal.h + create mode 100644 target/loongarch64/kvm.c + create mode 100644 target/loongarch64/kvm_larch.h + create mode 100644 target/loongarch64/larch-defs.h + create mode 100644 target/loongarch64/machine.c + create mode 100644 target/loongarch64/meson.build + create mode 100644 target/loongarch64/op_helper.c + create mode 100644 target/loongarch64/stabletimer.c + create mode 100644 target/loongarch64/tlb_helper.c + create mode 100644 target/loongarch64/trace-events + create mode 100644 target/loongarch64/trans.inc.c + create mode 100644 target/loongarch64/translate.c + +diff --git a/target/Kconfig b/target/Kconfig +index ae7f24fc66..50b46d0487 100644 +--- a/target/Kconfig ++++ b/target/Kconfig +@@ -4,6 +4,7 @@ source avr/Kconfig + source cris/Kconfig + source hppa/Kconfig + source i386/Kconfig ++source loongarch64/Kconfig + source m68k/Kconfig + source microblaze/Kconfig + source mips/Kconfig +diff --git a/target/loongarch64/Kconfig b/target/loongarch64/Kconfig +new file mode 100644 +index 0000000000..46b26b1a85 +--- /dev/null ++++ b/target/loongarch64/Kconfig +@@ -0,0 +1,2 @@ ++config LOONGARCH64 ++ bool +diff --git a/target/loongarch64/arch_dump.c b/target/loongarch64/arch_dump.c +new file mode 100644 +index 0000000000..9fb43b33d2 +--- /dev/null ++++ b/target/loongarch64/arch_dump.c +@@ -0,0 +1,175 @@ ++/* Support for writing ELF notes for RM architectures ++ * ++ * Copyright (C) 2015 Red Hat Inc. ++ * ++ * Author: Andrew Jones ++ * ++ * 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 . ++ */ ++ ++#include "qemu/osdep.h" ++#include "cpu.h" ++#include "elf.h" ++#include "sysemu/dump.h" ++#include "internal.h" ++ ++/* struct user_pt_regs from arch/loongarch/include/uapi/asm/ptrace.h */ ++struct loongarch_user_regs { ++ uint64_t gpr[32]; ++ uint64_t lo; ++ uint64_t hi; ++ uint64_t csr_era; ++ uint64_t csr_badvaddr; ++ uint64_t csr_crmd; ++ uint64_t csr_ecfg; ++ uint64_t pad[7]; ++} QEMU_PACKED; ++ ++QEMU_BUILD_BUG_ON(sizeof(struct loongarch_user_regs) != 360); ++ ++/* struct elf_prstatus from include/uapi/linux/elfcore.h */ ++struct loongarch_elf_prstatus { ++ char pad1[32]; /* 32 == offsetof(struct elf_prstatus, pr_pid) */ ++ uint32_t pr_pid; ++ char pad2[76]; /* 76 == offsetof(struct elf_prstatus, pr_reg) - ++ offsetof(struct elf_prstatus, pr_ppid) */ ++ struct loongarch_user_regs pr_reg; ++ uint32_t pr_fpvalid; ++ char pad3[4]; ++} QEMU_PACKED; ++ ++QEMU_BUILD_BUG_ON(sizeof(struct loongarch_elf_prstatus) != 480); ++ ++/* struct user_fpsimd_state from arch/arm64/include/uapi/asm/ptrace.h ++ * ++ * While the vregs member of user_fpsimd_state is of type __uint128_t, ++ * QEMU uses an array of uint64_t, where the high half of the 128-bit ++ * value is always in the 2n+1'th index. Thus we also break the 128- ++ * bit values into two halves in this reproduction of user_fpsimd_state. ++ */ ++ ++struct loongarch_fpu_struct { ++ uint64_t fpr[32]; ++ unsigned int fir; ++ unsigned int fcsr; ++} QEMU_PACKED; ++ ++QEMU_BUILD_BUG_ON(sizeof(struct loongarch_fpu_struct) != 264); ++ ++struct loongarch_note { ++ Elf64_Nhdr hdr; ++ char name[8]; /* align_up(sizeof("CORE"), 4) */ ++ union { ++ struct loongarch_elf_prstatus prstatus; ++ struct loongarch_fpu_struct fpu; ++ }; ++} QEMU_PACKED; ++ ++#define LOONGARCH_NOTE_HEADER_SIZE offsetof(struct loongarch_note, prstatus) ++#define LOONGARCH_PRSTATUS_NOTE_SIZE (LOONGARCH_NOTE_HEADER_SIZE + \ ++ sizeof(struct loongarch_elf_prstatus)) ++#define LOONGARCH_PRFPREG_NOTE_SIZE (LOONGARCH_NOTE_HEADER_SIZE + \ ++ sizeof(struct loongarch_fpu_struct)) ++ ++static void loongarch_note_init(struct loongarch_note *note, DumpState *s, ++ const char *name, Elf64_Word namesz, ++ Elf64_Word type, Elf64_Word descsz) ++{ ++ memset(note, 0, sizeof(*note)); ++ ++ note->hdr.n_namesz = cpu_to_dump32(s, namesz); ++ note->hdr.n_descsz = cpu_to_dump32(s, descsz); ++ note->hdr.n_type = cpu_to_dump32(s, type); ++ ++ memcpy(note->name, name, namesz); ++} ++ ++static int loongarch_write_elf64_fprpreg(WriteCoreDumpFunction f, ++ CPULOONGARCHState *env, int cpuid, ++ DumpState *s) ++{ ++ struct loongarch_note note; ++ int ret, i; ++ ++ loongarch_note_init(¬e, s, "CORE", 5, NT_PRFPREG, sizeof(note.fpu)); ++ ++ note.fpu.fcsr = cpu_to_dump64(s, env->active_fpu.fcsr0); ++ ++ for (i = 0; i < 32; ++i) { ++ note.fpu.fpr[i] = cpu_to_dump64(s, env->active_fpu.fpr[i].fd); ++ } ++ ++ ret = f(¬e, LOONGARCH_PRFPREG_NOTE_SIZE, s); ++ if (ret < 0) { ++ return -1; ++ } ++ ++ return 0; ++} ++ ++int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, ++ int cpuid, void *opaque) ++{ ++ struct loongarch_note note; ++ CPULOONGARCHState *env = &LOONGARCH_CPU(cs)->env; ++ DumpState *s = opaque; ++ int ret, i; ++ ++ loongarch_note_init(¬e, s, "CORE", 5, NT_PRSTATUS, sizeof(note.prstatus)); ++ ++ note.prstatus.pr_pid = cpu_to_dump32(s, cpuid); ++ note.prstatus.pr_fpvalid = cpu_to_dump32(s, 1); ++ ++ for (i = 0; i < 32; ++i) { ++ note.prstatus.pr_reg.gpr[i] = cpu_to_dump64(s, env->active_tc.gpr[i]); ++ } ++ note.prstatus.pr_reg.csr_era = cpu_to_dump64(s, env->CSR_ERA); ++ note.prstatus.pr_reg.csr_badvaddr = cpu_to_dump64(s, env->CSR_BADV); ++ note.prstatus.pr_reg.csr_crmd = cpu_to_dump64(s, env->CSR_CRMD); ++ note.prstatus.pr_reg.csr_ecfg = cpu_to_dump64(s, env->CSR_ECFG); ++ ++ ret = f(¬e, LOONGARCH_PRSTATUS_NOTE_SIZE, s); ++ if (ret < 0) { ++ return -1; ++ } ++ ++ ret = loongarch_write_elf64_fprpreg(f, env, cpuid, s); ++ if (ret < 0) { ++ return -1; ++ } ++ ++ return ret; ++} ++ ++int cpu_get_dump_info(ArchDumpInfo *info, ++ const GuestPhysBlockList *guest_phys_blocks) ++{ ++ info->d_machine = EM_LOONGARCH; ++ info->d_endian = ELFDATA2LSB; ++ info->d_class = ELFCLASS64; ++ ++ return 0; ++} ++ ++ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) ++{ ++ size_t note_size = 0; ++ ++ if (class == ELFCLASS64) { ++ note_size = LOONGARCH_PRSTATUS_NOTE_SIZE + LOONGARCH_PRFPREG_NOTE_SIZE; ++ } ++ ++ return note_size * nr_cpus; ++} ++ +diff --git a/target/loongarch64/cpu-csr.h b/target/loongarch64/cpu-csr.h +new file mode 100644 +index 0000000000..e549bb46b6 +--- /dev/null ++++ b/target/loongarch64/cpu-csr.h +@@ -0,0 +1,869 @@ ++#ifndef _CPU_CSR_H_ ++#define _CPU_CSR_H_ ++ ++/* basic CSR register */ ++#define LOONGARCH_CSR_CRMD 0x0 /* 32 current mode info */ ++#define CSR_CRMD_DACM_SHIFT 7 ++#define CSR_CRMD_DACM_WIDTH 2 ++#define CSR_CRMD_DACM (0x3UL << CSR_CRMD_DACM_SHIFT) ++#define CSR_CRMD_DACF_SHIFT 5 ++#define CSR_CRMD_DACF_WIDTH 2 ++#define CSR_CRMD_DACF (0x3UL << CSR_CRMD_DACF_SHIFT) ++#define CSR_CRMD_PG_SHIFT 4 ++#define CSR_CRMD_PG (0x1UL << CSR_CRMD_PG_SHIFT) ++#define CSR_CRMD_DA_SHIFT 3 ++#define CSR_CRMD_DA (0x1UL << CSR_CRMD_DA_SHIFT) ++#define CSR_CRMD_IE_SHIFT 2 ++#define CSR_CRMD_IE (0x1UL << CSR_CRMD_IE_SHIFT) ++#define CSR_CRMD_PLV_SHIFT 0 ++#define CSR_CRMD_PLV_WIDTH 2 ++#define CSR_CRMD_PLV (0x3UL << CSR_CRMD_PLV_SHIFT) ++ ++#define PLV_USER 3 ++#define PLV_KERN 0 ++#define PLV_MASK 0x3 ++ ++#define LOONGARCH_CSR_PRMD 0x1 /* 32 prev-exception mode info */ ++#define CSR_PRMD_PIE_SHIFT 2 ++#define CSR_PRMD_PIE (0x1UL << CSR_PRMD_PIE_SHIFT) ++#define CSR_PRMD_PPLV_SHIFT 0 ++#define CSR_PRMD_PPLV_WIDTH 2 ++#define CSR_PRMD_PPLV (0x3UL << CSR_PRMD_PPLV_SHIFT) ++ ++#define LOONGARCH_CSR_EUEN 0x2 /* 32 coprocessor enable */ ++#define CSR_EUEN_LBTEN_SHIFT 3 ++#define CSR_EUEN_LBTEN (0x1UL << CSR_EUEN_LBTEN_SHIFT) ++#define CSR_EUEN_LASXEN_SHIFT 2 ++#define CSR_EUEN_LASXEN (0x1UL << CSR_EUEN_LASXEN_SHIFT) ++#define CSR_EUEN_LSXEN_SHIFT 1 ++#define CSR_EUEN_LSXEN (0x1UL << CSR_EUEN_LSXEN_SHIFT) ++#define CSR_EUEN_FPEN_SHIFT 0 ++#define CSR_EUEN_FPEN (0x1UL << CSR_EUEN_FPEN_SHIFT) ++ ++#define LOONGARCH_CSR_MISC 0x3 /* 32 misc config */ ++ ++#define LOONGARCH_CSR_ECFG 0x4 /* 32 exception config */ ++#define CSR_ECFG_VS_SHIFT 16 ++#define CSR_ECFG_VS_WIDTH 3 ++#define CSR_ECFG_VS (0x7UL << CSR_ECFG_VS_SHIFT) ++#define CSR_ECFG_IM_SHIFT 0 ++#define CSR_ECFG_IM_WIDTH 13 ++#define CSR_ECFG_IM (0x1fffUL << CSR_ECFG_IM_SHIFT) ++ ++#define CSR_ECFG_IPMASK 0x00001fff ++ ++#define LOONGARCH_CSR_ESTAT 0x5 /* Exception status */ ++#define CSR_ESTAT_ESUBCODE_SHIFT 22 ++#define CSR_ESTAT_ESUBCODE_WIDTH 9 ++#define CSR_ESTAT_ESUBCODE (0x1ffULL << CSR_ESTAT_ESUBCODE_SHIFT) ++#define CSR_ESTAT_EXC_SH 16 ++#define CSR_ESTAT_EXC_WIDTH 5 ++#define CSR_ESTAT_EXC (0x1fULL << CSR_ESTAT_EXC_SH) ++#define CSR_ESTAT_IS_SHIFT 0 ++#define CSR_ESTAT_IS_WIDTH 15 ++#define CSR_ESTAT_IS (0x7fffULL << CSR_ESTAT_IS_SHIFT) ++ ++#define CSR_ESTAT_IPMASK 0x00001fff ++ ++#define EXCODE_IP 64 ++#define EXCCODE_RSV 0 ++#define EXCCODE_TLBL 1 ++#define EXCCODE_TLBS 2 ++#define EXCCODE_TLBI 3 ++#define EXCCODE_MOD 4 ++#define EXCCODE_TLBRI 5 ++#define EXCCODE_TLBXI 6 ++#define EXCCODE_TLBPE 7 ++#define EXCCODE_ADE 8 ++#define EXCCODE_UNALIGN 9 ++#define EXCCODE_OOB 10 ++#define EXCCODE_SYS 11 ++#define EXCCODE_BP 12 ++#define EXCCODE_RI 13 ++#define EXCCODE_IPE 14 ++#define EXCCODE_FPDIS 15 ++#define EXCCODE_LSXDIS 16 ++#define EXCCODE_LASXDIS 17 ++#define EXCCODE_FPE 18 ++#define EXCCODE_WATCH 19 ++#define EXCCODE_BTDIS 20 ++#define EXCCODE_BTE 21 ++#define EXCCODE_PSI 22 ++#define EXCCODE_HYP 23 ++#define EXCCODE_FC 24 ++#define EXCCODE_SE 25 ++ ++#define LOONGARCH_CSR_ERA 0x6 /* 64 error PC */ ++ ++#define LOONGARCH_CSR_BADV 0x7 /* 64 bad virtual address */ ++ ++#define LOONGARCH_CSR_BADI 0x8 /* 32 bad instruction */ ++ ++#define LOONGARCH_CSR_EEPN 0xc /* 64 exception enter base address */ ++#define LOONGARCH_EEPN_CPUID (0x3ffULL << 0) ++ ++#define CU_FPE 1 ++#define CU_LSXE (1 << 1) ++#define CU_LASXE (1 << 2) ++#define CU_LBTE (1 << 3) ++ ++/* TLB related CSR register : start with TLB if no pagewalk */ ++/* 32 TLB Index, EHINV, PageSize, is_gtlb */ ++#define LOONGARCH_CSR_TLBIDX 0x10 ++#define CSR_TLBIDX_EHINV_SHIFT 31 ++#define CSR_TLBIDX_EHINV (0x1ULL << CSR_TLBIDX_EHINV_SHIFT) ++#define CSR_TLBIDX_PS_SHIFT 24 ++#define CSR_TLBIDX_PS_WIDTH 6 ++#define CSR_TLBIDX_PS (0x3fULL << CSR_TLBIDX_PS_SHIFT) ++#define CSR_TLBIDX_IDX_SHIFT 0 ++#define CSR_TLBIDX_IDX_WIDTH 12 ++#define CSR_TLBIDX_IDX (0xfffULL << CSR_TLBIDX_IDX_SHIFT) ++#define CSR_TLBIDX_SIZEM 0x3f000000 ++#define CSR_TLBIDX_SIZE CSR_TLBIDX_PS_SHIFT ++#define CSR_TLBIDX_IDXM 0xfff ++ ++#define LOONGARCH_CSR_TLBEHI 0x11 /* 64 TLB EntryHi without ASID */ ++ ++#define LOONGARCH_CSR_TLBELO0 0x12 /* 64 TLB EntryLo0 */ ++#define CSR_TLBLO0_RPLV_SHIFT 63 ++#define CSR_TLBLO0_RPLV (0x1ULL << CSR_TLBLO0_RPLV_SHIFT) ++#define CSR_TLBLO0_XI_SHIFT 62 ++#define CSR_TLBLO0_XI (0x1ULL << CSR_TLBLO0_XI_SHIFT) ++#define CSR_TLBLO0_RI_SHIFT 61 ++#define CSR_TLBLO0_RI (0x1ULL << CSR_TLBLO0_RI_SHIFT) ++#define CSR_TLBLO0_PPN_SHIFT 12 ++#define CSR_TLBLO0_PPN_WIDTH 36 /* ignore lower 12bits */ ++#define CSR_TLBLO0_PPN (0xfffffffffULL << CSR_TLBLO0_PPN_SHIFT) ++#define CSR_TLBLO0_GLOBAL_SHIFT 6 ++#define CSR_TLBLO0_GLOBAL (0x1ULL << CSR_TLBLO0_GLOBAL_SHIFT) ++#define CSR_TLBLO0_CCA_SHIFT 4 ++#define CSR_TLBLO0_CCA_WIDTH 2 ++#define CSR_TLBLO0_CCA (0x3ULL << CSR_TLBLO0_CCA_SHIFT) ++#define CSR_TLBLO0_PLV_SHIFT 2 ++#define CSR_TLBLO0_PLV_WIDTH 2 ++#define CSR_TLBLO0_PLV (0x3ULL << CSR_TLBLO0_PLV_SHIFT) ++#define CSR_TLBLO0_WE_SHIFT 1 ++#define CSR_TLBLO0_WE (0x1ULL << CSR_TLBLO0_WE_SHIFT) ++#define CSR_TLBLO0_V_SHIFT 0 ++#define CSR_TLBLO0_V (0x1ULL << CSR_TLBLO0_V_SHIFT) ++ ++#define LOONGARCH_CSR_TLBELO1 0x13 /* 64 TLB EntryLo1 */ ++#define CSR_TLBLO1_RPLV_SHIFT 63 ++#define CSR_TLBLO1_RPLV (0x1ULL << CSR_TLBLO1_RPLV_SHIFT) ++#define CSR_TLBLO1_XI_SHIFT 62 ++#define CSR_TLBLO1_XI (0x1ULL << CSR_TLBLO1_XI_SHIFT) ++#define CSR_TLBLO1_RI_SHIFT 61 ++#define CSR_TLBLO1_RI (0x1ULL << CSR_TLBLO1_RI_SHIFT) ++#define CSR_TLBLO1_PPN_SHIFT 12 ++#define CSR_TLBLO1_PPN_WIDTH 36 /* ignore lower 12bits */ ++#define CSR_TLBLO1_PPN (0xfffffffffULL << CSR_TLBLO1_PPN_SHIFT) ++#define CSR_TLBLO1_GLOBAL_SHIFT 6 ++#define CSR_TLBLO1_GLOBAL (0x1ULL << CSR_TLBLO1_GLOBAL_SHIFT) ++#define CSR_TLBLO1_CCA_SHIFT 4 ++#define CSR_TLBLO1_CCA_WIDTH 2 ++#define CSR_TLBLO1_CCA (0x3ULL << CSR_TLBLO1_CCA_SHIFT) ++#define CSR_TLBLO1_PLV_SHIFT 2 ++#define CSR_TLBLO1_PLV_WIDTH 2 ++#define CSR_TLBLO1_PLV (0x3ULL << CSR_TLBLO1_PLV_SHIFT) ++#define CSR_TLBLO1_WE_SHIFT 1 ++#define CSR_TLBLO1_WE (0x1ULL << CSR_TLBLO1_WE_SHIFT) ++#define CSR_TLBLO1_V_SHIFT 0 ++#define CSR_TLBLO1_V (0x1ULL << CSR_TLBLO1_V_SHIFT) ++ ++#define LOONGARCH_ENTRYLO_RI (1ULL << 61) ++#define LOONGARCH_ENTRYLO_XI (1ULL << 62) ++ ++#define LOONGARCH_CSR_TLBWIRED 0x14 /* 32 TLB wired */ ++#define LOONGARCH_CSR_GTLBC 0x15 /* guest-related TLB */ ++#define CSR_GTLBC_RID_SHIFT 16 ++#define CSR_GTLBC_RID_WIDTH 8 ++#define CSR_GTLBC_RID (0xffULL << CSR_GTLBC_RID_SHIFT) ++#define CSR_GTLBC_TOTI_SHIFT 13 ++#define CSR_GTLBC_TOTI (0x1ULL << CSR_GTLBC_TOTI_SHIFT) ++#define CSR_GTLBC_USERID_SHIFT 12 ++#define CSR_GTLBC_USERID (0x1ULL << CSR_GTLBC_USERID_SHIFT) ++#define CSR_GTLBC_GMTLBSZ_SHIFT 0 ++#define CSR_GTLBC_GMTLBSZ_WIDTH 6 ++#define CSR_GTLBC_GMTLBSZ (0x3fULL << CSR_GTLBC_GVTLBSZ_SHIFT) ++ ++#define LOONGARCH_CSR_TRGP 0x16 /* guest-related TLB */ ++#define CSR_TRGP_RID_SHIFT 16 ++#define CSR_TRGP_RID_WIDTH 8 ++#define CSR_TRGP_RID (0xffULL << CSR_TRGP_RID_SHIFT) ++#define CSR_TRGP_GTLB_SHIFT 0 ++#define CSR_TRGP_GTLB (1 << CSR_TRGP_GTLB_SHIFT) ++ ++#define LOONGARCH_CSR_ASID 0x18 /* 64 ASID */ ++#define CSR_ASID_BIT_SHIFT 16 /* ASIDBits */ ++#define CSR_ASID_BIT_WIDTH 8 ++#define CSR_ASID_BIT (0xffULL << CSR_ASID_BIT_SHIFT) ++#define CSR_ASID_ASID_SHIFT 0 ++#define CSR_ASID_ASID_WIDTH 10 ++#define CSR_ASID_ASID (0x3ffULL << CSR_ASID_ASID_SHIFT) ++ ++/* 64 page table base address when badv[47] = 0 */ ++#define LOONGARCH_CSR_PGDL 0x19 ++/* 64 page table base address when badv[47] = 1 */ ++#define LOONGARCH_CSR_PGDH 0x1a ++ ++#define LOONGARCH_CSR_PGD 0x1b /* 64 page table base */ ++ ++#define LOONGARCH_CSR_PWCTL0 0x1c /* 64 PWCtl0 */ ++#define CSR_PWCTL0_PTEW_SHIFT 30 ++#define CSR_PWCTL0_PTEW_WIDTH 2 ++#define CSR_PWCTL0_PTEW (0x3ULL << CSR_PWCTL0_PTEW_SHIFT) ++#define CSR_PWCTL0_DIR1WIDTH_SHIFT 25 ++#define CSR_PWCTL0_DIR1WIDTH_WIDTH 5 ++#define CSR_PWCTL0_DIR1WIDTH (0x1fULL << CSR_PWCTL0_DIR1WIDTH_SHIFT) ++#define CSR_PWCTL0_DIR1BASE_SHIFT 20 ++#define CSR_PWCTL0_DIR1BASE_WIDTH 5 ++#define CSR_PWCTL0_DIR1BASE (0x1fULL << CSR_PWCTL0_DIR1BASE_SHIFT) ++#define CSR_PWCTL0_DIR0WIDTH_SHIFT 15 ++#define CSR_PWCTL0_DIR0WIDTH_WIDTH 5 ++#define CSR_PWCTL0_DIR0WIDTH (0x1fULL << CSR_PWCTL0_DIR0WIDTH_SHIFT) ++#define CSR_PWCTL0_DIR0BASE_SHIFT 10 ++#define CSR_PWCTL0_DIR0BASE_WIDTH 5 ++#define CSR_PWCTL0_DIR0BASE (0x1fULL << CSR_PWCTL0_DIR0BASE_SHIFT) ++#define CSR_PWCTL0_PTWIDTH_SHIFT 5 ++#define CSR_PWCTL0_PTWIDTH_WIDTH 5 ++#define CSR_PWCTL0_PTWIDTH (0x1fULL << CSR_PWCTL0_PTWIDTH_SHIFT) ++#define CSR_PWCTL0_PTBASE_SHIFT 0 ++#define CSR_PWCTL0_PTBASE_WIDTH 5 ++#define CSR_PWCTL0_PTBASE (0x1fULL << CSR_PWCTL0_PTBASE_SHIFT) ++ ++#define LOONGARCH_CSR_PWCTL1 0x1d /* 64 PWCtl1 */ ++#define CSR_PWCTL1_DIR3WIDTH_SHIFT 18 ++#define CSR_PWCTL1_DIR3WIDTH_WIDTH 5 ++#define CSR_PWCTL1_DIR3WIDTH (0x1fULL << CSR_PWCTL1_DIR3WIDTH_SHIFT) ++#define CSR_PWCTL1_DIR3BASE_SHIFT 12 ++#define CSR_PWCTL1_DIR3BASE_WIDTH 5 ++#define CSR_PWCTL1_DIR3BASE (0x1fULL << CSR_PWCTL0_DIR3BASE_SHIFT) ++#define CSR_PWCTL1_DIR2WIDTH_SHIFT 6 ++#define CSR_PWCTL1_DIR2WIDTH_WIDTH 5 ++#define CSR_PWCTL1_DIR2WIDTH (0x1fULL << CSR_PWCTL1_DIR2WIDTH_SHIFT) ++#define CSR_PWCTL1_DIR2BASE_SHIFT 0 ++#define CSR_PWCTL1_DIR2BASE_WIDTH 5 ++#define CSR_PWCTL1_DIR2BASE (0x1fULL << CSR_PWCTL0_DIR2BASE_SHIFT) ++ ++#define LOONGARCH_CSR_STLBPGSIZE 0x1e /* 64 */ ++#define CSR_STLBPGSIZE_PS_WIDTH 6 ++#define CSR_STLBPGSIZE_PS (0x3f) ++ ++#define LOONGARCH_CSR_RVACFG 0x1f ++#define CSR_RVACFG_RDVA_WIDTH 4 ++#define CSR_RVACFG_RDVA (0xf) ++ ++/* read only CSR register : start with CPU */ ++#define LOONGARCH_CSR_CPUID 0x20 /* 32 CPU core number */ ++#define CSR_CPUID_CID_WIDTH 9 ++#define CSR_CPUID_CID (0x1ff) ++ ++#define LOONGARCH_CSR_PRCFG1 0x21 /* 32 CPU info */ ++#define CSR_CONF1_VSMAX_SHIFT 12 ++#define CSR_CONF1_VSMAX_WIDTH 3 ++#define CSR_CONF1_VSMAX (7ULL << CSR_CONF1_VSMAX_SHIFT) ++/* stable timer bits - 1, 0x2f = 47*/ ++#define CSR_CONF1_TMRBITS_SHIFT 4 ++#define CSR_CONF1_TMRBITS_WIDTH 8 ++#define CSR_CONF1_TMRBITS (0xffULL << CSR_CONF1_TMRBITS_SHIFT) ++#define CSR_CONF1_KSNUM_SHIFT 0 ++#define CSR_CONF1_KSNUM_WIDTH 4 ++#define CSR_CONF1_KSNUM (0x8) ++ ++#define LOONGARCH_CSR_PRCFG2 0x22 ++#define CSR_CONF2_PGMASK_SUPP 0x3ffff000 ++ ++#define LOONGARCH_CSR_PRCFG3 0x23 ++#define CSR_CONF3_STLBIDX_SHIFT 20 ++#define CSR_CONF3_STLBIDX_WIDTH 6 ++#define CSR_CONF3_STLBIDX (0x3fULL << CSR_CONF3_STLBIDX_SHIFT) ++#define CSR_STLB_SETS 256 ++#define CSR_CONF3_STLBWAYS_SHIFT 12 ++#define CSR_CONF3_STLBWAYS_WIDTH 8 ++#define CSR_CONF3_STLBWAYS (0xffULL << CSR_CONF3_STLBWAYS_SHIFT) ++#define CSR_STLBWAYS_SIZE 8 ++#define CSR_CONF3_MTLBSIZE_SHIFT 4 ++#define CSR_CONF3_MTLBSIZE_WIDTH 8 ++#define CSR_CONF3_MTLBSIZE (0xffULL << CSR_CONF3_MTLBSIZE_SHIFT) ++/* mean VTLB 64 index */ ++#define CSR_MTLB_SIZE 64 ++#define CSR_CONF3_TLBORG_SHIFT 0 ++#define CSR_CONF3_TLBORG_WIDTH 4 ++#define CSR_CONF3_TLBORG (0xfULL << CSR_CONF3_TLBORG_SHIFT) ++/* mean use MTLB+STLB */ ++#define TLB_ORG 2 ++ ++/* Kscratch : start with KS */ ++#define LOONGARCH_CSR_KS0 0x30 /* 64 */ ++#define LOONGARCH_CSR_KS1 0x31 /* 64 */ ++#define LOONGARCH_CSR_KS2 0x32 /* 64 */ ++#define LOONGARCH_CSR_KS3 0x33 /* 64 */ ++#define LOONGARCH_CSR_KS4 0x34 /* 64 */ ++#define LOONGARCH_CSR_KS5 0x35 /* 64 */ ++#define LOONGARCH_CSR_KS6 0x36 /* 64 */ ++#define LOONGARCH_CSR_KS7 0x37 /* 64 */ ++#define LOONGARCH_CSR_KS8 0x38 /* 64 */ ++ ++/* timer : start with TM */ ++#define LOONGARCH_CSR_TMID 0x40 /* 32 timer ID */ ++ ++#define LOONGARCH_CSR_TCFG 0x41 /* 64 timer config */ ++#define CSR_TCFG_VAL_SHIFT 2 ++#define CSR_TCFG_VAL_WIDTH 48 ++#define CSR_TCFG_VAL (0x3fffffffffffULL << CSR_TCFG_VAL_SHIFT) ++#define CSR_TCFG_PERIOD_SHIFT 1 ++#define CSR_TCFG_PERIOD (0x1ULL << CSR_TCFG_PERIOD_SHIFT) ++#define CSR_TCFG_EN (0x1) ++ ++#define LOONGARCH_CSR_TVAL 0x42 /* 64 timer ticks remain */ ++ ++#define LOONGARCH_CSR_CNTC 0x43 /* 64 timer offset */ ++ ++#define LOONGARCH_CSR_TINTCLR 0x44 /* 64 timer interrupt clear */ ++#define CSR_TINTCLR_TI_SHIFT 0 ++#define CSR_TINTCLR_TI (1 << CSR_TINTCLR_TI_SHIFT) ++ ++/* guest : start with GST */ ++#define LOONGARCH_CSR_GSTAT 0x50 /* 32 basic guest info */ ++#define CSR_GSTAT_GID_SHIFT 16 ++#define CSR_GSTAT_GID_WIDTH 8 ++#define CSR_GSTAT_GID (0xffULL << CSR_GSTAT_GID_SHIFT) ++#define CSR_GSTAT_GIDBIT_SHIFT 4 ++#define CSR_GSTAT_GIDBIT_WIDTH 6 ++#define CSR_GSTAT_GIDBIT (0x3fULL << CSR_GSTAT_GIDBIT_SHIFT) ++#define CSR_GSTAT_PVM_SHIFT 1 ++#define CSR_GSTAT_PVM (0x1ULL << CSR_GSTAT_PVM_SHIFT) ++#define CSR_GSTAT_VM_SHIFT 0 ++#define CSR_GSTAT_VM (0x1ULL << CSR_GSTAT_VM_SHIFT) ++ ++#define LOONGARCH_CSR_GCFG 0x51 /* 32 guest config */ ++#define CSR_GCFG_GPERF_SHIFT 24 ++#define CSR_GCFG_GPERF_WIDTH 3 ++#define CSR_GCFG_GPERF (0x7ULL << CSR_GCFG_GPERF_SHIFT) ++#define CSR_GCFG_GCI_SHIFT 20 ++#define CSR_GCFG_GCI_WIDTH 2 ++#define CSR_GCFG_GCI (0x3ULL << CSR_GCFG_GCI_SHIFT) ++#define CSR_GCFG_GCI_ALL (0x0ULL << CSR_GCFG_GCI_SHIFT) ++#define CSR_GCFG_GCI_HIT (0x1ULL << CSR_GCFG_GCI_SHIFT) ++#define CSR_GCFG_GCI_SECURE (0x2ULL << CSR_GCFG_GCI_SHIFT) ++#define CSR_GCFG_GCIP_SHIFT 16 ++#define CSR_GCFG_GCIP (0xfULL << CSR_GCFG_GCIP_SHIFT) ++#define CSR_GCFG_GCIP_ALL (0x1ULL << CSR_GCFG_GCIP_SHIFT) ++#define CSR_GCFG_GCIP_HIT (0x1ULL << (CSR_GCFG_GCIP_SHIFT + 1)) ++#define CSR_GCFG_GCIP_SECURE (0x1ULL << (CSR_GCFG_GCIP_SHIFT + 2)) ++#define CSR_GCFG_TORU_SHIFT 15 ++#define CSR_GCFG_TORU (0x1ULL << CSR_GCFG_TORU_SHIFT) ++#define CSR_GCFG_TORUP_SHIFT 14 ++#define CSR_GCFG_TORUP (0x1ULL << CSR_GCFG_TORUP_SHIFT) ++#define CSR_GCFG_TOP_SHIFT 13 ++#define CSR_GCFG_TOP (0x1ULL << CSR_GCFG_TOP_SHIFT) ++#define CSR_GCFG_TOPP_SHIFT 12 ++#define CSR_GCFG_TOPP (0x1ULL << CSR_GCFG_TOPP_SHIFT) ++#define CSR_GCFG_TOE_SHIFT 11 ++#define CSR_GCFG_TOE (0x1ULL << CSR_GCFG_TOE_SHIFT) ++#define CSR_GCFG_TOEP_SHIFT 10 ++#define CSR_GCFG_TOEP (0x1ULL << CSR_GCFG_TOEP_SHIFT) ++#define CSR_GCFG_TIT_SHIFT 9 ++#define CSR_GCFG_TIT (0x1ULL << CSR_GCFG_TIT_SHIFT) ++#define CSR_GCFG_TITP_SHIFT 8 ++#define CSR_GCFG_TITP (0x1ULL << CSR_GCFG_TITP_SHIFT) ++#define CSR_GCFG_SIT_SHIFT 7 ++#define CSR_GCFG_SIT (0x1ULL << CSR_GCFG_SIT_SHIFT) ++#define CSR_GCFG_SITP_SHIFT 6 ++#define CSR_GCFG_SITP (0x1ULL << CSR_GCFG_SITP_SHIFT) ++#define CSR_GCFG_CACTRL_SHIFT 4 ++#define CSR_GCFG_CACTRL_WIDTH 2 ++#define CSR_GCFG_CACTRL (0x3ULL << CSR_GCFG_CACTRL_SHIFT) ++#define CSR_GCFG_CACTRL_GUEST (0x0ULL << CSR_GCFG_CACTRL_SHIFT) ++#define CSR_GCFG_CACTRL_ROOT (0x1ULL << CSR_GCFG_CACTRL_SHIFT) ++#define CSR_GCFG_CACTRL_NEST (0x2ULL << CSR_GCFG_CACTRL_SHIFT) ++#define CSR_GCFG_CCCP_WIDTH 4 ++#define CSR_GCFG_CCCP (0xf) ++#define CSR_GCFG_CCCP_GUEST (0x1ULL << 0) ++#define CSR_GCFG_CCCP_ROOT (0x1ULL << 1) ++#define CSR_GCFG_CCCP_NEST (0x1ULL << 2) ++ ++#define LOONGARCH_CSR_GINTC 0x52 /* 64 guest exception control */ ++#define CSR_GINTC_HC_SHIFT 16 ++#define CSR_GINTC_HC_WIDTH 8 ++#define CSR_GINTC_HC (0xffULL << CSR_GINTC_HC_SHIFT) ++#define CSR_GINTC_PIP_SHIFT 8 ++#define CSR_GINTC_PIP_WIDTH 8 ++#define CSR_GINTC_PIP (0xffULL << CSR_GINTC_PIP_SHIFT) ++#define CSR_GINTC_VIP_SHIFT 0 ++#define CSR_GINTC_VIP_WIDTH 8 ++#define CSR_GINTC_VIP (0xff) ++ ++#define LOONGARCH_CSR_GCNTC 0x53 /* 64 guest timer offset */ ++ ++/* LLBCTL */ ++#define LOONGARCH_CSR_LLBCTL 0x60 /* 32 csr number to be changed */ ++#define CSR_LLBCTL_ROLLB_SHIFT 0 ++#define CSR_LLBCTL_ROLLB (1ULL << CSR_LLBCTL_ROLLB_SHIFT) ++#define CSR_LLBCTL_WCLLB_SHIFT 1 ++#define CSR_LLBCTL_WCLLB (1ULL << CSR_LLBCTL_WCLLB_SHIFT) ++#define CSR_LLBCTL_KLO_SHIFT 2 ++#define CSR_LLBCTL_KLO (1ULL << CSR_LLBCTL_KLO_SHIFT) ++ ++/* implement dependent */ ++#define LOONGARCH_CSR_IMPCTL1 0x80 /* 32 loongarch config */ ++#define CSR_MISPEC_SHIFT 20 ++#define CSR_MISPEC_WIDTH 8 ++#define CSR_MISPEC (0xffULL << CSR_MISPEC_SHIFT) ++#define CSR_SSEN_SHIFT 18 ++#define CSR_SSEN (1ULL << CSR_SSEN_SHIFT) ++#define CSR_SCRAND_SHIFT 17 ++#define CSR_SCRAND (1ULL << CSR_SCRAND_SHIFT) ++#define CSR_LLEXCL_SHIFT 16 ++#define CSR_LLEXCL (1ULL << CSR_LLEXCL_SHIFT) ++#define CSR_DISVC_SHIFT 15 ++#define CSR_DISVC (1ULL << CSR_DISVC_SHIFT) ++#define CSR_VCLRU_SHIFT 14 ++#define CSR_VCLRU (1ULL << CSR_VCLRU_SHIFT) ++#define CSR_DCLRU_SHIFT 13 ++#define CSR_DCLRU (1ULL << CSR_DCLRU_SHIFT) ++#define CSR_FASTLDQ_SHIFT 12 ++#define CSR_FASTLDQ (1ULL << CSR_FASTLDQ_SHIFT) ++#define CSR_USERCAC_SHIFT 11 ++#define CSR_USERCAC (1ULL << CSR_USERCAC_SHIFT) ++#define CSR_ANTI_MISPEC_SHIFT 10 ++#define CSR_ANTI_MISPEC (1ULL << CSR_ANTI_MISPEC_SHIFT) ++#define CSR_ANTI_FLUSHSFB_SHIFT 9 ++#define CSR_ANTI_FLUSHSFB (1ULL << CSR_ANTI_FLUSHSFB_SHIFT) ++#define CSR_STFILL_SHIFT 8 ++#define CSR_STFILL (1ULL << CSR_STFILL_SHIFT) ++#define CSR_LIFEP_SHIFT 7 ++#define CSR_LIFEP (1ULL << CSR_LIFEP_SHIFT) ++#define CSR_LLSYNC_SHIFT 6 ++#define CSR_LLSYNC (1ULL << CSR_LLSYNC_SHIFT) ++#define CSR_BRBTDIS_SHIFT 5 ++#define CSR_BRBTDIS (1ULL << CSR_BRBTDIS_SHIFT) ++#define CSR_RASDIS_SHIFT 4 ++#define CSR_RASDIS (1ULL << CSR_RASDIS_SHIFT) ++#define CSR_STPRE_SHIFT 2 ++#define CSR_STPRE_WIDTH 2 ++#define CSR_STPRE (3ULL << CSR_STPRE_SHIFT) ++#define CSR_INSTPRE_SHIFT 1 ++#define CSR_INSTPRE (1ULL << CSR_INSTPRE_SHIFT) ++#define CSR_DATAPRE_SHIFT 0 ++#define CSR_DATAPRE (1ULL << CSR_DATAPRE_SHIFT) ++ ++#define LOONGARCH_CSR_IMPCTL2 0x81 /* 32 Flush */ ++#define CSR_IMPCTL2_MTLB_SHIFT 0 ++#define CSR_IMPCTL2_MTLB (1ULL << CSR_IMPCTL2_MTLB_SHIFT) ++#define CSR_IMPCTL2_STLB_SHIFT 1 ++#define CSR_IMPCTL2_STLB (1ULL << CSR_IMPCTL2_STLB_SHIFT) ++#define CSR_IMPCTL2_DTLB_SHIFT 2 ++#define CSR_IMPCTL2_DTLB (1ULL << CSR_IMPCTL2_DTLB_SHIFT) ++#define CSR_IMPCTL2_ITLB_SHIFT 3 ++#define CSR_IMPCTL2_ITLB (1ULL << CSR_IMPCTL2_ITLB_SHIFT) ++#define CSR_IMPCTL2_BTAC_SHIFT 4 ++#define CSR_IMPCTL2_BTAC (1ULL << CSR_IMPCTL2_BTAC_SHIFT) ++ ++#define LOONGARCH_FLUSH_VTLB 1 ++#define LOONGARCH_FLUSH_FTLB (1 << 1) ++#define LOONGARCH_FLUSH_DTLB (1 << 2) ++#define LOONGARCH_FLUSH_ITLB (1 << 3) ++#define LOONGARCH_FLUSH_BTAC (1 << 4) ++ ++#define LOONGARCH_CSR_GNMI 0x82 ++ ++/* TLB Refill Only */ ++#define LOONGARCH_CSR_TLBRENT 0x88 /* 64 TLB refill exception address */ ++#define LOONGARCH_CSR_TLBRBADV 0x89 /* 64 TLB refill badvaddr */ ++#define LOONGARCH_CSR_TLBRERA 0x8a /* 64 TLB refill ERA */ ++#define LOONGARCH_CSR_TLBRSAVE 0x8b /* 64 KScratch for TLB refill */ ++#define LOONGARCH_CSR_TLBRELO0 0x8c /* 64 TLB refill entrylo0 */ ++#define LOONGARCH_CSR_TLBRELO1 0x8d /* 64 TLB refill entrylo1 */ ++#define LOONGARCH_CSR_TLBREHI 0x8e /* 64 TLB refill entryhi */ ++#define LOONGARCH_CSR_TLBRPRMD 0x8f /* 64 TLB refill mode info */ ++ ++/* error related */ ++#define LOONGARCH_CSR_ERRCTL 0x90 /* 32 ERRCTL */ ++#define LOONGARCH_CSR_ERRINFO 0x91 ++#define LOONGARCH_CSR_ERRINFO1 0x92 ++#define LOONGARCH_CSR_ERRENT 0x93 /* 64 error exception base */ ++#define LOONGARCH_CSR_ERRERA 0x94 /* 64 error exception PC */ ++#define LOONGARCH_CSR_ERRSAVE 0x95 /* 64 KScratch for error exception */ ++ ++#define LOONGARCH_CSR_CTAG 0x98 /* 64 TagLo + TagHi */ ++ ++/* direct map windows */ ++#define LOONGARCH_CSR_DMWIN0 0x180 /* 64 direct map win0: MEM & IF */ ++#define LOONGARCH_CSR_DMWIN1 0x181 /* 64 direct map win1: MEM & IF */ ++#define LOONGARCH_CSR_DMWIN2 0x182 /* 64 direct map win2: MEM */ ++#define LOONGARCH_CSR_DMWIN3 0x183 /* 64 direct map win3: MEM */ ++#define CSR_DMW_PLV0 0x1 ++#define CSR_DMW_PLV1 0x2 ++#define CSR_DMW_PLV2 0x4 ++#define CSR_DMW_PLV3 0x8 ++#define CSR_DMW_BASE_SH 48 ++#define dmwin_va2pa(va) \ ++ (va & (((unsigned long)1 << CSR_DMW_BASE_SH) - 1)) ++ ++/* performance counter */ ++#define LOONGARCH_CSR_PERFCTRL0 0x200 /* 32 perf event 0 config */ ++#define LOONGARCH_CSR_PERFCNTR0 0x201 /* 64 perf event 0 count value */ ++#define LOONGARCH_CSR_PERFCTRL1 0x202 /* 32 perf event 1 config */ ++#define LOONGARCH_CSR_PERFCNTR1 0x203 /* 64 perf event 1 count value */ ++#define LOONGARCH_CSR_PERFCTRL2 0x204 /* 32 perf event 2 config */ ++#define LOONGARCH_CSR_PERFCNTR2 0x205 /* 64 perf event 2 count value */ ++#define LOONGARCH_CSR_PERFCTRL3 0x206 /* 32 perf event 3 config */ ++#define LOONGARCH_CSR_PERFCNTR3 0x207 /* 64 perf event 3 count value */ ++#define CSR_PERFCTRL_PLV0 (1ULL << 16) ++#define CSR_PERFCTRL_PLV1 (1ULL << 17) ++#define CSR_PERFCTRL_PLV2 (1ULL << 18) ++#define CSR_PERFCTRL_PLV3 (1ULL << 19) ++#define CSR_PERFCTRL_IE (1ULL << 20) ++#define CSR_PERFCTRL_EVENT 0x3ff ++ ++/* debug */ ++#define LOONGARCH_CSR_MWPC 0x300 /* data breakpoint config */ ++#define LOONGARCH_CSR_MWPS 0x301 /* data breakpoint status */ ++ ++#define LOONGARCH_CSR_DB0ADDR 0x310 /* data breakpoint 0 address */ ++#define LOONGARCH_CSR_DB0MASK 0x311 /* data breakpoint 0 mask */ ++#define LOONGARCH_CSR_DB0CTL 0x312 /* data breakpoint 0 control */ ++#define LOONGARCH_CSR_DB0ASID 0x313 /* data breakpoint 0 asid */ ++ ++#define LOONGARCH_CSR_DB1ADDR 0x318 /* data breakpoint 1 address */ ++#define LOONGARCH_CSR_DB1MASK 0x319 /* data breakpoint 1 mask */ ++#define LOONGARCH_CSR_DB1CTL 0x31a /* data breakpoint 1 control */ ++#define LOONGARCH_CSR_DB1ASID 0x31b /* data breakpoint 1 asid */ ++ ++#define LOONGARCH_CSR_DB2ADDR 0x320 /* data breakpoint 2 address */ ++#define LOONGARCH_CSR_DB2MASK 0x321 /* data breakpoint 2 mask */ ++#define LOONGARCH_CSR_DB2CTL 0x322 /* data breakpoint 2 control */ ++#define LOONGARCH_CSR_DB2ASID 0x323 /* data breakpoint 2 asid */ ++ ++#define LOONGARCH_CSR_DB3ADDR 0x328 /* data breakpoint 3 address */ ++#define LOONGARCH_CSR_DB3MASK 0x329 /* data breakpoint 3 mask */ ++#define LOONGARCH_CSR_DB3CTL 0x32a /* data breakpoint 3 control */ ++#define LOONGARCH_CSR_DB3ASID 0x32b /* data breakpoint 3 asid */ ++ ++#define LOONGARCH_CSR_FWPC 0x380 /* instruction breakpoint config */ ++#define LOONGARCH_CSR_FWPS 0x381 /* instruction breakpoint status */ ++ ++#define LOONGARCH_CSR_IB0ADDR 0x390 /* inst breakpoint 0 address */ ++#define LOONGARCH_CSR_IB0MASK 0x391 /* inst breakpoint 0 mask */ ++#define LOONGARCH_CSR_IB0CTL 0x392 /* inst breakpoint 0 control */ ++#define LOONGARCH_CSR_IB0ASID 0x393 /* inst breakpoint 0 asid */ ++#define LOONGARCH_CSR_IB1ADDR 0x398 /* inst breakpoint 1 address */ ++#define LOONGARCH_CSR_IB1MASK 0x399 /* inst breakpoint 1 mask */ ++#define LOONGARCH_CSR_IB1CTL 0x39a /* inst breakpoint 1 control */ ++#define LOONGARCH_CSR_IB1ASID 0x39b /* inst breakpoint 1 asid */ ++ ++#define LOONGARCH_CSR_IB2ADDR 0x3a0 /* inst breakpoint 2 address */ ++#define LOONGARCH_CSR_IB2MASK 0x3a1 /* inst breakpoint 2 mask */ ++#define LOONGARCH_CSR_IB2CTL 0x3a2 /* inst breakpoint 2 control */ ++#define LOONGARCH_CSR_IB2ASID 0x3a3 /* inst breakpoint 2 asid */ ++ ++#define LOONGARCH_CSR_IB3ADDR 0x3a8 /* inst breakpoint 3 address */ ++#define LOONGARCH_CSR_IB3MASK 0x3a9 /* inst breakpoint 3 mask */ ++#define LOONGARCH_CSR_IB3CTL 0x3aa /* inst breakpoint 3 control */ ++#define LOONGARCH_CSR_IB3ASID 0x3ab /* inst breakpoint 3 asid */ ++ ++#define LOONGARCH_CSR_IB4ADDR 0x3b0 /* inst breakpoint 4 address */ ++#define LOONGARCH_CSR_IB4MASK 0x3b1 /* inst breakpoint 4 mask */ ++#define LOONGARCH_CSR_IB4CTL 0x3b2 /* inst breakpoint 4 control */ ++#define LOONGARCH_CSR_IB4ASID 0x3b3 /* inst breakpoint 4 asid */ ++ ++#define LOONGARCH_CSR_IB5ADDR 0x3b8 /* inst breakpoint 5 address */ ++#define LOONGARCH_CSR_IB5MASK 0x3b9 /* inst breakpoint 5 mask */ ++#define LOONGARCH_CSR_IB5CTL 0x3ba /* inst breakpoint 5 control */ ++#define LOONGARCH_CSR_IB5ASID 0x3bb /* inst breakpoint 5 asid */ ++ ++#define LOONGARCH_CSR_IB6ADDR 0x3c0 /* inst breakpoint 6 address */ ++#define LOONGARCH_CSR_IB6MASK 0x3c1 /* inst breakpoint 6 mask */ ++#define LOONGARCH_CSR_IB6CTL 0x3c2 /* inst breakpoint 6 control */ ++#define LOONGARCH_CSR_IB6ASID 0x3c3 /* inst breakpoint 6 asid */ ++ ++#define LOONGARCH_CSR_IB7ADDR 0x3c8 /* inst breakpoint 7 address */ ++#define LOONGARCH_CSR_IB7MASK 0x3c9 /* inst breakpoint 7 mask */ ++#define LOONGARCH_CSR_IB7CTL 0x3ca /* inst breakpoint 7 control */ ++#define LOONGARCH_CSR_IB7ASID 0x3cb /* inst breakpoint 7 asid */ ++ ++#define LOONGARCH_CSR_DEBUG 0x500 /* debug config */ ++#define CSR_DEBUG_DM 0 ++#define CSR_DEBUG_DMVER 1 ++#define CSR_DEBUG_DINT 8 ++#define CSR_DEBUG_DBP 9 ++#define CSR_DEBUG_DIB 10 ++#define CSR_DEBUG_DDB 11 ++ ++#define LOONGARCH_CSR_DERA 0x501 /* debug era */ ++#define LOONGARCH_CSR_DESAVE 0x502 /* debug save */ ++ ++#define LOONGARCH_CSR_PRID 0xc0 /* 32 LOONGARCH CP0 PRID */ ++ ++#define LOONGARCH_CPUCFG0 0x0 ++#define CPUCFG0_3A5000_PRID 0x0014c010 ++ ++#define LOONGARCH_CPUCFG1 0x1 ++#define CPUCFG1_ISGR32 BIT(0) ++#define CPUCFG1_ISGR64 BIT(1) ++#define CPUCFG1_PAGING BIT(2) ++#define CPUCFG1_IOCSR BIT(3) ++#define CPUCFG1_PABITS (47 << 4) ++#define CPUCFG1_VABITS (47 << 12) ++#define CPUCFG1_UAL BIT(20) ++#define CPUCFG1_RI BIT(21) ++#define CPUCFG1_XI BIT(22) ++#define CPUCFG1_RPLV BIT(23) ++#define CPUCFG1_HUGEPG BIT(24) ++#define CPUCFG1_IOCSRBRD BIT(25) ++#define CPUCFG1_MSGINT BIT(26) ++ ++#define LOONGARCH_CPUCFG2 0x2 ++#define CPUCFG2_FP BIT(0) ++#define CPUCFG2_FPSP BIT(1) ++#define CPUCFG2_FPDP BIT(2) ++#define CPUCFG2_FPVERS (0 << 3) ++#define CPUCFG2_LSX BIT(6) ++#define CPUCFG2_LASX BIT(7) ++#define CPUCFG2_COMPLEX BIT(8) ++#define CPUCFG2_CRYPTO BIT(9) ++#define CPUCFG2_LVZP BIT(10) ++#define CPUCFG2_LVZVER (0 << 11) ++#define CPUCFG2_LLFTP BIT(14) ++#define CPUCFG2_LLFTPREV (1 << 15) ++#define CPUCFG2_X86BT BIT(18) ++#define CPUCFG2_ARMBT BIT(19) ++#define CPUCFG2_MIPSBT BIT(20) ++#define CPUCFG2_LSPW BIT(21) ++#define CPUCFG2_LAM BIT(22) ++ ++#define LOONGARCH_CPUCFG3 0x3 ++#define CPUCFG3_CCDMA BIT(0) ++#define CPUCFG3_SFB BIT(1) ++#define CPUCFG3_UCACC BIT(2) ++#define CPUCFG3_LLEXC BIT(3) ++#define CPUCFG3_SCDLY BIT(4) ++#define CPUCFG3_LLDBAR BIT(5) ++#define CPUCFG3_ITLBT BIT(6) ++#define CPUCFG3_ICACHET BIT(7) ++#define CPUCFG3_SPW_LVL (4 << 8) ++#define CPUCFG3_SPW_HG_HF BIT(11) ++#define CPUCFG3_RVA BIT(12) ++#define CPUCFG3_RVAMAX (7 << 13) ++ ++#define LOONGARCH_CPUCFG4 0x4 ++#define CCFREQ_100M 100000000 /* 100M */ ++ ++#define LOONGARCH_CPUCFG5 0x5 ++#define CPUCFG5_CCMUL 1 ++#define CPUCFG5_CCDIV (1 << 16) ++ ++#define LOONGARCH_CPUCFG6 0x6 ++#define CPUCFG6_PMP BIT(0) ++#define CPUCFG6_PAMVER (1 << 1) ++#define CPUCFG6_PMNUM (3 << 4) ++#define CPUCFG6_PMBITS (63 << 8) ++#define CPUCFG6_UPM BIT(14) ++ ++#define LOONGARCH_CPUCFG16 0x10 ++#define CPUCFG16_L1_IUPRE BIT(0) ++#define CPUCFG16_L1_UNIFY BIT(1) ++#define CPUCFG16_L1_DPRE BIT(2) ++#define CPUCFG16_L2_IUPRE BIT(3) ++#define CPUCFG16_L2_IUUNIFY BIT(4) ++#define CPUCFG16_L2_IUPRIV BIT(5) ++#define CPUCFG16_L2_IUINCL BIT(6) ++#define CPUCFG16_L2_DPRE BIT(7) ++#define CPUCFG16_L2_DPRIV BIT(8) ++#define CPUCFG16_L2_DINCL BIT(9) ++#define CPUCFG16_L3_IUPRE BIT(10) ++#define CPUCFG16_L3_IUUNIFY BIT(11) ++#define CPUCFG16_L3_IUPRIV BIT(12) ++#define CPUCFG16_L3_IUINCL BIT(13) ++#define CPUCFG16_L3_DPRE BIT(14) ++#define CPUCFG16_L3_DPRIV BIT(15) ++#define CPUCFG16_L3_DINCL BIT(16) ++ ++#define LOONGARCH_CPUCFG17 0x11 ++#define CPUCFG17_L1I_WAYS_M (3 << 0) ++#define CPUCFG17_L1I_SETS_M (8 << 16) ++#define CPUCFG17_L1I_SIZE_M (6 << 24) ++ ++#define LOONGARCH_CPUCFG18 0x12 ++#define CPUCFG18_L1D_WAYS_M (3 << 0) ++#define CPUCFG18_L1D_SETS_M (8 << 16) ++#define CPUCFG18_L1D_SIZE_M (6 << 24) ++ ++#define LOONGARCH_CPUCFG19 0x13 ++#define CPUCFG19_L2_WAYS_M (0xf << 0) ++#define CPUCFG19_L2_SETS_M (8 << 16) ++#define CPUCFG19_L2_SIZE_M (6 << 24) ++ ++#define LOONGARCH_CPUCFG20 0x14 ++#define CPUCFG20_L3_WAYS_M (0xf << 0) ++#define CPUCFG20_L3_SETS_M (0xe << 16) ++#define CPUCFG20_L3_SIZE_M (0x6 << 24) ++ ++#define LOONGARCH_PAGE_HUGE 0x40 ++#define LOONGARCH_HUGE_GLOBAL 0x1000 ++#define LOONGARCH_HUGE_GLOBAL_SH 12 ++ ++/* All CSR register ++ * ++ * default value in target/loongarch/cpu.c ++ * reset function in target/loongarch/translate.c:cpu_state_reset() ++ * ++ * This macro will be used only twice. ++ * > In target/loongarch/cpu.h:CPULOONGARCHState ++ * > In target/loongarch/internal.h:loongarch_def_t ++ * ++ * helper_function to rd/wr: ++ * > declare in target/loongarch/helper.h ++ * > realize in target/loongarch/op_helper.c ++ * ++ * during translate: ++ * > gen_csr_rdl() ++ * > gen_csr_wrl() ++ * > gen_csr_rdq() ++ * > gen_csr_wrq() ++ */ ++#define CPU_LOONGARCH_CSR \ ++ uint64_t CSR_CRMD; \ ++ uint64_t CSR_PRMD; \ ++ uint64_t CSR_EUEN; \ ++ uint64_t CSR_MISC; \ ++ uint64_t CSR_ECFG; \ ++ uint64_t CSR_ESTAT; \ ++ uint64_t CSR_ERA; \ ++ uint64_t CSR_BADV; \ ++ uint64_t CSR_BADI; \ ++ uint64_t CSR_EEPN; \ ++ uint64_t CSR_TLBIDX; \ ++ uint64_t CSR_TLBEHI; \ ++ uint64_t CSR_TLBELO0; \ ++ uint64_t CSR_TLBELO1; \ ++ uint64_t CSR_TLBWIRED; \ ++ uint64_t CSR_GTLBC; \ ++ uint64_t CSR_TRGP; \ ++ uint64_t CSR_ASID; \ ++ uint64_t CSR_PGDL; \ ++ uint64_t CSR_PGDH; \ ++ uint64_t CSR_PGD; \ ++ uint64_t CSR_PWCTL0; \ ++ uint64_t CSR_PWCTL1; \ ++ uint64_t CSR_STLBPGSIZE; \ ++ uint64_t CSR_RVACFG; \ ++ uint64_t CSR_CPUID; \ ++ uint64_t CSR_PRCFG1; \ ++ uint64_t CSR_PRCFG2; \ ++ uint64_t CSR_PRCFG3; \ ++ uint64_t CSR_KS0; \ ++ uint64_t CSR_KS1; \ ++ uint64_t CSR_KS2; \ ++ uint64_t CSR_KS3; \ ++ uint64_t CSR_KS4; \ ++ uint64_t CSR_KS5; \ ++ uint64_t CSR_KS6; \ ++ uint64_t CSR_KS7; \ ++ uint64_t CSR_KS8; \ ++ uint64_t CSR_TMID; \ ++ uint64_t CSR_TCFG; \ ++ uint64_t CSR_TVAL; \ ++ uint64_t CSR_CNTC; \ ++ uint64_t CSR_TINTCLR; \ ++ uint64_t CSR_GSTAT; \ ++ uint64_t CSR_GCFG; \ ++ uint64_t CSR_GINTC; \ ++ uint64_t CSR_GCNTC; \ ++ uint64_t CSR_LLBCTL; \ ++ uint64_t CSR_IMPCTL1; \ ++ uint64_t CSR_IMPCTL2; \ ++ uint64_t CSR_GNMI; \ ++ uint64_t CSR_TLBRENT; \ ++ uint64_t CSR_TLBRBADV; \ ++ uint64_t CSR_TLBRERA; \ ++ uint64_t CSR_TLBRSAVE; \ ++ uint64_t CSR_TLBRELO0; \ ++ uint64_t CSR_TLBRELO1; \ ++ uint64_t CSR_TLBREHI; \ ++ uint64_t CSR_TLBRPRMD; \ ++ uint64_t CSR_ERRCTL; \ ++ uint64_t CSR_ERRINFO; \ ++ uint64_t CSR_ERRINFO1; \ ++ uint64_t CSR_ERRENT; \ ++ uint64_t CSR_ERRERA; \ ++ uint64_t CSR_ERRSAVE; \ ++ uint64_t CSR_CTAG; \ ++ uint64_t CSR_DMWIN0; \ ++ uint64_t CSR_DMWIN1; \ ++ uint64_t CSR_DMWIN2; \ ++ uint64_t CSR_DMWIN3; \ ++ uint64_t CSR_PERFCTRL0; \ ++ uint64_t CSR_PERFCNTR0; \ ++ uint64_t CSR_PERFCTRL1; \ ++ uint64_t CSR_PERFCNTR1; \ ++ uint64_t CSR_PERFCTRL2; \ ++ uint64_t CSR_PERFCNTR2; \ ++ uint64_t CSR_PERFCTRL3; \ ++ uint64_t CSR_PERFCNTR3; \ ++ uint64_t CSR_MWPC; \ ++ uint64_t CSR_MWPS; \ ++ uint64_t CSR_DB0ADDR; \ ++ uint64_t CSR_DB0MASK; \ ++ uint64_t CSR_DB0CTL; \ ++ uint64_t CSR_DB0ASID; \ ++ uint64_t CSR_DB1ADDR; \ ++ uint64_t CSR_DB1MASK; \ ++ uint64_t CSR_DB1CTL; \ ++ uint64_t CSR_DB1ASID; \ ++ uint64_t CSR_DB2ADDR; \ ++ uint64_t CSR_DB2MASK; \ ++ uint64_t CSR_DB2CTL; \ ++ uint64_t CSR_DB2ASID; \ ++ uint64_t CSR_DB3ADDR; \ ++ uint64_t CSR_DB3MASK; \ ++ uint64_t CSR_DB3CTL; \ ++ uint64_t CSR_DB3ASID; \ ++ uint64_t CSR_FWPC; \ ++ uint64_t CSR_FWPS; \ ++ uint64_t CSR_IB0ADDR; \ ++ uint64_t CSR_IB0MASK; \ ++ uint64_t CSR_IB0CTL; \ ++ uint64_t CSR_IB0ASID; \ ++ uint64_t CSR_IB1ADDR; \ ++ uint64_t CSR_IB1MASK; \ ++ uint64_t CSR_IB1CTL; \ ++ uint64_t CSR_IB1ASID; \ ++ uint64_t CSR_IB2ADDR; \ ++ uint64_t CSR_IB2MASK; \ ++ uint64_t CSR_IB2CTL; \ ++ uint64_t CSR_IB2ASID; \ ++ uint64_t CSR_IB3ADDR; \ ++ uint64_t CSR_IB3MASK; \ ++ uint64_t CSR_IB3CTL; \ ++ uint64_t CSR_IB3ASID; \ ++ uint64_t CSR_IB4ADDR; \ ++ uint64_t CSR_IB4MASK; \ ++ uint64_t CSR_IB4CTL; \ ++ uint64_t CSR_IB4ASID; \ ++ uint64_t CSR_IB5ADDR; \ ++ uint64_t CSR_IB5MASK; \ ++ uint64_t CSR_IB5CTL; \ ++ uint64_t CSR_IB5ASID; \ ++ uint64_t CSR_IB6ADDR; \ ++ uint64_t CSR_IB6MASK; \ ++ uint64_t CSR_IB6CTL; \ ++ uint64_t CSR_IB6ASID; \ ++ uint64_t CSR_IB7ADDR; \ ++ uint64_t CSR_IB7MASK; \ ++ uint64_t CSR_IB7CTL; \ ++ uint64_t CSR_IB7ASID; \ ++ uint64_t CSR_DEBUG; \ ++ uint64_t CSR_DERA; \ ++ uint64_t CSR_DESAVE; \ ++ ++#define LOONGARCH_CSR_32(_R, _S) \ ++ (KVM_REG_LOONGARCH_CSR | KVM_REG_SIZE_U32 | (8 * (_R) + (_S))) ++ ++#define LOONGARCH_CSR_64(_R, _S) \ ++ (KVM_REG_LOONGARCH_CSR | KVM_REG_SIZE_U64 | (8 * (_R) + (_S))) ++ ++#define KVM_IOC_CSRID(id) LOONGARCH_CSR_64(id, 0) ++ ++#endif +diff --git a/target/loongarch64/cpu-param.h b/target/loongarch64/cpu-param.h +new file mode 100644 +index 0000000000..24ca458af0 +--- /dev/null ++++ b/target/loongarch64/cpu-param.h +@@ -0,0 +1,30 @@ ++#ifndef CPU_PARAM_H ++#define CPU_PARAM_H ++ ++/* If we want to use host float regs... */ ++/* #define USE_HOST_FLOAT_REGS */ ++ ++/* Real pages are variable size... */ ++#define TARGET_PAGE_BITS 14 ++ ++#define LOONGARCH_TLB_MAX 2112 ++ ++#define TARGET_LONG_BITS 64 ++#define TARGET_PHYS_ADDR_SPACE_BITS 48 ++#define TARGET_VIRT_ADDR_SPACE_BITS 48 ++ ++/* ++ * bit definitions for insn_flags (ISAs/ASEs flags) ++ * ------------------------------------------------ ++ */ ++#define ISA_LARCH32 0x00000001ULL ++#define ISA_LARCH64 0x00000002ULL ++#define INSN_LOONGARCH 0x00010000ULL ++ ++#define CPU_LARCH32 (ISA_LARCH32) ++#define CPU_LARCH64 (ISA_LARCH32 | ISA_LARCH64) ++ ++#define NB_MMU_MODES 4 ++ ++#endif /* QEMU_LOONGARCH_DEFS_H */ ++ +diff --git a/target/loongarch64/cpu-qom.h b/target/loongarch64/cpu-qom.h +new file mode 100644 +index 0000000000..ee9c1de571 +--- /dev/null ++++ b/target/loongarch64/cpu-qom.h +@@ -0,0 +1,54 @@ ++/* ++ * QEMU LOONGARCH 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 ++ * ++ */ ++#ifndef QEMU_LOONGARCH_CPU_QOM_H ++#define QEMU_LOONGARCH_CPU_QOM_H ++ ++#include "hw/core/cpu.h" ++ ++#define TYPE_LOONGARCH_CPU "loongarch-cpu" ++ ++#define LOONGARCH_CPU_CLASS(klass) \ ++ OBJECT_CLASS_CHECK(LOONGARCHCPUClass, (klass), TYPE_LOONGARCH_CPU) ++#define LOONGARCH_CPU(obj) \ ++ OBJECT_CHECK(LOONGARCHCPU, (obj), TYPE_LOONGARCH_CPU) ++#define LOONGARCH_CPU_GET_CLASS(obj) \ ++ OBJECT_GET_CLASS(LOONGARCHCPUClass, (obj), TYPE_LOONGARCH_CPU) ++ ++/** ++ * LOONGARCHCPUClass: ++ * @parent_realize: The parent class' realize handler. ++ * @parent_reset: The parent class' reset handler. ++ * ++ * A LOONGARCH CPU model. ++ */ ++typedef struct LOONGARCHCPUClass { ++ /*< private >*/ ++ CPUClass parent_class; ++ /*< public >*/ ++ ++ DeviceRealize parent_realize; ++ DeviceUnrealize parent_unrealize; ++ DeviceReset parent_reset; ++ const struct loongarch_def_t *cpu_def; ++} LOONGARCHCPUClass; ++ ++typedef struct LOONGARCHCPU LOONGARCHCPU; ++ ++#endif +diff --git a/target/loongarch64/cpu.c b/target/loongarch64/cpu.c +new file mode 100644 +index 0000000000..a4535d34a6 +--- /dev/null ++++ b/target/loongarch64/cpu.c +@@ -0,0 +1,576 @@ ++/* ++ * QEMU LOONGARCH 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 ++ * ++ */ ++ ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include "qapi/visitor.h" ++#include "cpu.h" ++#include "internal.h" ++#include "kvm_larch.h" ++#include "qemu-common.h" ++#include "hw/qdev-properties.h" ++#include "sysemu/kvm.h" ++#include "exec/exec-all.h" ++#include "sysemu/arch_init.h" ++#include "cpu-csr.h" ++#include "qemu/qemu-print.h" ++#include "qapi/qapi-commands-machine-target.h" ++#ifdef CONFIG_TCG ++#include "hw/core/tcg-cpu-ops.h" ++#endif /* CONFIG_TCG */ ++ ++#define LOONGARCH_CONFIG1 \ ++((0x8 << CSR_CONF1_KSNUM_SHIFT) | (0x2f << CSR_CONF1_TMRBITS_SHIFT) | \ ++ (0x7 << CSR_CONF1_VSMAX_SHIFT)) ++ ++#define LOONGARCH_CONFIG3 \ ++((0x2 << CSR_CONF3_TLBORG_SHIFT) | (0x3f << CSR_CONF3_MTLBSIZE_SHIFT) | \ ++ (0x7 << CSR_CONF3_STLBWAYS_SHIFT) | (0x8 << CSR_CONF3_STLBIDX_SHIFT)) ++ ++/*****************************************************************************/ ++/* LOONGARCH CPU definitions */ ++const loongarch_def_t loongarch_defs[] = { ++ { ++ .name = "Loongson-3A5000", ++ ++ /* for LoongISA CSR */ ++ .CSR_PRCFG1 = LOONGARCH_CONFIG1, ++ .CSR_PRCFG2 = 0x3ffff000, ++ .CSR_PRCFG3 = LOONGARCH_CONFIG3, ++ .CSR_CRMD = (0 << CSR_CRMD_PLV_SHIFT) | (0 << CSR_CRMD_IE_SHIFT) | ++ (1 << CSR_CRMD_DA_SHIFT) | (0 << CSR_CRMD_PG_SHIFT) | ++ (1 << CSR_CRMD_DACF_SHIFT) | (1 << CSR_CRMD_DACM_SHIFT) , ++ .CSR_ECFG = 0x7 << 16, ++ .CSR_STLBPGSIZE = 0xe, ++ .CSR_RVACFG = 0x0, ++ .CSR_ASID = 0xa0000, ++ .FCSR0 = 0x0, ++ .FCSR0_rw_bitmask = 0x1f1f03df, ++ .PABITS = 48, ++ .insn_flags = CPU_LARCH64 | INSN_LOONGARCH, ++ .mmu_type = MMU_TYPE_LS3A5K, ++ }, ++ { ++ .name = "host", ++ ++ /* for LoongISA CSR */ ++ .CSR_PRCFG1 = LOONGARCH_CONFIG1, ++ .CSR_PRCFG2 = 0x3ffff000, ++ .CSR_PRCFG3 = LOONGARCH_CONFIG3, ++ .CSR_CRMD = (0 << CSR_CRMD_PLV_SHIFT) | (0 << CSR_CRMD_IE_SHIFT) | ++ (1 << CSR_CRMD_DA_SHIFT) | (0 << CSR_CRMD_PG_SHIFT) | ++ (1 << CSR_CRMD_DACF_SHIFT) | (1 << CSR_CRMD_DACM_SHIFT) , ++ .CSR_ECFG = 0x7 << 16, ++ .CSR_STLBPGSIZE = 0xe, ++ .CSR_RVACFG = 0x0, ++ .FCSR0 = 0x0, ++ .FCSR0_rw_bitmask = 0x1f1f03df, ++ .PABITS = 48, ++ .insn_flags = CPU_LARCH64 | INSN_LOONGARCH, ++ .mmu_type = MMU_TYPE_LS3A5K, ++ }, ++}; ++const int loongarch_defs_number = ARRAY_SIZE(loongarch_defs); ++ ++void loongarch_cpu_list(void) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(loongarch_defs); i++) { ++ qemu_printf("LOONGARCH '%s'\n", ++ loongarch_defs[i].name); ++ } ++} ++ ++CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) ++{ ++ CpuDefinitionInfoList *cpu_list = NULL; ++ const loongarch_def_t *def; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(loongarch_defs); i++) { ++ CpuDefinitionInfoList *entry; ++ CpuDefinitionInfo *info; ++ ++ def = &loongarch_defs[i]; ++ info = g_malloc0(sizeof(*info)); ++ info->name = g_strdup(def->name); ++ ++ entry = g_malloc0(sizeof(*entry)); ++ entry->value = info; ++ entry->next = cpu_list; ++ cpu_list = entry; ++ } ++ ++ return cpu_list; ++} ++ ++static void loongarch_cpu_set_pc(CPUState *cs, vaddr value) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ ++ env->active_tc.PC = value & ~(target_ulong)1; ++} ++ ++static bool loongarch_cpu_has_work(CPUState *cs) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ bool has_work = false; ++ ++ /* It is implementation dependent if non-enabled ++ interrupts wake-up the CPU, however most of the implementations only ++ check for interrupts that can be taken. */ ++ if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && ++ cpu_loongarch_hw_interrupts_pending(env)) { ++ has_work = true; ++ } ++ ++ return has_work; ++} ++ ++const char * const regnames[] = { ++ "r0", "ra", "tp", "sp", "a0", "a1", "a2", "a3", ++ "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", ++ "t4", "t5", "t6", "t7", "t8", "x0", "fp", "s0", ++ "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", ++}; ++ ++const char * const fregnames[] = { ++ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", ++ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", ++ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", ++ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", ++}; ++ ++static void fpu_dump_state(CPULOONGARCHState *env, FILE *f, ++ fprintf_function fpu_fprintf, int flags) ++{ ++ int i; ++ int is_fpu64 = 1; ++ ++#define printfpr(fp) \ ++ do { \ ++ if (is_fpu64) \ ++ fpu_fprintf(f, "w:%08x d:%016" PRIx64 \ ++ " fd:%13g fs:%13g psu: %13g\n", \ ++ (fp)->w[FP_ENDIAN_IDX], (fp)->d, \ ++ (double)(fp)->fd, \ ++ (double)(fp)->fs[FP_ENDIAN_IDX], \ ++ (double)(fp)->fs[!FP_ENDIAN_IDX]); \ ++ else { \ ++ fpr_t tmp; \ ++ tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \ ++ tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \ ++ fpu_fprintf(f, "w:%08x d:%016" PRIx64 \ ++ " fd:%13g fs:%13g psu:%13g\n", \ ++ tmp.w[FP_ENDIAN_IDX], tmp.d, \ ++ (double)tmp.fd, \ ++ (double)tmp.fs[FP_ENDIAN_IDX], \ ++ (double)tmp.fs[!FP_ENDIAN_IDX]); \ ++ } \ ++ } while (0) ++ ++ ++ fpu_fprintf(f, "FCSR0 0x%08x SR.FR %d fp_status 0x%02x\n", ++ env->active_fpu.fcsr0, is_fpu64, ++ get_float_exception_flags(&env->active_fpu.fp_status)); ++ for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) { ++ fpu_fprintf(f, "%3s: ", fregnames[i]); ++ printfpr(&env->active_fpu.fpr[i]); ++ } ++ ++#undef printfpr ++} ++ ++void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ int i; ++ ++ qemu_fprintf(f, "pc:\t %lx\n", env->active_tc.PC); ++ for (i = 0; i < 32; i++) { ++ if ((i & 3) == 0) { ++ qemu_fprintf(f, "GPR%02d:", i); ++ } ++ qemu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], ++ env->active_tc.gpr[i]); ++ if ((i & 3) == 3) { ++ qemu_fprintf(f, "\n"); ++ } ++ } ++ qemu_fprintf(f, "EUEN 0x%lx\n", env->CSR_EUEN); ++ qemu_fprintf(f, "ESTAT 0x%lx\n", env->CSR_ESTAT); ++ qemu_fprintf(f, "ERA 0x%lx\n", env->CSR_ERA); ++ qemu_fprintf(f, "CRMD 0x%lx\n", env->CSR_CRMD); ++ qemu_fprintf(f, "PRMD 0x%lx\n", env->CSR_PRMD); ++ qemu_fprintf(f, "BadVAddr 0x%lx\n", env->CSR_BADV); ++ qemu_fprintf(f, "TLB refill ERA 0x%lx\n", env->CSR_TLBRERA); ++ qemu_fprintf(f, "TLB refill BadV 0x%lx\n", env->CSR_TLBRBADV); ++ qemu_fprintf(f, "EEPN 0x%lx\n", env->CSR_EEPN); ++ qemu_fprintf(f, "BadInstr 0x%lx\n", env->CSR_BADI); ++ qemu_fprintf(f, "PRCFG1 0x%lx\nPRCFG2 0x%lx\nPRCFG3 0x%lx\n", ++ env->CSR_PRCFG1, env->CSR_PRCFG3, env->CSR_PRCFG3); ++ if ((flags & CPU_DUMP_FPU) && (env->hflags & LARCH_HFLAG_FPU)) { ++ fpu_dump_state(env, f, qemu_fprintf, flags); ++ } ++} ++ ++void cpu_state_reset(CPULOONGARCHState *env) ++{ ++ LOONGARCHCPU *cpu = loongarch_env_get_cpu(env); ++ CPUState *cs = CPU(cpu); ++ ++ /* Reset registers to their default values */ ++ env->CSR_PRCFG1 = env->cpu_model->CSR_PRCFG1; ++ env->CSR_PRCFG2 = env->cpu_model->CSR_PRCFG2; ++ env->CSR_PRCFG3 = env->cpu_model->CSR_PRCFG3; ++ env->CSR_CRMD = env->cpu_model->CSR_CRMD; ++ env->CSR_ECFG = env->cpu_model->CSR_ECFG; ++ env->CSR_STLBPGSIZE = env->cpu_model->CSR_STLBPGSIZE; ++ env->CSR_RVACFG = env->cpu_model->CSR_RVACFG; ++ env->CSR_ASID = env->cpu_model->CSR_ASID; ++ ++ env->current_tc = 0; ++ env->active_fpu.fcsr0_rw_bitmask = env->cpu_model->FCSR0_rw_bitmask; ++ env->active_fpu.fcsr0 = env->cpu_model->FCSR0; ++ env->insn_flags = env->cpu_model->insn_flags; ++ ++#if !defined(CONFIG_USER_ONLY) ++ env->CSR_ERA = env->active_tc.PC; ++ env->active_tc.PC = env->exception_base; ++#ifdef CONFIG_TCG ++ env->tlb->tlb_in_use = env->tlb->nb_tlb; ++#endif ++ env->CSR_TLBWIRED = 0; ++ env->CSR_TMID = cs->cpu_index; ++ env->CSR_CPUID = (cs->cpu_index & 0x1ff); ++ env->CSR_EEPN |= (uint64_t)0x80000000; ++ env->CSR_TLBRENT |= (uint64_t)0x80000000; ++#endif ++ ++ /* Count register increments in debug mode, EJTAG version 1 */ ++ env->CSR_DEBUG = (1 << CSR_DEBUG_DINT) | (0x1 << CSR_DEBUG_DMVER); ++ ++ compute_hflags(env); ++ restore_fp_status(env); ++ cs->exception_index = EXCP_NONE; ++} ++ ++/* CPUClass::reset() */ ++static void loongarch_cpu_reset(DeviceState *dev) ++{ ++ CPUState *s = CPU(dev); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(s); ++ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(cpu); ++ CPULOONGARCHState *env = &cpu->env; ++ ++ mcc->parent_reset(dev); ++ ++ memset(env, 0, offsetof(CPULOONGARCHState, end_reset_fields)); ++ ++ cpu_state_reset(env); ++ ++#ifndef CONFIG_USER_ONLY ++ if (kvm_enabled()) { ++ kvm_loongarch_reset_vcpu(cpu); ++ } ++#endif ++} ++ ++static void loongarch_cpu_disas_set_info(CPUState *s, disassemble_info *info) ++{ ++ info->print_insn = print_insn_loongarch; ++} ++ ++static void fpu_init(CPULOONGARCHState *env, const loongarch_def_t *def) ++{ ++ memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu)); ++} ++ ++void cpu_loongarch_realize_env(CPULOONGARCHState *env) ++{ ++ env->exception_base = 0x1C000000; ++ ++#ifdef CONFIG_TCG ++#ifndef CONFIG_USER_ONLY ++ mmu_init(env, env->cpu_model); ++#endif ++#endif ++ fpu_init(env, env->cpu_model); ++} ++ ++static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp) ++{ ++ CPUState *cs = CPU(dev); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); ++ LOONGARCHCPUClass *mcc = LOONGARCH_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_loongarch_realize_env(&cpu->env); ++ ++ loongarch_cpu_register_gdb_regs_for_features(cs); ++ ++ cpu_reset(cs); ++ qemu_init_vcpu(cs); ++ ++ mcc->parent_realize(dev, errp); ++ cpu->hotplugged = 1; ++} ++ ++static void loongarch_cpu_unrealizefn(DeviceState *dev) ++{ ++ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(dev); ++ ++#ifndef CONFIG_USER_ONLY ++ cpu_remove_sync(CPU(dev)); ++#endif ++ ++ mcc->parent_unrealize(dev); ++} ++static void loongarch_cpu_initfn(Object *obj) ++{ ++ CPUState *cs = CPU(obj); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(obj); ++ CPULOONGARCHState *env = &cpu->env; ++ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(obj); ++ cpu_set_cpustate_pointers(cpu); ++ cs->env_ptr = env; ++ env->cpu_model = mcc->cpu_def; ++ cs->halted = 1; ++ cpu->dtb_compatible = "loongarch,Loongson-3A5000"; ++} ++ ++static char *loongarch_cpu_type_name(const char *cpu_model) ++{ ++ return g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"), cpu_model); ++} ++ ++static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model) ++{ ++ ObjectClass *oc; ++ char *typename; ++ ++ typename = loongarch_cpu_type_name(cpu_model); ++ oc = object_class_by_name(typename); ++ g_free(typename); ++ return oc; ++} ++ ++static int64_t loongarch_cpu_get_arch_id(CPUState *cs) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ ++ return cpu->id; ++} ++ ++static Property loongarch_cpu_properties[] = { ++ DEFINE_PROP_INT32("core-id", LOONGARCHCPU, core_id, -1), ++ DEFINE_PROP_INT32("id", LOONGARCHCPU, id, UNASSIGNED_CPU_ID), ++ DEFINE_PROP_INT32("node-id", LOONGARCHCPU, node_id, CPU_UNSET_NUMA_NODE_ID), ++ ++ DEFINE_PROP_END_OF_LIST() ++}; ++ ++#ifdef CONFIG_TCG ++static void loongarch_cpu_synchronize_from_tb(CPUState *cs,const TranslationBlock *tb) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ ++ env->active_tc.PC = tb->pc; ++ env->hflags &= ~LARCH_HFLAG_BMASK; ++ env->hflags |= tb->flags & LARCH_HFLAG_BMASK; ++} ++ ++static const struct TCGCPUOps loongarch_tcg_ops = { ++ .initialize = loongarch_tcg_init, ++ .synchronize_from_tb = loongarch_cpu_synchronize_from_tb, ++ ++ .tlb_fill = loongarch_cpu_tlb_fill, ++ .cpu_exec_interrupt = loongarch_cpu_exec_interrupt, ++ .do_interrupt = loongarch_cpu_do_interrupt, ++ ++#ifndef CONFIG_USER_ONLY ++ .do_unaligned_access = loongarch_cpu_do_unaligned_access, ++#endif /* !CONFIG_USER_ONLY */ ++}; ++#endif /* CONFIG_TCG */ ++ ++ ++#if !defined(CONFIG_USER_ONLY) ++static int get_physical_address(CPULOONGARCHState *env, hwaddr *physical, ++ int *prot, target_ulong real_address, ++ int rw, int access_type, int mmu_idx) ++{ ++ int user_mode = mmu_idx == LARCH_HFLAG_UM; ++ int kernel_mode = !user_mode; ++ unsigned plv, base_c, base_v, tmp; ++ ++ /* effective address (modified for KVM T&E kernel segments) */ ++ target_ulong address = real_address; ++ ++ /* Check PG */ ++ if (!(env->CSR_CRMD & CSR_CRMD_PG)) { ++ /* DA mode */ ++ *physical = address & 0xffffffffffffUL; ++ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ++ return TLBRET_MATCH; ++ } ++ ++ plv = kernel_mode | (user_mode << 3); ++ base_v = address >> CSR_DMW_BASE_SH; ++ /* Check direct map window 0 */ ++ base_c = env->CSR_DMWIN0 >> CSR_DMW_BASE_SH; ++ if ((plv & env->CSR_DMWIN0) && (base_c == base_v)) { ++ *physical = dmwin_va2pa(address); ++ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ++ return TLBRET_MATCH; ++ } ++ /* Check direct map window 1 */ ++ base_c = env->CSR_DMWIN1 >> CSR_DMW_BASE_SH; ++ if ((plv & env->CSR_DMWIN1) && (base_c == base_v)) { ++ *physical = dmwin_va2pa(address); ++ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ++ return TLBRET_MATCH; ++ } ++ /* Check valid extension */ ++ tmp = address >> 47; ++ if (!(tmp == 0 || tmp == 0x1ffff)) { ++ return TLBRET_BADADDR; ++ } ++ /* mapped address */ ++ return env->tlb->map_address(env, physical, prot, real_address, rw, ++ access_type); ++} ++ ++hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ hwaddr phys_addr; ++ int prot; ++ ++ if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT, ++ cpu_mmu_index(env, false)) != 0) { ++ return -1; ++ } ++ return phys_addr; ++} ++#endif ++ ++ ++#ifndef CONFIG_USER_ONLY ++#include "hw/core/sysemu-cpu-ops.h" ++ ++static const struct SysemuCPUOps loongarch_sysemu_ops = { ++ .write_elf64_note = loongarch_cpu_write_elf64_note, ++ .get_phys_page_debug = loongarch_cpu_get_phys_page_debug, ++ .legacy_vmsd = &vmstate_loongarch_cpu, ++}; ++#endif ++ ++ ++static void loongarch_cpu_class_init(ObjectClass *c, void *data) ++{ ++ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_CLASS(c); ++ CPUClass *cc = CPU_CLASS(c); ++ DeviceClass *dc = DEVICE_CLASS(c); ++ ++ device_class_set_props(dc, loongarch_cpu_properties); ++ device_class_set_parent_realize(dc, loongarch_cpu_realizefn, ++ &mcc->parent_realize); ++ ++ device_class_set_parent_unrealize(dc, loongarch_cpu_unrealizefn, ++ &mcc->parent_unrealize); ++ ++ device_class_set_parent_reset(dc, loongarch_cpu_reset, &mcc->parent_reset); ++ cc->get_arch_id = loongarch_cpu_get_arch_id; ++ ++ cc->class_by_name = loongarch_cpu_class_by_name; ++ cc->has_work = loongarch_cpu_has_work; ++ cc->dump_state = loongarch_cpu_dump_state; ++ cc->set_pc = loongarch_cpu_set_pc; ++ cc->gdb_read_register = loongarch_cpu_gdb_read_register; ++ cc->gdb_write_register = loongarch_cpu_gdb_write_register; ++ cc->disas_set_info = loongarch_cpu_disas_set_info; ++#ifndef CONFIG_USER_ONLY ++ cc->sysemu_ops = &loongarch_sysemu_ops; ++#endif /* !CONFIG_USER_ONLY */ ++ ++ cc->gdb_num_core_regs = 33; ++ cc->gdb_core_xml_file = "loongarch-base64.xml"; ++ cc->gdb_stop_before_watchpoint = true; ++ ++ dc->user_creatable = true; ++#ifdef CONFIG_TCG ++ cc->tcg_ops = &loongarch_tcg_ops; ++#endif /* CONFIG_TCG */ ++} ++ ++static const TypeInfo loongarch_cpu_type_info = { ++ .name = TYPE_LOONGARCH_CPU, ++ .parent = TYPE_CPU, ++ .instance_size = sizeof(LOONGARCHCPU), ++ .instance_init = loongarch_cpu_initfn, ++ .abstract = true, ++ .class_size = sizeof(LOONGARCHCPUClass), ++ .class_init = loongarch_cpu_class_init, ++}; ++ ++static void loongarch_cpu_cpudef_class_init(ObjectClass *oc, void *data) ++{ ++ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_CLASS(oc); ++ mcc->cpu_def = data; ++} ++ ++static void loongarch_register_cpudef_type(const struct loongarch_def_t *def) ++{ ++ char *typename = loongarch_cpu_type_name(def->name); ++ TypeInfo ti = { ++ .name = typename, ++ .parent = TYPE_LOONGARCH_CPU, ++ .class_init = loongarch_cpu_cpudef_class_init, ++ .class_data = (void *)def, ++ }; ++ ++ type_register(&ti); ++ g_free(typename); ++} ++ ++static void loongarch_cpu_register_types(void) ++{ ++ int i; ++ ++ type_register_static(&loongarch_cpu_type_info); ++ for (i = 0; i < loongarch_defs_number; i++) { ++ loongarch_register_cpudef_type(&loongarch_defs[i]); ++ } ++} ++ ++type_init(loongarch_cpu_register_types) +diff --git a/target/loongarch64/cpu.h b/target/loongarch64/cpu.h +new file mode 100644 +index 0000000000..10facb3b73 +--- /dev/null ++++ b/target/loongarch64/cpu.h +@@ -0,0 +1,326 @@ ++#ifndef LOONGARCH_CPU_H ++#define LOONGARCH_CPU_H ++ ++ ++#define CPUArchState struct CPULOONGARCHState ++ ++#include "qemu-common.h" ++#include "cpu-qom.h" ++#include "larch-defs.h" ++#include "exec/cpu-defs.h" ++#include "fpu/softfloat.h" ++#include "sysemu/sysemu.h" ++#include "cpu-csr.h" ++ ++#define TCG_GUEST_DEFAULT_MO (0) ++ ++struct CPULOONGARCHState; ++typedef LOONGARCHCPU ArchCPU; ++typedef struct CPULOONGARCHTLBContext CPULOONGARCHTLBContext; ++ ++#define LASX_REG_WIDTH (256) ++typedef union lasx_reg_t lasx_reg_t; ++union lasx_reg_t { ++ int64_t val64[LASX_REG_WIDTH / 64]; ++}; ++ ++typedef union fpr_t fpr_t; ++union fpr_t { ++ float64 fd; /* ieee double precision */ ++ float32 fs[2];/* ieee single precision */ ++ uint64_t d; /* binary double fixed-point */ ++ uint32_t w[2]; /* binary single fixed-point */ ++/* FPU/LASX register mapping is not tested on big-endian hosts. */ ++ lasx_reg_t lasx; /* vector data */ ++}; ++/* define FP_ENDIAN_IDX to access the same location ++ * in the fpr_t union regardless of the host endianness ++ */ ++#if defined(HOST_WORDS_BIGENDIAN) ++# define FP_ENDIAN_IDX 1 ++#else ++# define FP_ENDIAN_IDX 0 ++#endif ++ ++typedef struct CPULOONGARCHFPUContext { ++ /* Floating point registers */ ++ fpr_t fpr[32]; ++ float_status fp_status; ++ ++ bool cf[8]; ++ /* fcsr0 ++ * 31:29 |28:24 |23:21 |20:16 |15:10 |9:8 |7 |6 |5 |4:0 ++ * Cause Flags RM DAE TM Enables ++ */ ++ uint32_t fcsr0; ++ uint32_t fcsr0_rw_bitmask; ++ uint32_t vcsr16; ++} CPULOONGARCHFPUContext; ++ ++/* fp control and status register definition */ ++#define FCSR0_M1 0xdf /* DAE, TM and Enables */ ++#define FCSR0_M2 0x1f1f0000 /* Cause and Flags */ ++#define FCSR0_M3 0x300 /* Round Mode */ ++#define FCSR0_RM 8 /* Round Mode bit num on fcsr0 */ ++#define GET_FP_CAUSE(reg) (((reg) >> 24) & 0x1f) ++#define GET_FP_ENABLE(reg) (((reg) >> 0) & 0x1f) ++#define GET_FP_FLAGS(reg) (((reg) >> 16) & 0x1f) ++#define SET_FP_CAUSE(reg, v) do { (reg) = ((reg) & ~(0x1f << 24)) | \ ++ ((v & 0x1f) << 24); \ ++ } while (0) ++#define SET_FP_ENABLE(reg, v) do { (reg) = ((reg) & ~(0x1f << 0)) | \ ++ ((v & 0x1f) << 0); \ ++ } while (0) ++#define SET_FP_FLAGS(reg, v) do { (reg) = ((reg) & ~(0x1f << 16)) | \ ++ ((v & 0x1f) << 16); \ ++ } while (0) ++#define UPDATE_FP_FLAGS(reg, v) do { (reg) |= ((v & 0x1f) << 16); } while (0) ++#define FP_INEXACT 1 ++#define FP_UNDERFLOW 2 ++#define FP_OVERFLOW 4 ++#define FP_DIV0 8 ++#define FP_INVALID 16 ++ ++#define TARGET_INSN_START_EXTRA_WORDS 2 ++ ++typedef struct loongarch_def_t loongarch_def_t; ++ ++#define LOONGARCH_FPU_MAX 1 ++#define LOONGARCH_KSCRATCH_NUM 8 ++ ++typedef struct TCState TCState; ++struct TCState { ++ target_ulong gpr[32]; ++ target_ulong PC; ++}; ++ ++#define N_IRQS 14 ++#define IRQ_TIMER 11 ++#define IRQ_IPI 12 ++#define IRQ_UART 2 ++ ++typedef struct CPULOONGARCHState CPULOONGARCHState; ++struct CPULOONGARCHState { ++ TCState active_tc; ++ CPULOONGARCHFPUContext active_fpu; ++ ++ uint32_t current_tc; ++ uint64_t scr[4]; ++ uint32_t PABITS; ++ ++ /* LoongISA CSR register */ ++ CPU_LOONGARCH_CSR ++ uint64_t lladdr; ++ target_ulong llval; ++ uint64_t llval_wp; ++ uint32_t llnewval_wp; ++ ++ CPULOONGARCHFPUContext fpus[LOONGARCH_FPU_MAX]; ++ /* QEMU */ ++ int error_code; ++#define EXCP_TLB_NOMATCH 0x1 ++#define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */ ++ uint32_t hflags; /* CPU State */ ++ /* TMASK defines different execution modes */ ++#define LARCH_HFLAG_TMASK 0x5F5807FF ++ /* ++ * The KSU flags must be the lowest bits in hflags. The flag order ++ * must be the same as defined for CP0 Status. This allows to use ++ * the bits as the value of mmu_idx. ++ */ ++#define LARCH_HFLAG_KSU 0x00003 /* kernel/user mode mask */ ++#define LARCH_HFLAG_UM 0x00003 /* user mode flag */ ++#define LARCH_HFLAG_KM 0x00000 /* kernel mode flag */ ++#define LARCH_HFLAG_64 0x00008 /* 64-bit instructions enabled */ ++#define LARCH_HFLAG_FPU 0x00020 /* FPU enabled */ ++#define LARCH_HFLAG_AWRAP 0x00200 /* 32-bit compatibility address wrapping */ ++ /* If translation is interrupted between the branch instruction and ++ * the delay slot, record what type of branch it is so that we can ++ * resume translation properly. It might be possible to reduce ++ * this from three bits to two. */ ++#define LARCH_HFLAG_BMASK 0x03800 ++#define LARCH_HFLAG_B 0x00800 /* Unconditional branch */ ++#define LARCH_HFLAG_BC 0x01000 /* Conditional branch */ ++#define LARCH_HFLAG_BR 0x02000 /* branch to register (can't link TB) */ ++#define LARCH_HFLAG_LSX 0x1000000 ++#define LARCH_HFLAG_LASX 0x2000000 ++#define LARCH_HFLAG_LBT 0x40000000 ++ target_ulong btarget; /* Jump / branch target */ ++ target_ulong bcond; /* Branch condition (if needed) */ ++ ++ uint64_t insn_flags; /* Supported instruction set */ ++ int cpu_cfg[64]; ++ ++ /* Fields up to this point are cleared by a CPU reset */ ++ struct {} end_reset_fields; ++ ++ /* Fields from here on are preserved across CPU reset. */ ++#if !defined(CONFIG_USER_ONLY) ++ CPULOONGARCHTLBContext *tlb; ++#endif ++ ++ const loongarch_def_t *cpu_model; ++ void *irq[N_IRQS]; ++ QEMUTimer *timer; /* Internal timer */ ++ MemoryRegion *itc_tag; /* ITC Configuration Tags */ ++ target_ulong exception_base; /* ExceptionBase input to the core */ ++ struct { ++ uint64_t guest_addr; ++ } st; ++}; ++ ++ ++/* CPU can't have 0xFFFFFFFF APIC ID, use that value to distinguish ++ * that ID hasn't been set yet ++ */ ++#define UNASSIGNED_CPU_ID 0xFFFFFFFF ++ ++/** ++ * LOONGARCHCPU: ++ * @env: #CPULOONGARCHState ++ * ++ * A LOONGARCH CPU. ++ */ ++struct LOONGARCHCPU { ++ /*< private >*/ ++ CPUState parent_obj; ++ /*< public >*/ ++ CPUNegativeOffsetState neg; ++ CPULOONGARCHState env; ++ int32_t id; ++ int hotplugged; ++ uint8_t online_vcpus; ++ uint8_t is_migrate; ++ uint64_t counter_value; ++ uint32_t cpu_freq; ++ uint32_t count_ctl; ++ uint64_t pending_exceptions; ++ uint64_t pending_exceptions_clr; ++ uint64_t core_ext_ioisr[4]; ++ VMChangeStateEntry *cpuStateEntry; ++ int32_t node_id; /* NUMA node this CPU belongs to */ ++ int32_t core_id; ++ struct kvm_msrs *kvm_msr_buf; ++ /* 'compatible' string for this CPU for Linux device trees */ ++ const char *dtb_compatible; ++}; ++ ++static inline LOONGARCHCPU *loongarch_env_get_cpu(CPULOONGARCHState *env) ++{ ++ return container_of(env, LOONGARCHCPU, env); ++} ++ ++#define ENV_GET_CPU(e) CPU(loongarch_env_get_cpu(e)) ++ ++#define ENV_OFFSET offsetof(LOONGARCHCPU, env) ++ ++void loongarch_cpu_list(void); ++ ++#define cpu_signal_handler cpu_loongarch_signal_handler ++#define cpu_list loongarch_cpu_list ++ ++/* MMU modes definitions. We carefully match the indices with our ++ hflags layout. */ ++#define MMU_MODE0_SUFFIX _kernel ++#define MMU_MODE1_SUFFIX _super ++#define MMU_MODE2_SUFFIX _user ++#define MMU_MODE3_SUFFIX _error ++#define MMU_USER_IDX 3 ++ ++static inline int hflags_mmu_index(uint32_t hflags) ++{ ++ return hflags & LARCH_HFLAG_KSU; ++} ++ ++static inline int cpu_mmu_index(CPULOONGARCHState *env, bool ifetch) ++{ ++ return hflags_mmu_index(env->hflags); ++} ++ ++#include "exec/cpu-all.h" ++ ++/* Memory access type : ++ * may be needed for precise access rights control and precise exceptions. ++ */ ++enum { ++ /* 1 bit to define user level / supervisor access */ ++ ACCESS_USER = 0x00, ++ ACCESS_SUPER = 0x01, ++ /* 1 bit to indicate direction */ ++ ACCESS_STORE = 0x02, ++ /* Type of instruction that generated the access */ ++ ACCESS_CODE = 0x10, /* Code fetch access */ ++ ACCESS_INT = 0x20, /* Integer load/store access */ ++ ACCESS_FLOAT = 0x30, /* floating point load/store access */ ++}; ++ ++/* Exceptions */ ++enum { ++ EXCP_NONE = -1, ++ EXCP_RESET = 0, ++ EXCP_SRESET, ++ EXCP_DINT, ++ EXCP_NMI, ++ EXCP_EXT_INTERRUPT, /* 7 */ ++ EXCP_AdEL, ++ EXCP_AdES, ++ EXCP_TLBF, ++ EXCP_IBE, ++ EXCP_SYSCALL, ++ EXCP_BREAK, ++ EXCP_FPDIS, ++ EXCP_LSXDIS, ++ EXCP_LASXDIS, ++ EXCP_RI, ++ EXCP_OVERFLOW, ++ EXCP_TRAP, ++ EXCP_FPE, ++ EXCP_LTLBL, ++ EXCP_TLBL, ++ EXCP_TLBS, ++ EXCP_DBE, ++ EXCP_TLBXI, ++ EXCP_TLBRI, ++ EXCP_TLBPE, ++ EXCP_BTDIS, ++ ++ EXCP_LAST = EXCP_BTDIS, ++}; ++ ++/* ++ * This is an internally generated WAKE request line. ++ * It is driven by the CPU itself. Raised when the MT ++ * block wants to wake a VPE from an inactive state and ++ * cleared when VPE goes from active to inactive. ++ */ ++#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0 ++ ++int cpu_loongarch_signal_handler(int host_signum, void *pinfo, void *puc); ++ ++#define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU ++#define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX ++#define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU ++ ++/* helper.c */ ++target_ulong exception_resume_pc(CPULOONGARCHState *env); ++ ++/* gdbstub.c */ ++void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs); ++void mmu_init(CPULOONGARCHState *env, const loongarch_def_t *def); ++ ++static inline void cpu_get_tb_cpu_state(CPULOONGARCHState *env, target_ulong *pc, ++ target_ulong *cs_base, uint32_t *flags) ++{ ++ *pc = env->active_tc.PC; ++ *cs_base = 0; ++ *flags = env->hflags & (LARCH_HFLAG_TMASK | LARCH_HFLAG_BMASK); ++} ++ ++static inline bool cpu_refill_state(CPULOONGARCHState *env) ++{ ++ return env->CSR_TLBRERA & 0x1; ++} ++ ++extern const char * const regnames[]; ++extern const char * const fregnames[]; ++#endif /* LOONGARCH_CPU_H */ +diff --git a/target/loongarch64/csr_helper.c b/target/loongarch64/csr_helper.c +new file mode 100644 +index 0000000000..182e59e925 +--- /dev/null ++++ b/target/loongarch64/csr_helper.c +@@ -0,0 +1,704 @@ ++/* ++ * loongarch tlb emulation helpers for qemu. ++ * ++ * Copyright (c) 2020 - 2021 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++ ++#include "qemu/osdep.h" ++#include "qemu/main-loop.h" ++#include "cpu.h" ++#include "internal.h" ++#include "qemu/host-utils.h" ++#include "exec/helper-proto.h" ++#include "exec/exec-all.h" ++#include "exec/cpu_ldst.h" ++#include "sysemu/kvm.h" ++#include "hw/irq.h" ++#include "cpu-csr.h" ++#include "instmap.h" ++ ++#ifndef CONFIG_USER_ONLY ++target_ulong helper_csr_rdq(CPULOONGARCHState *env, uint64_t csr) ++{ ++ int64_t v; ++ ++#define CASE_CSR_RDQ(csr) \ ++ case LOONGARCH_CSR_ ## csr: \ ++ { \ ++ v = env->CSR_ ## csr; \ ++ break; \ ++ }; \ ++ ++ switch (csr) { ++ CASE_CSR_RDQ(CRMD) ++ CASE_CSR_RDQ(PRMD) ++ CASE_CSR_RDQ(EUEN) ++ CASE_CSR_RDQ(MISC) ++ CASE_CSR_RDQ(ECFG) ++ CASE_CSR_RDQ(ESTAT) ++ CASE_CSR_RDQ(ERA) ++ CASE_CSR_RDQ(BADV) ++ CASE_CSR_RDQ(BADI) ++ CASE_CSR_RDQ(EEPN) ++ CASE_CSR_RDQ(TLBIDX) ++ CASE_CSR_RDQ(TLBEHI) ++ CASE_CSR_RDQ(TLBELO0) ++ CASE_CSR_RDQ(TLBELO1) ++ CASE_CSR_RDQ(TLBWIRED) ++ CASE_CSR_RDQ(GTLBC) ++ CASE_CSR_RDQ(TRGP) ++ CASE_CSR_RDQ(ASID) ++ CASE_CSR_RDQ(PGDL) ++ CASE_CSR_RDQ(PGDH) ++ CASE_CSR_RDQ(PGD) ++ CASE_CSR_RDQ(PWCTL0) ++ CASE_CSR_RDQ(PWCTL1) ++ CASE_CSR_RDQ(STLBPGSIZE) ++ CASE_CSR_RDQ(RVACFG) ++ CASE_CSR_RDQ(CPUID) ++ CASE_CSR_RDQ(PRCFG1) ++ CASE_CSR_RDQ(PRCFG2) ++ CASE_CSR_RDQ(PRCFG3) ++ CASE_CSR_RDQ(KS0) ++ CASE_CSR_RDQ(KS1) ++ CASE_CSR_RDQ(KS2) ++ CASE_CSR_RDQ(KS3) ++ CASE_CSR_RDQ(KS4) ++ CASE_CSR_RDQ(KS5) ++ CASE_CSR_RDQ(KS6) ++ CASE_CSR_RDQ(KS7) ++ CASE_CSR_RDQ(KS8) ++ CASE_CSR_RDQ(TMID) ++ CASE_CSR_RDQ(TCFG) ++ case LOONGARCH_CSR_TVAL: ++ v = cpu_loongarch_get_stable_timer_ticks(env); ++ break; ++ CASE_CSR_RDQ(CNTC) ++ CASE_CSR_RDQ(TINTCLR) ++ CASE_CSR_RDQ(GSTAT) ++ CASE_CSR_RDQ(GCFG) ++ CASE_CSR_RDQ(GINTC) ++ CASE_CSR_RDQ(GCNTC) ++ CASE_CSR_RDQ(LLBCTL) ++ CASE_CSR_RDQ(IMPCTL1) ++ CASE_CSR_RDQ(IMPCTL2) ++ CASE_CSR_RDQ(GNMI) ++ CASE_CSR_RDQ(TLBRENT) ++ CASE_CSR_RDQ(TLBRBADV) ++ CASE_CSR_RDQ(TLBRERA) ++ CASE_CSR_RDQ(TLBRSAVE) ++ CASE_CSR_RDQ(TLBRELO0) ++ CASE_CSR_RDQ(TLBRELO1) ++ CASE_CSR_RDQ(TLBREHI) ++ CASE_CSR_RDQ(TLBRPRMD) ++ CASE_CSR_RDQ(ERRCTL) ++ CASE_CSR_RDQ(ERRINFO) ++ CASE_CSR_RDQ(ERRINFO1) ++ CASE_CSR_RDQ(ERRENT) ++ CASE_CSR_RDQ(ERRERA) ++ CASE_CSR_RDQ(ERRSAVE) ++ CASE_CSR_RDQ(CTAG) ++ CASE_CSR_RDQ(DMWIN0) ++ CASE_CSR_RDQ(DMWIN1) ++ CASE_CSR_RDQ(DMWIN2) ++ CASE_CSR_RDQ(DMWIN3) ++ CASE_CSR_RDQ(PERFCTRL0) ++ CASE_CSR_RDQ(PERFCNTR0) ++ CASE_CSR_RDQ(PERFCTRL1) ++ CASE_CSR_RDQ(PERFCNTR1) ++ CASE_CSR_RDQ(PERFCTRL2) ++ CASE_CSR_RDQ(PERFCNTR2) ++ CASE_CSR_RDQ(PERFCTRL3) ++ CASE_CSR_RDQ(PERFCNTR3) ++ /* debug */ ++ CASE_CSR_RDQ(MWPC) ++ CASE_CSR_RDQ(MWPS) ++ CASE_CSR_RDQ(DB0ADDR) ++ CASE_CSR_RDQ(DB0MASK) ++ CASE_CSR_RDQ(DB0CTL) ++ CASE_CSR_RDQ(DB0ASID) ++ CASE_CSR_RDQ(DB1ADDR) ++ CASE_CSR_RDQ(DB1MASK) ++ CASE_CSR_RDQ(DB1CTL) ++ CASE_CSR_RDQ(DB1ASID) ++ CASE_CSR_RDQ(DB2ADDR) ++ CASE_CSR_RDQ(DB2MASK) ++ CASE_CSR_RDQ(DB2CTL) ++ CASE_CSR_RDQ(DB2ASID) ++ CASE_CSR_RDQ(DB3ADDR) ++ CASE_CSR_RDQ(DB3MASK) ++ CASE_CSR_RDQ(DB3CTL) ++ CASE_CSR_RDQ(DB3ASID) ++ CASE_CSR_RDQ(FWPC) ++ CASE_CSR_RDQ(FWPS) ++ CASE_CSR_RDQ(IB0ADDR) ++ CASE_CSR_RDQ(IB0MASK) ++ CASE_CSR_RDQ(IB0CTL) ++ CASE_CSR_RDQ(IB0ASID) ++ CASE_CSR_RDQ(IB1ADDR) ++ CASE_CSR_RDQ(IB1MASK) ++ CASE_CSR_RDQ(IB1CTL) ++ CASE_CSR_RDQ(IB1ASID) ++ CASE_CSR_RDQ(IB2ADDR) ++ CASE_CSR_RDQ(IB2MASK) ++ CASE_CSR_RDQ(IB2CTL) ++ CASE_CSR_RDQ(IB2ASID) ++ CASE_CSR_RDQ(IB3ADDR) ++ CASE_CSR_RDQ(IB3MASK) ++ CASE_CSR_RDQ(IB3CTL) ++ CASE_CSR_RDQ(IB3ASID) ++ CASE_CSR_RDQ(IB4ADDR) ++ CASE_CSR_RDQ(IB4MASK) ++ CASE_CSR_RDQ(IB4CTL) ++ CASE_CSR_RDQ(IB4ASID) ++ CASE_CSR_RDQ(IB5ADDR) ++ CASE_CSR_RDQ(IB5MASK) ++ CASE_CSR_RDQ(IB5CTL) ++ CASE_CSR_RDQ(IB5ASID) ++ CASE_CSR_RDQ(IB6ADDR) ++ CASE_CSR_RDQ(IB6MASK) ++ CASE_CSR_RDQ(IB6CTL) ++ CASE_CSR_RDQ(IB6ASID) ++ CASE_CSR_RDQ(IB7ADDR) ++ CASE_CSR_RDQ(IB7MASK) ++ CASE_CSR_RDQ(IB7CTL) ++ CASE_CSR_RDQ(IB7ASID) ++ CASE_CSR_RDQ(DEBUG) ++ CASE_CSR_RDQ(DERA) ++ CASE_CSR_RDQ(DESAVE) ++ default : ++ assert(0); ++ } ++ ++#undef CASE_CSR_RDQ ++ compute_hflags(env); ++ return v; ++} ++ ++target_ulong helper_csr_wrq(CPULOONGARCHState *env, target_ulong val, ++ uint64_t csr) ++{ ++ int64_t old_v, v; ++ old_v = -1; ++ v = val; ++ ++#define CASE_CSR_WRQ(csr) \ ++ case LOONGARCH_CSR_ ## csr: \ ++ { \ ++ old_v = env->CSR_ ## csr; \ ++ env->CSR_ ## csr = v; \ ++ break; \ ++ }; \ ++ ++ switch (csr) { ++ CASE_CSR_WRQ(CRMD) ++ CASE_CSR_WRQ(PRMD) ++ CASE_CSR_WRQ(EUEN) ++ CASE_CSR_WRQ(MISC) ++ CASE_CSR_WRQ(ECFG) ++ CASE_CSR_WRQ(ESTAT) ++ CASE_CSR_WRQ(ERA) ++ CASE_CSR_WRQ(BADV) ++ CASE_CSR_WRQ(BADI) ++ CASE_CSR_WRQ(EEPN) ++ CASE_CSR_WRQ(TLBIDX) ++ CASE_CSR_WRQ(TLBEHI) ++ CASE_CSR_WRQ(TLBELO0) ++ CASE_CSR_WRQ(TLBELO1) ++ CASE_CSR_WRQ(TLBWIRED) ++ CASE_CSR_WRQ(GTLBC) ++ CASE_CSR_WRQ(TRGP) ++ CASE_CSR_WRQ(ASID) ++ CASE_CSR_WRQ(PGDL) ++ CASE_CSR_WRQ(PGDH) ++ CASE_CSR_WRQ(PGD) ++ CASE_CSR_WRQ(PWCTL0) ++ CASE_CSR_WRQ(PWCTL1) ++ CASE_CSR_WRQ(STLBPGSIZE) ++ CASE_CSR_WRQ(RVACFG) ++ CASE_CSR_WRQ(CPUID) ++ CASE_CSR_WRQ(PRCFG1) ++ CASE_CSR_WRQ(PRCFG2) ++ CASE_CSR_WRQ(PRCFG3) ++ CASE_CSR_WRQ(KS0) ++ CASE_CSR_WRQ(KS1) ++ CASE_CSR_WRQ(KS2) ++ CASE_CSR_WRQ(KS3) ++ CASE_CSR_WRQ(KS4) ++ CASE_CSR_WRQ(KS5) ++ CASE_CSR_WRQ(KS6) ++ CASE_CSR_WRQ(KS7) ++ CASE_CSR_WRQ(KS8) ++ CASE_CSR_WRQ(TMID) ++ case LOONGARCH_CSR_TCFG: ++ old_v = env->CSR_TCFG; ++ cpu_loongarch_store_stable_timer_config(env, v); ++ break; ++ CASE_CSR_WRQ(TVAL) ++ CASE_CSR_WRQ(CNTC) ++ case LOONGARCH_CSR_TINTCLR: ++ old_v = 0; ++ qemu_irq_lower(env->irq[IRQ_TIMER]); ++ break; ++ CASE_CSR_WRQ(GSTAT) ++ CASE_CSR_WRQ(GCFG) ++ CASE_CSR_WRQ(GINTC) ++ CASE_CSR_WRQ(GCNTC) ++ CASE_CSR_WRQ(LLBCTL) ++ CASE_CSR_WRQ(IMPCTL1) ++ case LOONGARCH_CSR_IMPCTL2: ++ if (v & CSR_IMPCTL2_MTLB) { ++ ls3a5k_flush_vtlb(env); ++ } ++ if (v & CSR_IMPCTL2_STLB) { ++ ls3a5k_flush_ftlb(env); ++ } ++ break; ++ CASE_CSR_WRQ(GNMI) ++ CASE_CSR_WRQ(TLBRENT) ++ CASE_CSR_WRQ(TLBRBADV) ++ CASE_CSR_WRQ(TLBRERA) ++ CASE_CSR_WRQ(TLBRSAVE) ++ CASE_CSR_WRQ(TLBRELO0) ++ CASE_CSR_WRQ(TLBRELO1) ++ CASE_CSR_WRQ(TLBREHI) ++ CASE_CSR_WRQ(TLBRPRMD) ++ CASE_CSR_WRQ(ERRCTL) ++ CASE_CSR_WRQ(ERRINFO) ++ CASE_CSR_WRQ(ERRINFO1) ++ CASE_CSR_WRQ(ERRENT) ++ CASE_CSR_WRQ(ERRERA) ++ CASE_CSR_WRQ(ERRSAVE) ++ CASE_CSR_WRQ(CTAG) ++ CASE_CSR_WRQ(DMWIN0) ++ CASE_CSR_WRQ(DMWIN1) ++ CASE_CSR_WRQ(DMWIN2) ++ CASE_CSR_WRQ(DMWIN3) ++ CASE_CSR_WRQ(PERFCTRL0) ++ CASE_CSR_WRQ(PERFCNTR0) ++ CASE_CSR_WRQ(PERFCTRL1) ++ CASE_CSR_WRQ(PERFCNTR1) ++ CASE_CSR_WRQ(PERFCTRL2) ++ CASE_CSR_WRQ(PERFCNTR2) ++ CASE_CSR_WRQ(PERFCTRL3) ++ CASE_CSR_WRQ(PERFCNTR3) ++ /* debug */ ++ CASE_CSR_WRQ(MWPC) ++ CASE_CSR_WRQ(MWPS) ++ CASE_CSR_WRQ(DB0ADDR) ++ CASE_CSR_WRQ(DB0MASK) ++ CASE_CSR_WRQ(DB0CTL) ++ CASE_CSR_WRQ(DB0ASID) ++ CASE_CSR_WRQ(DB1ADDR) ++ CASE_CSR_WRQ(DB1MASK) ++ CASE_CSR_WRQ(DB1CTL) ++ CASE_CSR_WRQ(DB1ASID) ++ CASE_CSR_WRQ(DB2ADDR) ++ CASE_CSR_WRQ(DB2MASK) ++ CASE_CSR_WRQ(DB2CTL) ++ CASE_CSR_WRQ(DB2ASID) ++ CASE_CSR_WRQ(DB3ADDR) ++ CASE_CSR_WRQ(DB3MASK) ++ CASE_CSR_WRQ(DB3CTL) ++ CASE_CSR_WRQ(DB3ASID) ++ CASE_CSR_WRQ(FWPC) ++ CASE_CSR_WRQ(FWPS) ++ CASE_CSR_WRQ(IB0ADDR) ++ CASE_CSR_WRQ(IB0MASK) ++ CASE_CSR_WRQ(IB0CTL) ++ CASE_CSR_WRQ(IB0ASID) ++ CASE_CSR_WRQ(IB1ADDR) ++ CASE_CSR_WRQ(IB1MASK) ++ CASE_CSR_WRQ(IB1CTL) ++ CASE_CSR_WRQ(IB1ASID) ++ CASE_CSR_WRQ(IB2ADDR) ++ CASE_CSR_WRQ(IB2MASK) ++ CASE_CSR_WRQ(IB2CTL) ++ CASE_CSR_WRQ(IB2ASID) ++ CASE_CSR_WRQ(IB3ADDR) ++ CASE_CSR_WRQ(IB3MASK) ++ CASE_CSR_WRQ(IB3CTL) ++ CASE_CSR_WRQ(IB3ASID) ++ CASE_CSR_WRQ(IB4ADDR) ++ CASE_CSR_WRQ(IB4MASK) ++ CASE_CSR_WRQ(IB4CTL) ++ CASE_CSR_WRQ(IB4ASID) ++ CASE_CSR_WRQ(IB5ADDR) ++ CASE_CSR_WRQ(IB5MASK) ++ CASE_CSR_WRQ(IB5CTL) ++ CASE_CSR_WRQ(IB5ASID) ++ CASE_CSR_WRQ(IB6ADDR) ++ CASE_CSR_WRQ(IB6MASK) ++ CASE_CSR_WRQ(IB6CTL) ++ CASE_CSR_WRQ(IB6ASID) ++ CASE_CSR_WRQ(IB7ADDR) ++ CASE_CSR_WRQ(IB7MASK) ++ CASE_CSR_WRQ(IB7CTL) ++ CASE_CSR_WRQ(IB7ASID) ++ CASE_CSR_WRQ(DEBUG) ++ CASE_CSR_WRQ(DERA) ++ CASE_CSR_WRQ(DESAVE) ++ default : ++ assert(0); ++ } ++ ++ if (csr == LOONGARCH_CSR_ASID) { ++ if (old_v != v) { ++ tlb_flush(CPU(loongarch_env_get_cpu(env))); ++ } ++ } ++ ++#undef CASE_CSR_WRQ ++ compute_hflags(env); ++ return old_v; ++} ++ ++target_ulong helper_csr_xchgq(CPULOONGARCHState *env, target_ulong val, ++ target_ulong mask, uint64_t csr) ++{ ++ target_ulong v, tmp; ++ v = val & mask; ++ ++#define CASE_CSR_XCHGQ(csr) \ ++ case LOONGARCH_CSR_ ## csr: \ ++ { \ ++ val = env->CSR_ ## csr; \ ++ env->CSR_ ## csr = (env->CSR_ ## csr) & (~mask); \ ++ env->CSR_ ## csr = (env->CSR_ ## csr) | v; \ ++ break; \ ++ }; \ ++ ++ switch (csr) { ++ CASE_CSR_XCHGQ(CRMD) ++ CASE_CSR_XCHGQ(PRMD) ++ CASE_CSR_XCHGQ(EUEN) ++ CASE_CSR_XCHGQ(MISC) ++ CASE_CSR_XCHGQ(ECFG) ++ case LOONGARCH_CSR_ESTAT: ++ val = env->CSR_ESTAT; ++ qatomic_and(&env->CSR_ESTAT, ~mask); ++ qatomic_or(&env->CSR_ESTAT, v); ++ break; ++ CASE_CSR_XCHGQ(ERA) ++ CASE_CSR_XCHGQ(BADV) ++ CASE_CSR_XCHGQ(BADI) ++ CASE_CSR_XCHGQ(EEPN) ++ CASE_CSR_XCHGQ(TLBIDX) ++ CASE_CSR_XCHGQ(TLBEHI) ++ CASE_CSR_XCHGQ(TLBELO0) ++ CASE_CSR_XCHGQ(TLBELO1) ++ CASE_CSR_XCHGQ(TLBWIRED) ++ CASE_CSR_XCHGQ(GTLBC) ++ CASE_CSR_XCHGQ(TRGP) ++ CASE_CSR_XCHGQ(ASID) ++ CASE_CSR_XCHGQ(PGDL) ++ CASE_CSR_XCHGQ(PGDH) ++ CASE_CSR_XCHGQ(PGD) ++ CASE_CSR_XCHGQ(PWCTL0) ++ CASE_CSR_XCHGQ(PWCTL1) ++ CASE_CSR_XCHGQ(STLBPGSIZE) ++ CASE_CSR_XCHGQ(RVACFG) ++ CASE_CSR_XCHGQ(CPUID) ++ CASE_CSR_XCHGQ(PRCFG1) ++ CASE_CSR_XCHGQ(PRCFG2) ++ CASE_CSR_XCHGQ(PRCFG3) ++ CASE_CSR_XCHGQ(KS0) ++ CASE_CSR_XCHGQ(KS1) ++ CASE_CSR_XCHGQ(KS2) ++ CASE_CSR_XCHGQ(KS3) ++ CASE_CSR_XCHGQ(KS4) ++ CASE_CSR_XCHGQ(KS5) ++ CASE_CSR_XCHGQ(KS6) ++ CASE_CSR_XCHGQ(KS7) ++ CASE_CSR_XCHGQ(KS8) ++ CASE_CSR_XCHGQ(TMID) ++ case LOONGARCH_CSR_TCFG: ++ val = env->CSR_TCFG; ++ tmp = val & ~mask; ++ tmp |= v; ++ cpu_loongarch_store_stable_timer_config(env, tmp); ++ break; ++ CASE_CSR_XCHGQ(TVAL) ++ CASE_CSR_XCHGQ(CNTC) ++ CASE_CSR_XCHGQ(TINTCLR) ++ CASE_CSR_XCHGQ(GSTAT) ++ CASE_CSR_XCHGQ(GCFG) ++ CASE_CSR_XCHGQ(GINTC) ++ CASE_CSR_XCHGQ(GCNTC) ++ CASE_CSR_XCHGQ(LLBCTL) ++ CASE_CSR_XCHGQ(IMPCTL1) ++ CASE_CSR_XCHGQ(IMPCTL2) ++ CASE_CSR_XCHGQ(GNMI) ++ CASE_CSR_XCHGQ(TLBRENT) ++ CASE_CSR_XCHGQ(TLBRBADV) ++ CASE_CSR_XCHGQ(TLBRERA) ++ CASE_CSR_XCHGQ(TLBRSAVE) ++ CASE_CSR_XCHGQ(TLBRELO0) ++ CASE_CSR_XCHGQ(TLBRELO1) ++ CASE_CSR_XCHGQ(TLBREHI) ++ CASE_CSR_XCHGQ(TLBRPRMD) ++ CASE_CSR_XCHGQ(ERRCTL) ++ CASE_CSR_XCHGQ(ERRINFO) ++ CASE_CSR_XCHGQ(ERRINFO1) ++ CASE_CSR_XCHGQ(ERRENT) ++ CASE_CSR_XCHGQ(ERRERA) ++ CASE_CSR_XCHGQ(ERRSAVE) ++ CASE_CSR_XCHGQ(CTAG) ++ CASE_CSR_XCHGQ(DMWIN0) ++ CASE_CSR_XCHGQ(DMWIN1) ++ CASE_CSR_XCHGQ(DMWIN2) ++ CASE_CSR_XCHGQ(DMWIN3) ++ CASE_CSR_XCHGQ(PERFCTRL0) ++ CASE_CSR_XCHGQ(PERFCNTR0) ++ CASE_CSR_XCHGQ(PERFCTRL1) ++ CASE_CSR_XCHGQ(PERFCNTR1) ++ CASE_CSR_XCHGQ(PERFCTRL2) ++ CASE_CSR_XCHGQ(PERFCNTR2) ++ CASE_CSR_XCHGQ(PERFCTRL3) ++ CASE_CSR_XCHGQ(PERFCNTR3) ++ /* debug */ ++ CASE_CSR_XCHGQ(MWPC) ++ CASE_CSR_XCHGQ(MWPS) ++ CASE_CSR_XCHGQ(DB0ADDR) ++ CASE_CSR_XCHGQ(DB0MASK) ++ CASE_CSR_XCHGQ(DB0CTL) ++ CASE_CSR_XCHGQ(DB0ASID) ++ CASE_CSR_XCHGQ(DB1ADDR) ++ CASE_CSR_XCHGQ(DB1MASK) ++ CASE_CSR_XCHGQ(DB1CTL) ++ CASE_CSR_XCHGQ(DB1ASID) ++ CASE_CSR_XCHGQ(DB2ADDR) ++ CASE_CSR_XCHGQ(DB2MASK) ++ CASE_CSR_XCHGQ(DB2CTL) ++ CASE_CSR_XCHGQ(DB2ASID) ++ CASE_CSR_XCHGQ(DB3ADDR) ++ CASE_CSR_XCHGQ(DB3MASK) ++ CASE_CSR_XCHGQ(DB3CTL) ++ CASE_CSR_XCHGQ(DB3ASID) ++ CASE_CSR_XCHGQ(FWPC) ++ CASE_CSR_XCHGQ(FWPS) ++ CASE_CSR_XCHGQ(IB0ADDR) ++ CASE_CSR_XCHGQ(IB0MASK) ++ CASE_CSR_XCHGQ(IB0CTL) ++ CASE_CSR_XCHGQ(IB0ASID) ++ CASE_CSR_XCHGQ(IB1ADDR) ++ CASE_CSR_XCHGQ(IB1MASK) ++ CASE_CSR_XCHGQ(IB1CTL) ++ CASE_CSR_XCHGQ(IB1ASID) ++ CASE_CSR_XCHGQ(IB2ADDR) ++ CASE_CSR_XCHGQ(IB2MASK) ++ CASE_CSR_XCHGQ(IB2CTL) ++ CASE_CSR_XCHGQ(IB2ASID) ++ CASE_CSR_XCHGQ(IB3ADDR) ++ CASE_CSR_XCHGQ(IB3MASK) ++ CASE_CSR_XCHGQ(IB3CTL) ++ CASE_CSR_XCHGQ(IB3ASID) ++ CASE_CSR_XCHGQ(IB4ADDR) ++ CASE_CSR_XCHGQ(IB4MASK) ++ CASE_CSR_XCHGQ(IB4CTL) ++ CASE_CSR_XCHGQ(IB4ASID) ++ CASE_CSR_XCHGQ(IB5ADDR) ++ CASE_CSR_XCHGQ(IB5MASK) ++ CASE_CSR_XCHGQ(IB5CTL) ++ CASE_CSR_XCHGQ(IB5ASID) ++ CASE_CSR_XCHGQ(IB6ADDR) ++ CASE_CSR_XCHGQ(IB6MASK) ++ CASE_CSR_XCHGQ(IB6CTL) ++ CASE_CSR_XCHGQ(IB6ASID) ++ CASE_CSR_XCHGQ(IB7ADDR) ++ CASE_CSR_XCHGQ(IB7MASK) ++ CASE_CSR_XCHGQ(IB7CTL) ++ CASE_CSR_XCHGQ(IB7ASID) ++ CASE_CSR_XCHGQ(DEBUG) ++ CASE_CSR_XCHGQ(DERA) ++ CASE_CSR_XCHGQ(DESAVE) ++ default : ++ assert(0); ++ } ++ ++#undef CASE_CSR_XCHGQ ++ compute_hflags(env); ++ return val; ++} ++ ++static target_ulong confbus_addr(CPULOONGARCHState *env, int cpuid, ++ target_ulong csr_addr) ++{ ++ target_ulong addr; ++ target_ulong node_addr; ++ int cores_per_node = ((0x60018 >> 3) & 0xff) + 1; ++ ++ switch (cores_per_node) { ++ case 4: ++ assert(cpuid < 64); ++ node_addr = ((target_ulong)(cpuid & 0x3c) << 42); ++ break; ++ case 8: ++ assert(cpuid < 128); ++ node_addr = ((target_ulong)(cpuid & 0x78) << 41) + ++ ((target_ulong)(cpuid & 0x4) << 14); ++ break; ++ case 16: ++ assert(cpuid < 256); ++ node_addr = ((target_ulong)(cpuid & 0xf0) << 40) + ++ ((target_ulong)(cpuid & 0xc) << 14); ++ break; ++ default: ++ assert(0); ++ break; ++ } ++ ++ /* ++ * per core address ++ *0x10xx => ipi ++ * 0x18xx => extioi isr ++ */ ++ if (((csr_addr & 0xff00) == 0x1000)) { ++ addr = (csr_addr & 0xff) + (target_ulong)(cpuid << 8); ++ addr = 0x800000001f000000UL + addr; ++ return addr; ++ } else if ((csr_addr & 0xff00) == 0x1800) { ++ addr = (csr_addr & 0xff) + ((target_ulong)(cpuid << 8)); ++ addr = 0x800000001f020000UL + addr; ++ return addr; ++ } else if ((csr_addr & 0xff00) >= 0x1400 && (csr_addr & 0xff00) < 0x1d00) { ++ addr = 0x800000001f010000UL + ((csr_addr & 0xfff) - 0x400); ++ return addr; ++ } else if (csr_addr == 0x408) { ++ addr = csr_addr; ++ } else { ++ addr = csr_addr + node_addr; ++ } ++ ++ addr = 0x800000001fe00000UL + addr; ++ return addr; ++} ++ ++void helper_iocsr(CPULOONGARCHState *env, target_ulong r_addr, ++ target_ulong r_val, uint32_t op) ++{ ++ target_ulong addr; ++ target_ulong val = env->active_tc.gpr[r_val]; ++ int mask; ++ ++ addr = confbus_addr(env, CPU(loongarch_env_get_cpu(env))->cpu_index, ++ env->active_tc.gpr[r_addr]); ++ ++ switch (env->active_tc.gpr[r_addr]) { ++ /* IPI send */ ++ case 0x1040: ++ if (op != OPC_LARCH_ST_W) { ++ return; ++ } ++ op = OPC_LARCH_ST_W; ++ break; ++ ++ /* Mail send */ ++ case 0x1048: ++ if (op != OPC_LARCH_ST_D) { ++ return; ++ } ++ op = OPC_LARCH_ST_D; ++ break; ++ ++ /* ANY send */ ++ case 0x1158: ++ if (op != OPC_LARCH_ST_D) { ++ return; ++ } ++ addr = confbus_addr(env, (val >> 16) & 0x3ff, val & 0xffff); ++ mask = (val >> 27) & 0xf; ++ val = (val >> 32); ++ switch (mask) { ++ case 0: ++ op = OPC_LARCH_ST_W; ++ break; ++ case 0x7: ++ op = OPC_LARCH_ST_B; ++ addr += 3; ++ val >>= 24; ++ break; ++ case 0xb: ++ op = OPC_LARCH_ST_B; ++ addr += 2; ++ val >>= 16; ++ break; ++ case 0xd: ++ op = OPC_LARCH_ST_B; ++ addr += 1; ++ val >>= 8; ++ break; ++ case 0xe: ++ op = OPC_LARCH_ST_B; ++ break; ++ case 0xc: ++ op = OPC_LARCH_ST_H; ++ break; ++ case 0x3: ++ op = OPC_LARCH_ST_H; ++ addr += 2; ++ val >>= 16; ++ break; ++ default: ++ qemu_log("Unsupported any_send mask0x%x\n", mask); ++ break; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ switch (op) { ++ case OPC_LARCH_LD_D: ++ env->active_tc.gpr[r_val] = cpu_ldq_data_ra(env, addr, ++ GETPC()); ++ break; ++ case OPC_LARCH_LD_W: ++ env->active_tc.gpr[r_val] = cpu_ldl_data_ra(env, addr, ++ GETPC()); ++ break; ++ case OPC_LARCH_LD_H: ++ assert(0); ++ break; ++ case OPC_LARCH_LD_B: ++ assert(0); ++ break; ++ case OPC_LARCH_ST_D: ++ cpu_stq_data_ra(env, addr, val, GETPC()); ++ break; ++ case OPC_LARCH_ST_W: ++ cpu_stl_data_ra(env, addr, val, GETPC()); ++ break; ++ case OPC_LARCH_ST_H: ++ cpu_stb_data_ra(env, addr, val, GETPC()); ++ break; ++ case OPC_LARCH_ST_B: ++ cpu_stb_data_ra(env, addr, val, GETPC()); ++ break; ++ default: ++ qemu_log("Unknown op 0x%x", op); ++ assert(0); ++ } ++} ++#endif ++ ++target_ulong helper_cpucfg(CPULOONGARCHState *env, target_ulong rj) ++{ ++ return 0; ++} ++ ++ +diff --git a/target/loongarch64/fpu.c b/target/loongarch64/fpu.c +new file mode 100644 +index 0000000000..795458205b +--- /dev/null ++++ b/target/loongarch64/fpu.c +@@ -0,0 +1,28 @@ ++/* ++ * loongarch float point emulation helpers for qemu. ++ * ++ * Copyright (c) 2020-2021 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#include "qemu/osdep.h" ++#include "fpu/softfloat.h" ++ ++/* convert loongarch rounding mode in fcsr0 to IEEE library */ ++unsigned int ieee_rm[] = { ++ float_round_nearest_even, ++ float_round_to_zero, ++ float_round_up, ++ float_round_down ++}; +diff --git a/target/loongarch64/fpu_helper.c b/target/loongarch64/fpu_helper.c +new file mode 100644 +index 0000000000..42d7f05ca2 +--- /dev/null ++++ b/target/loongarch64/fpu_helper.c +@@ -0,0 +1,952 @@ ++/* ++ * loongarch float point emulation helpers for qemu. ++ * ++ * Copyright (c) 2020-2021 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#include "qemu/osdep.h" ++#include "cpu.h" ++#include "internal.h" ++#include "qemu/host-utils.h" ++#include "exec/helper-proto.h" ++#include "exec/exec-all.h" ++#include "fpu/softfloat.h" ++ ++#define FP_TO_INT32_OVERFLOW 0x7fffffff ++#define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL ++ ++#define FLOAT_CLASS_SIGNALING_NAN 0x001 ++#define FLOAT_CLASS_QUIET_NAN 0x002 ++#define FLOAT_CLASS_NEGATIVE_INFINITY 0x004 ++#define FLOAT_CLASS_NEGATIVE_NORMAL 0x008 ++#define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010 ++#define FLOAT_CLASS_NEGATIVE_ZERO 0x020 ++#define FLOAT_CLASS_POSITIVE_INFINITY 0x040 ++#define FLOAT_CLASS_POSITIVE_NORMAL 0x080 ++#define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100 ++#define FLOAT_CLASS_POSITIVE_ZERO 0x200 ++ ++target_ulong helper_movfcsr2gr(CPULOONGARCHState *env, uint32_t reg) ++{ ++ target_ulong r = 0; ++ ++ switch (reg) { ++ case 0: ++ r = (uint32_t)env->active_fpu.fcsr0; ++ break; ++ case 1: ++ r = (env->active_fpu.fcsr0 & FCSR0_M1); ++ break; ++ case 2: ++ r = (env->active_fpu.fcsr0 & FCSR0_M2); ++ break; ++ case 3: ++ r = (env->active_fpu.fcsr0 & FCSR0_M3); ++ break; ++ case 16: ++ r = (uint32_t)env->active_fpu.vcsr16; ++ break; ++ default: ++ printf("%s: warning, fcsr '%d' not supported\n", __func__, reg); ++ assert(0); ++ break; ++ } ++ ++ return r; ++} ++ ++void helper_movgr2fcsr(CPULOONGARCHState *env, target_ulong arg1, ++ uint32_t fcsr, uint32_t rj) ++{ ++ switch (fcsr) { ++ case 0: ++ env->active_fpu.fcsr0 = arg1; ++ break; ++ case 1: ++ env->active_fpu.fcsr0 = (arg1 & FCSR0_M1) | ++ (env->active_fpu.fcsr0 & ~FCSR0_M1); ++ break; ++ case 2: ++ env->active_fpu.fcsr0 = (arg1 & FCSR0_M2) | ++ (env->active_fpu.fcsr0 & ~FCSR0_M2); ++ break; ++ case 3: ++ env->active_fpu.fcsr0 = (arg1 & FCSR0_M3) | ++ (env->active_fpu.fcsr0 & ~FCSR0_M3); ++ break; ++ case 16: ++ env->active_fpu.vcsr16 = arg1; ++ break; ++ default: ++ printf("%s: warning, fcsr '%d' not supported\n", __func__, fcsr); ++ assert(0); ++ break; ++ } ++ restore_fp_status(env); ++ set_float_exception_flags(0, &env->active_fpu.fp_status); ++} ++ ++void helper_movreg2cf(CPULOONGARCHState *env, uint32_t cd, target_ulong src) ++{ ++ env->active_fpu.cf[cd & 0x7] = src & 0x1; ++} ++ ++void helper_movreg2cf_i32(CPULOONGARCHState *env, uint32_t cd, uint32_t src) ++{ ++ env->active_fpu.cf[cd & 0x7] = src & 0x1; ++} ++ ++void helper_movreg2cf_i64(CPULOONGARCHState *env, uint32_t cd, uint64_t src) ++{ ++ env->active_fpu.cf[cd & 0x7] = src & 0x1; ++} ++ ++target_ulong helper_movcf2reg(CPULOONGARCHState *env, uint32_t cj) ++{ ++ return (target_ulong)env->active_fpu.cf[cj & 0x7]; ++} ++ ++int ieee_ex_to_loongarch(int xcpt) ++{ ++ int ret = 0; ++ if (xcpt) { ++ if (xcpt & float_flag_invalid) { ++ ret |= FP_INVALID; ++ } ++ if (xcpt & float_flag_overflow) { ++ ret |= FP_OVERFLOW; ++ } ++ if (xcpt & float_flag_underflow) { ++ ret |= FP_UNDERFLOW; ++ } ++ if (xcpt & float_flag_divbyzero) { ++ ret |= FP_DIV0; ++ } ++ if (xcpt & float_flag_inexact) { ++ ret |= FP_INEXACT; ++ } ++ } ++ return ret; ++} ++ ++static inline void update_fcsr0(CPULOONGARCHState *env, uintptr_t pc) ++{ ++ int tmp = ieee_ex_to_loongarch(get_float_exception_flags( ++ &env->active_fpu.fp_status)); ++ ++ SET_FP_CAUSE(env->active_fpu.fcsr0, tmp); ++ if (tmp) { ++ set_float_exception_flags(0, &env->active_fpu.fp_status); ++ ++ if (GET_FP_ENABLE(env->active_fpu.fcsr0) & tmp) { ++ do_raise_exception(env, EXCP_FPE, pc); ++ } else { ++ UPDATE_FP_FLAGS(env->active_fpu.fcsr0, tmp); ++ } ++ } ++} ++ ++/* unary operations, modifying fp status */ ++uint64_t helper_float_sqrt_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdt0; ++} ++ ++uint32_t helper_float_sqrt_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fst0; ++} ++ ++uint64_t helper_float_cvtd_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint64_t fdt2; ++ ++ fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdt2; ++} ++ ++uint64_t helper_float_cvtd_w(CPULOONGARCHState *env, uint32_t wt0) ++{ ++ uint64_t fdt2; ++ ++ fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdt2; ++} ++ ++uint64_t helper_float_cvtd_l(CPULOONGARCHState *env, uint64_t dt0) ++{ ++ uint64_t fdt2; ++ ++ fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdt2; ++} ++ ++uint64_t helper_float_cvt_l_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t dt2; ++ ++ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint64_t helper_float_cvt_l_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint64_t dt2; ++ ++ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint32_t helper_float_cvts_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint32_t fst2; ++ ++ fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fst2; ++} ++ ++uint32_t helper_float_cvts_w(CPULOONGARCHState *env, uint32_t wt0) ++{ ++ uint32_t fst2; ++ ++ fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fst2; ++} ++ ++uint32_t helper_float_cvts_l(CPULOONGARCHState *env, uint64_t dt0) ++{ ++ uint32_t fst2; ++ ++ fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fst2; ++} ++ ++uint32_t helper_float_cvt_w_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t wt2; ++ ++ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint32_t helper_float_cvt_w_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint32_t wt2; ++ ++ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint64_t helper_float_round_l_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t dt2; ++ ++ set_float_rounding_mode(float_round_nearest_even, ++ &env->active_fpu.fp_status); ++ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint64_t helper_float_round_l_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint64_t dt2; ++ ++ set_float_rounding_mode(float_round_nearest_even, ++ &env->active_fpu.fp_status); ++ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint32_t helper_float_round_w_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint32_t wt2; ++ ++ set_float_rounding_mode(float_round_nearest_even, ++ &env->active_fpu.fp_status); ++ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint32_t helper_float_round_w_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t wt2; ++ ++ set_float_rounding_mode(float_round_nearest_even, ++ &env->active_fpu.fp_status); ++ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint64_t helper_float_trunc_l_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t dt2; ++ ++ dt2 = float64_to_int64_round_to_zero(fdt0, ++ &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint64_t helper_float_trunc_l_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint64_t dt2; ++ ++ dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint32_t helper_float_trunc_w_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint32_t wt2; ++ ++ wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint32_t helper_float_trunc_w_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t wt2; ++ ++ wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint64_t helper_float_ceil_l_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t dt2; ++ ++ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); ++ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint64_t helper_float_ceil_l_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint64_t dt2; ++ ++ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); ++ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint32_t helper_float_ceil_w_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint32_t wt2; ++ ++ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); ++ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint32_t helper_float_ceil_w_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t wt2; ++ ++ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); ++ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint64_t helper_float_floor_l_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t dt2; ++ ++ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); ++ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint64_t helper_float_floor_l_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint64_t dt2; ++ ++ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); ++ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint32_t helper_float_floor_w_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint32_t wt2; ++ ++ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); ++ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint32_t helper_float_floor_w_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t wt2; ++ ++ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); ++ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++/* unary operations, not modifying fp status */ ++#define FLOAT_UNOP(name) \ ++uint64_t helper_float_ ## name ## _d(uint64_t fdt0) \ ++{ \ ++ return float64_ ## name(fdt0); \ ++} \ ++uint32_t helper_float_ ## name ## _s(uint32_t fst0) \ ++{ \ ++ return float32_ ## name(fst0); \ ++} ++ ++FLOAT_UNOP(abs) ++FLOAT_UNOP(chs) ++#undef FLOAT_UNOP ++ ++uint64_t helper_float_recip_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t fdt2; ++ ++ fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdt2; ++} ++ ++uint32_t helper_float_recip_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t fst2; ++ ++ fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fst2; ++} ++ ++uint64_t helper_float_rsqrt_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t fdt2; ++ ++ fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status); ++ fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdt2; ++} ++ ++uint32_t helper_float_rsqrt_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t fst2; ++ ++ fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status); ++ fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fst2; ++} ++ ++uint32_t helper_float_rint_s(CPULOONGARCHState *env, uint32_t fs) ++{ ++ uint32_t fdret; ++ ++ fdret = float32_round_to_int(fs, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdret; ++} ++ ++uint64_t helper_float_rint_d(CPULOONGARCHState *env, uint64_t fs) ++{ ++ uint64_t fdret; ++ ++ fdret = float64_round_to_int(fs, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdret; ++} ++ ++#define FLOAT_CLASS(name, bits) \ ++uint ## bits ## _t float_ ## name(uint ## bits ## _t arg, \ ++ float_status *status) \ ++{ \ ++ if (float ## bits ## _is_signaling_nan(arg, status)) { \ ++ return FLOAT_CLASS_SIGNALING_NAN; \ ++ } else if (float ## bits ## _is_quiet_nan(arg, status)) { \ ++ return FLOAT_CLASS_QUIET_NAN; \ ++ } else if (float ## bits ## _is_neg(arg)) { \ ++ if (float ## bits ## _is_infinity(arg)) { \ ++ return FLOAT_CLASS_NEGATIVE_INFINITY; \ ++ } else if (float ## bits ## _is_zero(arg)) { \ ++ return FLOAT_CLASS_NEGATIVE_ZERO; \ ++ } else if (float ## bits ## _is_zero_or_denormal(arg)) { \ ++ return FLOAT_CLASS_NEGATIVE_SUBNORMAL; \ ++ } else { \ ++ return FLOAT_CLASS_NEGATIVE_NORMAL; \ ++ } \ ++ } else { \ ++ if (float ## bits ## _is_infinity(arg)) { \ ++ return FLOAT_CLASS_POSITIVE_INFINITY; \ ++ } else if (float ## bits ## _is_zero(arg)) { \ ++ return FLOAT_CLASS_POSITIVE_ZERO; \ ++ } else if (float ## bits ## _is_zero_or_denormal(arg)) { \ ++ return FLOAT_CLASS_POSITIVE_SUBNORMAL; \ ++ } else { \ ++ return FLOAT_CLASS_POSITIVE_NORMAL; \ ++ } \ ++ } \ ++} \ ++ \ ++uint ## bits ## _t helper_float_ ## name(CPULOONGARCHState *env, \ ++ uint ## bits ## _t arg) \ ++{ \ ++ return float_ ## name(arg, &env->active_fpu.fp_status); \ ++} ++ ++FLOAT_CLASS(class_s, 32) ++FLOAT_CLASS(class_d, 64) ++#undef FLOAT_CLASS ++ ++/* binary operations */ ++#define FLOAT_BINOP(name) \ ++uint64_t helper_float_ ## name ## _d(CPULOONGARCHState *env, \ ++ uint64_t fdt0, uint64_t fdt1) \ ++{ \ ++ uint64_t dt2; \ ++ \ ++ dt2 = float64_ ## name(fdt0, fdt1, &env->active_fpu.fp_status);\ ++ update_fcsr0(env, GETPC()); \ ++ return dt2; \ ++} \ ++ \ ++uint32_t helper_float_ ## name ## _s(CPULOONGARCHState *env, \ ++ uint32_t fst0, uint32_t fst1) \ ++{ \ ++ uint32_t wt2; \ ++ \ ++ wt2 = float32_ ## name(fst0, fst1, &env->active_fpu.fp_status);\ ++ update_fcsr0(env, GETPC()); \ ++ return wt2; \ ++} ++ ++FLOAT_BINOP(add) ++FLOAT_BINOP(sub) ++FLOAT_BINOP(mul) ++FLOAT_BINOP(div) ++#undef FLOAT_BINOP ++ ++uint64_t helper_float_exp2_d(CPULOONGARCHState *env, ++ uint64_t fdt0, uint64_t fdt1) ++{ ++ uint64_t dt2; ++ int64_t n = (int64_t)fdt1; ++ ++ dt2 = float64_scalbn(fdt0, ++ n > 0x1000 ? 0x1000 : ++ n < -0x1000 ? -0x1000 : n, ++ &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint32_t helper_float_exp2_s(CPULOONGARCHState *env, ++ uint32_t fst0, uint32_t fst1) ++{ ++ uint32_t wt2; ++ int32_t n = (int32_t)fst1; ++ ++ wt2 = float32_scalbn(fst0, ++ n > 0x200 ? 0x200 : ++ n < -0x200 ? -0x200 : n, ++ &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++#define FLOAT_MINMAX(name, bits, minmaxfunc) \ ++uint ## bits ## _t helper_float_ ## name(CPULOONGARCHState *env, \ ++ uint ## bits ## _t fs, \ ++ uint ## bits ## _t ft) \ ++{ \ ++ uint ## bits ## _t fdret; \ ++ \ ++ fdret = float ## bits ## _ ## minmaxfunc(fs, ft, \ ++ &env->active_fpu.fp_status); \ ++ update_fcsr0(env, GETPC()); \ ++ return fdret; \ ++} ++ ++FLOAT_MINMAX(max_s, 32, maxnum) ++FLOAT_MINMAX(max_d, 64, maxnum) ++FLOAT_MINMAX(maxa_s, 32, maxnummag) ++FLOAT_MINMAX(maxa_d, 64, maxnummag) ++ ++FLOAT_MINMAX(min_s, 32, minnum) ++FLOAT_MINMAX(min_d, 64, minnum) ++FLOAT_MINMAX(mina_s, 32, minnummag) ++FLOAT_MINMAX(mina_d, 64, minnummag) ++#undef FLOAT_MINMAX ++ ++#define FLOAT_FMADDSUB(name, bits, muladd_arg) \ ++uint ## bits ## _t helper_float_ ## name(CPULOONGARCHState *env, \ ++ uint ## bits ## _t fs, \ ++ uint ## bits ## _t ft, \ ++ uint ## bits ## _t fd) \ ++{ \ ++ uint ## bits ## _t fdret; \ ++ \ ++ fdret = float ## bits ## _muladd(fs, ft, fd, muladd_arg, \ ++ &env->active_fpu.fp_status); \ ++ update_fcsr0(env, GETPC()); \ ++ return fdret; \ ++} ++ ++FLOAT_FMADDSUB(maddf_s, 32, 0) ++FLOAT_FMADDSUB(maddf_d, 64, 0) ++FLOAT_FMADDSUB(msubf_s, 32, float_muladd_negate_c) ++FLOAT_FMADDSUB(msubf_d, 64, float_muladd_negate_c) ++FLOAT_FMADDSUB(nmaddf_s, 32, float_muladd_negate_result) ++FLOAT_FMADDSUB(nmaddf_d, 64, float_muladd_negate_result) ++FLOAT_FMADDSUB(nmsubf_s, 32, float_muladd_negate_result | float_muladd_negate_c) ++FLOAT_FMADDSUB(nmsubf_d, 64, float_muladd_negate_result | float_muladd_negate_c) ++#undef FLOAT_FMADDSUB ++ ++/* compare operations */ ++#define FOP_CONDN_D(op, cond) \ ++uint64_t helper_cmp_d_ ## op(CPULOONGARCHState *env, uint64_t fdt0, \ ++ uint64_t fdt1) \ ++{ \ ++ uint64_t c; \ ++ c = cond; \ ++ update_fcsr0(env, GETPC()); \ ++ if (c) { \ ++ return -1; \ ++ } else { \ ++ return 0; \ ++ } \ ++} ++ ++/* ++ * NOTE: the comma operator will make "cond" to eval to false, ++ * but float64_unordered_quiet() is still called. ++ */ ++FOP_CONDN_D(af, (float64_unordered_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status), 0)) ++FOP_CONDN_D(un, (float64_unordered_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(eq, (float64_eq_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_eq_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(lt, (float64_lt_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(le, (float64_le_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_le_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++/* ++ * NOTE: the comma operator will make "cond" to eval to false, ++ * but float64_unordered() is still called. ++ */ ++FOP_CONDN_D(saf, (float64_unordered(fdt1, fdt0, ++ &env->active_fpu.fp_status), 0)) ++FOP_CONDN_D(sun, (float64_unordered(fdt1, fdt0, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(seq, (float64_eq(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_eq(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(slt, (float64_lt(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sle, (float64_le(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_le(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(or, (float64_le_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_le_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(une, (float64_unordered_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(ne, (float64_lt_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sor, (float64_le(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_le(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sne, (float64_lt(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++ ++#define FOP_CONDN_S(op, cond) \ ++uint32_t helper_cmp_s_ ## op(CPULOONGARCHState *env, uint32_t fst0, \ ++ uint32_t fst1) \ ++{ \ ++ uint64_t c; \ ++ c = cond; \ ++ update_fcsr0(env, GETPC()); \ ++ if (c) { \ ++ return -1; \ ++ } else { \ ++ return 0; \ ++ } \ ++} ++ ++/* ++ * NOTE: the comma operator will make "cond" to eval to false, ++ * but float32_unordered_quiet() is still called. ++ */ ++FOP_CONDN_S(af, (float32_unordered_quiet(fst1, fst0, ++ &env->active_fpu.fp_status), 0)) ++FOP_CONDN_S(un, (float32_unordered_quiet(fst1, fst0, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(eq, (float32_eq_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(ueq, (float32_unordered_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_eq_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(lt, (float32_lt_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(ult, (float32_unordered_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(le, (float32_le_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(ule, (float32_unordered_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_le_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++/* ++ * NOTE: the comma operator will make "cond" to eval to false, ++ * but float32_unordered() is still called. ++ */ ++FOP_CONDN_S(saf, (float32_unordered(fst1, fst0, ++ &env->active_fpu.fp_status), 0)) ++FOP_CONDN_S(sun, (float32_unordered(fst1, fst0, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(seq, (float32_eq(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_eq(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(slt, (float32_lt(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sult, (float32_unordered(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sle, (float32_le(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sule, (float32_unordered(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_le(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(or, (float32_le_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_le_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(une, (float32_unordered_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(ne, (float32_lt_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sor, (float32_le(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_le(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sune, (float32_unordered(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sne, (float32_lt(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt(fst0, fst1, ++ &env->active_fpu.fp_status))) ++ ++uint32_t helper_float_logb_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t wt2; ++ ++ wt2 = float32_log2(fst0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint64_t helper_float_logb_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t dt2; ++ ++ dt2 = float64_log2(fdt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++target_ulong helper_fsel(CPULOONGARCHState *env, target_ulong fj, ++ target_ulong fk, uint32_t ca) ++{ ++ if (env->active_fpu.cf[ca & 0x7]) { ++ return fk; ++ } else { ++ return fj; ++ } ++} +diff --git a/target/loongarch64/fpu_helper.h b/target/loongarch64/fpu_helper.h +new file mode 100644 +index 0000000000..b6898c2e91 +--- /dev/null ++++ b/target/loongarch64/fpu_helper.h +@@ -0,0 +1,129 @@ ++/* loongarch internal definitions and helpers ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or later. ++ * See the COPYING file in the top-level directory. ++ */ ++ ++#ifndef LOONGARCH_FPU_H ++#define LOONGARCH_FPU_H ++ ++#include "cpu-csr.h" ++ ++ ++extern const struct loongarch_def_t loongarch_defs[]; ++extern const int loongarch_defs_number; ++ ++enum CPULSXDataFormat { ++ DF_BYTE = 0, ++ DF_HALF, ++ DF_WORD, ++ DF_DOUBLE, ++ DF_QUAD ++}; ++ ++void loongarch_cpu_do_interrupt(CPUState *cpu); ++bool loongarch_cpu_exec_interrupt(CPUState *cpu, int int_req); ++void loongarch_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, ++ MMUAccessType access_type, ++ int mmu_idx, uintptr_t retaddr) QEMU_NORETURN; ++ ++#if !defined(CONFIG_USER_ONLY) ++ ++typedef struct r4k_tlb_t r4k_tlb_t; ++struct r4k_tlb_t { ++ target_ulong VPN; ++ uint32_t PageMask; ++ uint16_t ASID; ++ unsigned int G:1; ++ unsigned int C0:3; ++ unsigned int C1:3; ++ unsigned int V0:1; ++ unsigned int V1:1; ++ unsigned int D0:1; ++ unsigned int D1:1; ++ unsigned int XI0:1; ++ unsigned int XI1:1; ++ unsigned int RI0:1; ++ unsigned int RI1:1; ++ unsigned int EHINV:1; ++ uint64_t PPN[2]; ++}; ++ ++int no_mmu_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, ++ target_ulong address, int rw, int access_type); ++int fixed_mmu_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, ++ target_ulong address, int rw, int access_type); ++int r4k_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, ++ target_ulong address, int rw, int access_type); ++ ++/* loongarch 3a5000 tlb helper function : lisa csr */ ++int ls3a5k_map_address(CPULOONGARCHState *env, hwaddr *physical, ++ int *prot, target_ulong address, ++ int rw, int access_type); ++void ls3a5k_helper_tlbwr(CPULOONGARCHState *env); ++void ls3a5k_helper_tlbfill(CPULOONGARCHState *env); ++void ls3a5k_helper_tlbsrch(CPULOONGARCHState *env); ++void ls3a5k_helper_tlbrd(CPULOONGARCHState *env); ++void ls3a5k_helper_tlbclr(CPULOONGARCHState *env); ++void ls3a5k_helper_tlbflush(CPULOONGARCHState *env); ++void ls3a5k_invalidate_tlb(CPULOONGARCHState *env, int idx); ++void ls3a5k_helper_invtlb(CPULOONGARCHState *env, target_ulong addr, ++ target_ulong info, int op); ++void ls3a5k_flush_vtlb(CPULOONGARCHState *env); ++void ls3a5k_flush_ftlb(CPULOONGARCHState *env); ++/*void loongarch_cpu_unassigned_access(CPUState *cpu, hwaddr addr, ++ bool is_write, bool is_exec, int unused, ++ unsigned size); ++*/ ++hwaddr cpu_loongarch_translate_address(CPULOONGARCHState *env, target_ulong address, ++ int rw); ++#endif ++ ++#define cpu_signal_handler cpu_loongarch_signal_handler ++ ++ ++static inline bool cpu_loongarch_hw_interrupts_enabled(CPULOONGARCHState *env) ++{ ++ bool ret = 0; ++ ++ ret = env->CSR_CRMD & (1 << CSR_CRMD_IE_SHIFT); ++ ++ return ret; ++} ++ ++ ++void loongarch_tcg_init(void); ++ ++ ++/* helper.c */ ++bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, ++ MMUAccessType access_type, int mmu_idx, ++ bool probe, uintptr_t retaddr); ++ ++/* op_helper.c */ ++uint32_t float_class_s(uint32_t arg, float_status *fst); ++uint64_t float_class_d(uint64_t arg, float_status *fst); ++ ++int ieee_ex_to_loongarch(int xcpt); ++void update_pagemask(CPULOONGARCHState *env, target_ulong arg1, int32_t *pagemask); ++ ++void cpu_loongarch_tlb_flush(CPULOONGARCHState *env); ++void sync_c0_status(CPULOONGARCHState *env, CPULOONGARCHState *cpu, int tc); ++ ++void QEMU_NORETURN do_raise_exception_err(CPULOONGARCHState *env, uint32_t exception, ++ int error_code, uintptr_t pc); ++int loongarch_read_qxfer(CPUState *cs, const char *annex, ++ uint8_t *read_buf, ++ unsigned long offset, unsigned long len); ++int loongarch_write_qxfer(CPUState *cs, const char *annex, ++ const uint8_t *write_buf, ++ unsigned long offset, unsigned long len); ++ ++static inline void QEMU_NORETURN do_raise_exception(CPULOONGARCHState *env, ++ uint32_t exception, ++ uintptr_t pc) ++{ ++ do_raise_exception_err(env, exception, 0, pc); ++} ++ ++#endif +diff --git a/target/loongarch64/gdbstub.c b/target/loongarch64/gdbstub.c +new file mode 100644 +index 0000000000..4013178f45 +--- /dev/null ++++ b/target/loongarch64/gdbstub.c +@@ -0,0 +1,109 @@ ++/* ++ * LOONGARCH 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 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 . ++ */ ++#include "qemu/osdep.h" ++#include "qemu-common.h" ++#include "cpu.h" ++#include "internal.h" ++#include "exec/gdbstub.h" ++#ifdef CONFIG_TCG ++#include "exec/helper-proto.h" ++#endif ++int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ ++ if (0 <= n && n < 32) { ++ return gdb_get_regl(mem_buf, env->active_tc.gpr[n]); ++ } else if (n == 32) { ++ return gdb_get_regl(mem_buf, env->active_tc.PC); ++ } ++ return 0; ++} ++ ++int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ target_ulong tmp = ldtul_p(mem_buf); ++ ++ if (0 <= n && n < 32) { ++ return env->active_tc.gpr[n] = tmp, sizeof(target_ulong); ++ } else if (n == 32) { ++ return env->active_tc.PC = tmp, sizeof(target_ulong); ++ } ++ return 0; ++} ++ ++static int loongarch_gdb_get_fpu(CPULOONGARCHState *env, GByteArray *mem_buf, int n) ++{ ++ if (0 <= n && n < 32) { ++ return gdb_get_reg64(mem_buf, env->active_fpu.fpr[n].d); ++ } else if (32 <= n && n < 40) { ++ return gdb_get_reg8(mem_buf, env->active_fpu.cf[n - 32]); ++ } else if (n == 40) { ++ return gdb_get_reg32(mem_buf, env->active_fpu.fcsr0); ++ } ++ return 0; ++} ++ ++static int loongarch_gdb_set_fpu(CPULOONGARCHState *env, uint8_t *mem_buf, int n) ++{ ++ if (0 <= n && n < 32) { ++ return env->active_fpu.fpr[n].d = ldq_p(mem_buf), 8; ++ } else if (32 <= n && n < 40) { ++ return env->active_fpu.cf[n - 32] = ldub_p(mem_buf), 1; ++ } else if (n == 40) { ++ return env->active_fpu.fcsr0 = ldl_p(mem_buf), 4; ++ } ++ return 0; ++} ++ ++void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs) ++{ ++ gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, ++ 41, "loongarch-fpu64.xml", 0); ++} ++ ++#ifdef CONFIG_TCG ++int loongarch_read_qxfer(CPUState *cs, const char *annex, uint8_t *read_buf, ++ unsigned long offset, unsigned long len) ++{ ++ if (strncmp(annex, "cpucfg", sizeof("cpucfg") - 1) == 0) { ++ if (offset % 4 != 0 || len % 4 != 0) { ++ return 0; ++ } ++ ++ size_t i; ++ for (i = offset; i < offset + len; i += 4) ++ ((uint32_t *)read_buf)[(i - offset) / 4] = ++ helper_cpucfg(&(LOONGARCH_CPU(cs)->env), i / 4); ++ return 32 * 4; ++ } ++ return 0; ++} ++ ++int loongarch_write_qxfer(CPUState *cs, const char *annex, ++ const uint8_t *write_buf, unsigned long offset, ++ unsigned long len) ++{ ++ return 0; ++} ++#endif +diff --git a/target/loongarch64/helper.c b/target/loongarch64/helper.c +new file mode 100644 +index 0000000000..841240e57b +--- /dev/null ++++ b/target/loongarch64/helper.c +@@ -0,0 +1,727 @@ ++/* ++ * LOONGARCH emulation helpers for qemu. ++ * ++ * Copyright (c) 2004-2005 Jocelyn Mayer ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#include "qemu/osdep.h" ++#include "cpu.h" ++#include "internal.h" ++#include "exec/exec-all.h" ++#include "exec/cpu_ldst.h" ++#include "exec/log.h" ++#include "hw/loongarch/cpudevs.h" ++ ++ ++#if !defined(CONFIG_USER_ONLY) ++ ++static int ls3a5k_map_address_tlb_entry( ++ CPULOONGARCHState *env, ++ hwaddr *physical, ++ int *prot, ++ target_ulong address, ++ int rw, ++ int access_type, ++ ls3a5k_tlb_t *tlb) ++{ ++ uint64_t mask = tlb->PageMask; ++ int n = !!(address & mask & ~(mask >> 1)); ++ uint32_t plv = env->CSR_CRMD & CSR_CRMD_PLV; ++ ++ /* Check access rights */ ++ if (!(n ? tlb->V1 : tlb->V0)) { ++ return TLBRET_INVALID; ++ } ++ ++ if (rw == MMU_INST_FETCH && (n ? tlb->XI1 : tlb->XI0)) { ++ return TLBRET_XI; ++ } ++ ++ if (rw == MMU_DATA_LOAD && (n ? tlb->RI1 : tlb->RI0)) { ++ return TLBRET_RI; ++ } ++ ++ if (plv > (n ? tlb->PLV1 : tlb->PLV0)) { ++ return TLBRET_PE; ++ } ++ ++ if (rw != MMU_DATA_STORE || (n ? tlb->WE1 : tlb->WE0)) { ++ /* PPN address ++ * 4 KB: [47:13] [12;0] ++ * 16 KB: [47:15] [14:0] ++ */ ++ if (n) { ++ *physical = tlb->PPN1 | (address & (mask >> 1)); ++ } else { ++ *physical = tlb->PPN0 | (address & (mask >> 1)); ++ } ++ *prot = PAGE_READ; ++ if (n ? tlb->WE1 : tlb->WE0) { ++ *prot |= PAGE_WRITE; ++ } ++ if (!(n ? tlb->XI1 : tlb->XI0)) { ++ *prot |= PAGE_EXEC; ++ } ++ return TLBRET_MATCH; ++ } ++ ++ return TLBRET_DIRTY; ++} ++ ++/* Loongarch 3A5K -style MMU emulation */ ++int ls3a5k_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, ++ target_ulong address, int rw, int access_type) ++{ ++ uint16_t asid = env->CSR_ASID & 0x3ff; ++ int i; ++ ls3a5k_tlb_t *tlb; ++ ++ int ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; ++ int vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; ++ ++ int ftlb_idx; ++ ++ uint64_t mask; ++ uint64_t vpn; /* address to map */ ++ uint64_t tag; /* address in TLB entry */ ++ ++ /* search VTLB */ ++ for (i = ftlb_size; i < ftlb_size + vtlb_size; ++i) { ++ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ mask = tlb->PageMask; ++ ++ vpn = address & 0xffffffffe000 & ~mask; ++ tag = tlb->VPN & ~mask; ++ ++ if ((tlb->G == 1 || tlb->ASID == asid) ++ && vpn == tag ++ && tlb->EHINV != 1) ++ { ++ return ls3a5k_map_address_tlb_entry(env, physical, prot, ++ address, rw, access_type, tlb); ++ } ++ } ++ ++ if (ftlb_size == 0) { ++ return TLBRET_NOMATCH; ++ } ++ ++ /* search FTLB */ ++ mask = env->tlb->mmu.ls3a5k.ftlb_mask; ++ vpn = address & 0xffffffffe000 & ~mask; ++ ++ ftlb_idx = (address & 0xffffffffc000) >> 15; /* 16 KB */ ++ ftlb_idx = ftlb_idx & 0xff; /* [0,255] */ ++ ++ for (i = 0; i < 8; ++i) { ++ /* ---------- set 0 1 2 ... 7 ++ * ftlb_idx ----------------------------------- ++ * 0 | 0 1 2 ... 7 ++ * 1 | 8 9 10 ... 15 ++ * 2 | 16 17 18 ... 23 ++ * ... | ++ * 255 | 2040 2041 2042 ... 2047 ++ */ ++ tlb = &env->tlb->mmu.ls3a5k.tlb[ftlb_idx * 8 + i]; ++ tag = tlb->VPN & ~mask; ++ ++ if ((tlb->G == 1 || tlb->ASID == asid) ++ && vpn == tag ++ && tlb->EHINV != 1) ++ { ++ return ls3a5k_map_address_tlb_entry(env, physical, prot, ++ address, rw, access_type, tlb); ++ } ++ } ++ ++ return TLBRET_NOMATCH; ++} ++ ++static int get_physical_address(CPULOONGARCHState *env, hwaddr *physical, ++ int *prot, target_ulong real_address, ++ int rw, int access_type, int mmu_idx) ++{ ++ int user_mode = mmu_idx == LARCH_HFLAG_UM; ++ int kernel_mode = !user_mode; ++ unsigned plv, base_c, base_v, tmp; ++ ++ /* effective address (modified for KVM T&E kernel segments) */ ++ target_ulong address = real_address; ++ ++ /* Check PG */ ++ if (!(env->CSR_CRMD & CSR_CRMD_PG)) { ++ /* DA mode */ ++ *physical = address & 0xffffffffffffUL; ++ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ++ return TLBRET_MATCH; ++ } ++ ++ plv = kernel_mode | (user_mode << 3); ++ base_v = address >> CSR_DMW_BASE_SH; ++ /* Check direct map window 0 */ ++ base_c = env->CSR_DMWIN0 >> CSR_DMW_BASE_SH; ++ if ((plv & env->CSR_DMWIN0) && (base_c == base_v)) { ++ *physical = dmwin_va2pa(address); ++ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ++ return TLBRET_MATCH; ++ } ++ /* Check direct map window 1 */ ++ base_c = env->CSR_DMWIN1 >> CSR_DMW_BASE_SH; ++ if ((plv & env->CSR_DMWIN1) && (base_c == base_v)) { ++ *physical = dmwin_va2pa(address); ++ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ++ return TLBRET_MATCH; ++ } ++ /* Check valid extension */ ++ tmp = address >> 47; ++ if (!(tmp == 0 || tmp == 0x1ffff)) { ++ return TLBRET_BADADDR; ++ } ++ /* mapped address */ ++ return env->tlb->map_address(env, physical, prot, real_address, rw, ++ access_type); ++} ++ ++void cpu_loongarch_tlb_flush(CPULOONGARCHState *env) ++{ ++ LOONGARCHCPU *cpu = loongarch_env_get_cpu(env); ++ ++ /* Flush qemu's TLB and discard all shadowed entries. */ ++ tlb_flush(CPU(cpu)); ++ env->tlb->tlb_in_use = env->tlb->nb_tlb; ++} ++#endif ++ ++static void raise_mmu_exception(CPULOONGARCHState *env, target_ulong address, ++ int rw, int tlb_error) ++{ ++ CPUState *cs = CPU(loongarch_env_get_cpu(env)); ++ int exception = 0, error_code = 0; ++ ++ if (rw == MMU_INST_FETCH) { ++ error_code |= EXCP_INST_NOTAVAIL; ++ } ++ ++ switch (tlb_error) { ++ default: ++ case TLBRET_BADADDR: ++ /* Reference to kernel address from user mode or supervisor mode */ ++ /* Reference to supervisor address from user mode */ ++ if (rw == MMU_DATA_STORE) { ++ exception = EXCP_AdES; ++ } else { ++ exception = EXCP_AdEL; ++ } ++ break; ++ case TLBRET_NOMATCH: ++ /* No TLB match for a mapped address */ ++ if (rw == MMU_DATA_STORE) { ++ exception = EXCP_TLBS; ++ } else { ++ exception = EXCP_TLBL; ++ } ++ error_code |= EXCP_TLB_NOMATCH; ++ break; ++ case TLBRET_INVALID: ++ /* TLB match with no valid bit */ ++ if (rw == MMU_DATA_STORE) { ++ exception = EXCP_TLBS; ++ } else { ++ exception = EXCP_TLBL; ++ } ++ break; ++ case TLBRET_DIRTY: ++ /* TLB match but 'D' bit is cleared */ ++ exception = EXCP_LTLBL; ++ break; ++ case TLBRET_XI: ++ /* Execute-Inhibit Exception */ ++ exception = EXCP_TLBXI; ++ break; ++ case TLBRET_RI: ++ /* Read-Inhibit Exception */ ++ exception = EXCP_TLBRI; ++ break; ++ case TLBRET_PE: ++ /* Privileged Exception */ ++ exception = EXCP_TLBPE; ++ break; ++ } ++ ++ if (env->insn_flags & INSN_LOONGARCH) { ++ if (tlb_error == TLBRET_NOMATCH) { ++ env->CSR_TLBRBADV = address; ++ env->CSR_TLBREHI = address & (TARGET_PAGE_MASK << 1); ++ cs->exception_index = exception; ++ env->error_code = error_code; ++ return; ++ } ++ } ++ ++ /* Raise exception */ ++ env->CSR_BADV = address; ++ cs->exception_index = exception; ++ env->error_code = error_code; ++ ++ if (env->insn_flags & INSN_LOONGARCH) { ++ env->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1); ++ } ++} ++ ++bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, ++ MMUAccessType access_type, int mmu_idx, ++ bool probe, uintptr_t retaddr) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++#if !defined(CONFIG_USER_ONLY) ++ hwaddr physical; ++ int prot; ++ int loongarch_access_type; ++#endif ++ int ret = TLBRET_BADADDR; ++ ++ qemu_log_mask(CPU_LOG_MMU, ++ "%s pc " TARGET_FMT_lx " ad %" VADDR_PRIx " mmu_idx %d\n", ++ __func__, env->active_tc.PC, address, mmu_idx); ++ ++ /* data access */ ++#if !defined(CONFIG_USER_ONLY) ++ /* XXX: put correct access by using cpu_restore_state() correctly */ ++ loongarch_access_type = ACCESS_INT; ++ ret = get_physical_address(env, &physical, &prot, address, ++ access_type, loongarch_access_type, mmu_idx); ++ switch (ret) { ++ case TLBRET_MATCH: ++ qemu_log_mask(CPU_LOG_MMU, ++ "%s address=%" VADDR_PRIx " physical " TARGET_FMT_plx ++ " prot %d asid %ld pc 0x%lx\n", ++ __func__, address, physical, prot, ++ env->CSR_ASID, env->active_tc.PC); ++ break; ++ default: ++ qemu_log_mask(CPU_LOG_MMU, ++ "%s address=%" VADDR_PRIx " ret %d asid %ld pc 0x%lx\n", ++ __func__, address, ret, env->CSR_ASID, env->active_tc.PC); ++ break; ++ } ++ if (ret == TLBRET_MATCH) { ++ tlb_set_page(cs, address & TARGET_PAGE_MASK, ++ physical & TARGET_PAGE_MASK, prot | PAGE_EXEC, ++ mmu_idx, TARGET_PAGE_SIZE); ++ ret = true; ++ } ++ if (probe) { ++ return false; ++ } ++#endif ++ ++ raise_mmu_exception(env, address, access_type, ret); ++ do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr); ++} ++ ++#if !defined(CONFIG_USER_ONLY) ++hwaddr cpu_loongarch_translate_address(CPULOONGARCHState *env, ++ target_ulong address, int rw) ++{ ++ hwaddr physical; ++ int prot; ++ int access_type; ++ int ret = 0; ++ ++ /* data access */ ++ access_type = ACCESS_INT; ++ ret = get_physical_address(env, &physical, &prot, address, rw, access_type, ++ cpu_mmu_index(env, false)); ++ if (ret != TLBRET_MATCH) { ++ raise_mmu_exception(env, address, rw, ret); ++ return -1LL; ++ } else { ++ return physical; ++ } ++} ++ ++static const char * const excp_names[EXCP_LAST + 1] = { ++ [EXCP_RESET] = "reset", ++ [EXCP_SRESET] = "soft reset", ++ [EXCP_NMI] = "non-maskable interrupt", ++ [EXCP_EXT_INTERRUPT] = "interrupt", ++ [EXCP_AdEL] = "address error load", ++ [EXCP_AdES] = "address error store", ++ [EXCP_TLBF] = "TLB refill", ++ [EXCP_IBE] = "instruction bus error", ++ [EXCP_SYSCALL] = "syscall", ++ [EXCP_BREAK] = "break", ++ [EXCP_FPDIS] = "float unit unusable", ++ [EXCP_LSXDIS] = "vector128 unusable", ++ [EXCP_LASXDIS] = "vector256 unusable", ++ [EXCP_RI] = "reserved instruction", ++ [EXCP_OVERFLOW] = "arithmetic overflow", ++ [EXCP_TRAP] = "trap", ++ [EXCP_FPE] = "floating point", ++ [EXCP_LTLBL] = "TLB modify", ++ [EXCP_TLBL] = "TLB load", ++ [EXCP_TLBS] = "TLB store", ++ [EXCP_DBE] = "data bus error", ++ [EXCP_TLBXI] = "TLB execute-inhibit", ++ [EXCP_TLBRI] = "TLB read-inhibit", ++ [EXCP_TLBPE] = "TLB priviledged error", ++}; ++#endif ++ ++target_ulong exception_resume_pc(CPULOONGARCHState *env) ++{ ++ target_ulong bad_pc; ++ ++ bad_pc = env->active_tc.PC; ++ if (env->hflags & LARCH_HFLAG_BMASK) { ++ /* If the exception was raised from a delay slot, come back to ++ the jump. */ ++ bad_pc -= 4; ++ } ++ ++ return bad_pc; ++} ++ ++#if !defined(CONFIG_USER_ONLY) ++static void set_hflags_for_handler (CPULOONGARCHState *env) ++{ ++ /* Exception handlers are entered in 32-bit mode. */ ++} ++ ++static inline void set_badinstr_registers(CPULOONGARCHState *env) ++{ ++ if ((env->insn_flags & INSN_LOONGARCH)) { ++ env->CSR_BADI = cpu_ldl_code(env, env->active_tc.PC); ++ return; ++ } ++} ++#endif ++ ++static inline unsigned int get_vint_size(CPULOONGARCHState *env) ++{ ++ unsigned int size = 0; ++ ++ switch ((env->CSR_ECFG >> 16) & 0x7) { ++ case 0: ++ break; ++ case 1: ++ size = 2 * 4; /* #Insts * inst_size */ ++ break; ++ case 2: ++ size = 4 * 4; ++ break; ++ case 3: ++ size = 8 * 4; ++ break; ++ case 4: ++ size = 16 * 4; ++ break; ++ case 5: ++ size = 32 * 4; ++ break; ++ case 6: ++ size = 64 * 4; ++ break; ++ case 7: ++ size = 128 * 4; ++ break; ++ default: ++ printf("%s: unexpected value", __func__); ++ assert(0); ++ } ++ ++ return size; ++} ++ ++#define is_refill(cs, env) (((cs->exception_index == EXCP_TLBL) \ ++ || (cs->exception_index == EXCP_TLBS)) \ ++ && (env->error_code & EXCP_TLB_NOMATCH)) ++ ++void loongarch_cpu_do_interrupt(CPUState *cs) ++{ ++#if !defined(CONFIG_USER_ONLY) ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ bool update_badinstr = 0; ++ int cause = -1; ++ const char *name; ++ ++ if (qemu_loglevel_mask(CPU_LOG_INT) ++ && cs->exception_index != EXCP_EXT_INTERRUPT) { ++ if (cs->exception_index < 0 || cs->exception_index > EXCP_LAST) { ++ name = "unknown"; ++ } else { ++ name = excp_names[cs->exception_index]; ++ } ++ ++ qemu_log("%s enter: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx ++ " TLBRERA 0x%016lx" " %s exception\n", __func__, ++ env->active_tc.PC, env->CSR_ERA, env->CSR_TLBRERA, name); ++ } ++ ++ switch (cs->exception_index) { ++ case EXCP_RESET: ++ cpu_reset(CPU(cpu)); ++ break; ++ case EXCP_NMI: ++ env->CSR_ERRERA = exception_resume_pc(env); ++ env->hflags &= ~LARCH_HFLAG_BMASK; ++ env->hflags |= LARCH_HFLAG_64; ++ env->hflags &= ~LARCH_HFLAG_AWRAP; ++ env->hflags &= ~(LARCH_HFLAG_KSU); ++ env->active_tc.PC = env->exception_base; ++ set_hflags_for_handler(env); ++ break; ++ case EXCP_EXT_INTERRUPT: ++ cause = 0; ++ goto set_ERA; ++ case EXCP_LTLBL: ++ cause = 1; ++ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); ++ goto set_ERA; ++ case EXCP_TLBL: ++ cause = 2; ++ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); ++ goto set_ERA; ++ case EXCP_TLBS: ++ cause = 3; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_AdEL: ++ cause = 4; ++ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); ++ goto set_ERA; ++ case EXCP_AdES: ++ cause = 5; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_IBE: ++ cause = 6; ++ goto set_ERA; ++ case EXCP_DBE: ++ cause = 7; ++ goto set_ERA; ++ case EXCP_SYSCALL: ++ cause = 8; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_BREAK: ++ cause = 9; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_RI: ++ cause = 10; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_FPDIS: ++ case EXCP_LSXDIS: ++ case EXCP_LASXDIS: ++ cause = 11; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_OVERFLOW: ++ cause = 12; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_TRAP: ++ cause = 13; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_FPE: ++ cause = 15; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_TLBRI: ++ cause = 19; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_TLBXI: ++ case EXCP_TLBPE: ++ cause = 20; ++ goto set_ERA; ++ set_ERA: ++ if (is_refill(cs, env)) { ++ env->CSR_TLBRERA = exception_resume_pc(env); ++ env->CSR_TLBRERA |= 1; ++ } else { ++ env->CSR_ERA = exception_resume_pc(env); ++ } ++ ++ if (update_badinstr) { ++ set_badinstr_registers(env); ++ } ++ env->hflags &= ~(LARCH_HFLAG_KSU); ++ ++ env->hflags &= ~LARCH_HFLAG_BMASK; ++ if (env->insn_flags & INSN_LOONGARCH) { ++ /* save PLV and IE */ ++ if (is_refill(cs, env)) { ++ env->CSR_TLBRPRMD &= (~0x7); ++ env->CSR_TLBRPRMD |= (env->CSR_CRMD & 0x7); ++ } else { ++ env->CSR_PRMD &= (~0x7); ++ env->CSR_PRMD |= (env->CSR_CRMD & 0x7); ++ } ++ ++ env->CSR_CRMD &= ~(0x7); ++ ++ switch (cs->exception_index) { ++ case EXCP_EXT_INTERRUPT: ++ break; ++ case EXCP_TLBL: ++ if (env->error_code & EXCP_INST_NOTAVAIL) { ++ cause = EXCCODE_TLBI; ++ } else { ++ cause = EXCCODE_TLBL; ++ } ++ break; ++ case EXCP_TLBS: ++ cause = EXCCODE_TLBS; ++ break; ++ case EXCP_LTLBL: ++ cause = EXCCODE_MOD; ++ break; ++ case EXCP_TLBRI: ++ cause = EXCCODE_TLBRI; ++ break; ++ case EXCP_TLBXI: ++ cause = EXCCODE_TLBXI; ++ break; ++ case EXCP_TLBPE: ++ cause = EXCCODE_TLBPE; ++ break; ++ case EXCP_AdEL: ++ case EXCP_AdES: ++ case EXCP_IBE: ++ case EXCP_DBE: ++ cause = EXCCODE_ADE; ++ break; ++ case EXCP_SYSCALL: ++ cause = EXCCODE_SYS; ++ break; ++ case EXCP_BREAK: ++ cause = EXCCODE_BP; ++ break; ++ case EXCP_RI: ++ cause = EXCCODE_RI; ++ break; ++ case EXCP_FPDIS: ++ cause = EXCCODE_FPDIS; ++ break; ++ case EXCP_LSXDIS: ++ cause = EXCCODE_LSXDIS; ++ break; ++ case EXCP_LASXDIS: ++ cause = EXCCODE_LASXDIS; ++ break; ++ case EXCP_FPE: ++ cause = EXCCODE_FPE; ++ break; ++ default: ++ printf("Error: exception(%d) '%s' has not been supported\n", ++ cs->exception_index, excp_names[cs->exception_index]); ++ abort(); ++ } ++ ++ uint32_t vec_size = get_vint_size(env); ++ env->active_tc.PC = env->CSR_EEPN; ++ env->active_tc.PC += cause * vec_size; ++ if (is_refill(cs, env)) { ++ /* TLB Refill */ ++ env->active_tc.PC = env->CSR_TLBRENT; ++ break; /* Do not modify excode */ ++ } ++ if (cs->exception_index == EXCP_EXT_INTERRUPT) { ++ /* Interrupt */ ++ uint32_t vector = 0; ++ uint32_t pending = env->CSR_ESTAT & CSR_ESTAT_IPMASK; ++ pending &= env->CSR_ECFG & CSR_ECFG_IPMASK; ++ ++ /* Find the highest-priority interrupt. */ ++ while (pending >>= 1) { ++ vector++; ++ } ++ env->active_tc.PC = env->CSR_EEPN + ++ (EXCODE_IP + vector) * vec_size; ++ if (qemu_loglevel_mask(CPU_LOG_INT)) { ++ qemu_log("%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx ++ " cause %d\n" " A " TARGET_FMT_lx " D " ++ TARGET_FMT_lx " vector = %d ExC %08lx ExS %08lx\n", ++ __func__, env->active_tc.PC, env->CSR_ERA, ++ cause, env->CSR_BADV, env->CSR_DERA, vector, ++ env->CSR_ECFG, env->CSR_ESTAT); ++ } ++ } ++ /* Excode */ ++ env->CSR_ESTAT = (env->CSR_ESTAT & ~(0x1f << CSR_ESTAT_EXC_SH)) | ++ (cause << CSR_ESTAT_EXC_SH); ++ } ++ set_hflags_for_handler(env); ++ break; ++ default: ++ abort(); ++ } ++ if (qemu_loglevel_mask(CPU_LOG_INT) ++ && cs->exception_index != EXCP_EXT_INTERRUPT) { ++ qemu_log("%s: PC " TARGET_FMT_lx " ERA 0x%08lx" " cause %d%s\n" ++ " ESTAT %08lx EXCFG 0x%08lx BADVA 0x%08lx BADI 0x%08lx \ ++ SYS_NUM %lu cpu %d asid 0x%lx" "\n", ++ __func__, env->active_tc.PC, ++ is_refill(cs, env) ? env->CSR_TLBRERA : env->CSR_ERA, ++ cause, ++ is_refill(cs, env) ? "(refill)" : "", ++ env->CSR_ESTAT, env->CSR_ECFG, ++ is_refill(cs, env) ? env->CSR_TLBRBADV : env->CSR_BADV, ++ env->CSR_BADI, env->active_tc.gpr[11], cs->cpu_index, ++ env->CSR_ASID ++ ); ++ } ++#endif ++ cs->exception_index = EXCP_NONE; ++} ++ ++bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request) ++{ ++ if (interrupt_request & CPU_INTERRUPT_HARD) { ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ ++ if (cpu_loongarch_hw_interrupts_enabled(env) && ++ cpu_loongarch_hw_interrupts_pending(env)) { ++ /* Raise it */ ++ cs->exception_index = EXCP_EXT_INTERRUPT; ++ env->error_code = 0; ++ loongarch_cpu_do_interrupt(cs); ++ return true; ++ } ++ } ++ return false; ++} ++ ++void QEMU_NORETURN do_raise_exception_err(CPULOONGARCHState *env, ++ uint32_t exception, ++ int error_code, ++ uintptr_t pc) ++{ ++ CPUState *cs = CPU(loongarch_env_get_cpu(env)); ++ ++ qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n", ++ __func__, exception, error_code); ++ cs->exception_index = exception; ++ env->error_code = error_code; ++ ++ cpu_loop_exit_restore(cs, pc); ++} +diff --git a/target/loongarch64/helper.h b/target/loongarch64/helper.h +new file mode 100644 +index 0000000000..ff2026ed82 +--- /dev/null ++++ b/target/loongarch64/helper.h +@@ -0,0 +1,168 @@ ++DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int) ++DEF_HELPER_2(raise_exception, noreturn, env, i32) ++DEF_HELPER_1(raise_exception_debug, noreturn, env) ++ ++#if 0 ++#ifndef CONFIG_USER_ONLY ++DEF_HELPER_3(ll, tl, env, tl, int) ++DEF_HELPER_3(lld, tl, env, tl, int) ++#endif ++#endif ++ ++DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl) ++DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl) ++ ++DEF_HELPER_3(crc32, tl, tl, tl, i32) ++DEF_HELPER_3(crc32c, tl, tl, tl, i32) ++ ++#ifndef CONFIG_USER_ONLY ++/* LoongISA CSR register */ ++DEF_HELPER_2(csr_rdq, tl, env, i64) ++DEF_HELPER_3(csr_wrq, tl, env, tl, i64) ++DEF_HELPER_4(csr_xchgq, tl, env, tl, tl, i64) ++ ++#endif /* !CONFIG_USER_ONLY */ ++ ++/* CP1 functions */ ++DEF_HELPER_2(movfcsr2gr, tl, env, i32) ++DEF_HELPER_4(movgr2fcsr, void, env, tl, i32, i32) ++ ++DEF_HELPER_2(float_cvtd_s, i64, env, i32) ++DEF_HELPER_2(float_cvtd_w, i64, env, i32) ++DEF_HELPER_2(float_cvtd_l, i64, env, i64) ++DEF_HELPER_2(float_cvts_d, i32, env, i64) ++DEF_HELPER_2(float_cvts_w, i32, env, i32) ++DEF_HELPER_2(float_cvts_l, i32, env, i64) ++ ++DEF_HELPER_FLAGS_2(float_class_s, TCG_CALL_NO_RWG_SE, i32, env, i32) ++DEF_HELPER_FLAGS_2(float_class_d, TCG_CALL_NO_RWG_SE, i64, env, i64) ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_4(float_ ## op ## _s, i32, env, i32, i32, i32) \ ++DEF_HELPER_4(float_ ## op ## _d, i64, env, i64, i64, i64) ++FOP_PROTO(maddf) ++FOP_PROTO(msubf) ++FOP_PROTO(nmaddf) ++FOP_PROTO(nmsubf) ++#undef FOP_PROTO ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_3(float_ ## op ## _s, i32, env, i32, i32) \ ++DEF_HELPER_3(float_ ## op ## _d, i64, env, i64, i64) ++FOP_PROTO(max) ++FOP_PROTO(maxa) ++FOP_PROTO(min) ++FOP_PROTO(mina) ++#undef FOP_PROTO ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_2(float_ ## op ## _l_s, i64, env, i32) \ ++DEF_HELPER_2(float_ ## op ## _l_d, i64, env, i64) \ ++DEF_HELPER_2(float_ ## op ## _w_s, i32, env, i32) \ ++DEF_HELPER_2(float_ ## op ## _w_d, i32, env, i64) ++FOP_PROTO(cvt) ++FOP_PROTO(round) ++FOP_PROTO(trunc) ++FOP_PROTO(ceil) ++FOP_PROTO(floor) ++#undef FOP_PROTO ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_2(float_ ## op ## _s, i32, env, i32) \ ++DEF_HELPER_2(float_ ## op ## _d, i64, env, i64) ++FOP_PROTO(sqrt) ++FOP_PROTO(rsqrt) ++FOP_PROTO(recip) ++FOP_PROTO(rint) ++#undef FOP_PROTO ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_1(float_ ## op ## _s, i32, i32) \ ++DEF_HELPER_1(float_ ## op ## _d, i64, i64) ++FOP_PROTO(abs) ++FOP_PROTO(chs) ++#undef FOP_PROTO ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_3(float_ ## op ## _s, i32, env, i32, i32) \ ++DEF_HELPER_3(float_ ## op ## _d, i64, env, i64, i64) ++FOP_PROTO(add) ++FOP_PROTO(sub) ++FOP_PROTO(mul) ++FOP_PROTO(div) ++#undef FOP_PROTO ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_3(cmp_d_ ## op, i64, env, i64, i64) \ ++DEF_HELPER_3(cmp_s_ ## op, i32, env, i32, i32) ++FOP_PROTO(af) ++FOP_PROTO(un) ++FOP_PROTO(eq) ++FOP_PROTO(ueq) ++FOP_PROTO(lt) ++FOP_PROTO(ult) ++FOP_PROTO(le) ++FOP_PROTO(ule) ++FOP_PROTO(saf) ++FOP_PROTO(sun) ++FOP_PROTO(seq) ++FOP_PROTO(sueq) ++FOP_PROTO(slt) ++FOP_PROTO(sult) ++FOP_PROTO(sle) ++FOP_PROTO(sule) ++FOP_PROTO(or) ++FOP_PROTO(une) ++FOP_PROTO(ne) ++FOP_PROTO(sor) ++FOP_PROTO(sune) ++FOP_PROTO(sne) ++#undef FOP_PROTO ++ ++/* Special functions */ ++#ifndef CONFIG_USER_ONLY ++DEF_HELPER_1(tlbwr, void, env) ++DEF_HELPER_1(tlbfill, void, env) ++DEF_HELPER_1(tlbsrch, void, env) ++DEF_HELPER_1(tlbrd, void, env) ++DEF_HELPER_1(tlbclr, void, env) ++DEF_HELPER_1(tlbflush, void, env) ++DEF_HELPER_4(invtlb, void, env, tl, tl, tl) ++DEF_HELPER_1(ertn, void, env) ++DEF_HELPER_5(lddir, void, env, tl, tl, tl, i32) ++DEF_HELPER_4(ldpte, void, env, tl, tl, i32) ++DEF_HELPER_3(drdtime, void, env, tl, tl) ++DEF_HELPER_1(read_pgd, tl, env) ++#endif /* !CONFIG_USER_ONLY */ ++DEF_HELPER_2(cpucfg, tl, env, tl) ++DEF_HELPER_1(idle, void, env) ++ ++DEF_HELPER_3(float_exp2_s, i32, env, i32, i32) ++DEF_HELPER_3(float_exp2_d, i64, env, i64, i64) ++DEF_HELPER_2(float_logb_s, i32, env, i32) ++DEF_HELPER_2(float_logb_d, i64, env, i64) ++DEF_HELPER_3(movreg2cf, void, env, i32, tl) ++DEF_HELPER_2(movcf2reg, tl, env, i32) ++DEF_HELPER_3(movreg2cf_i32, void, env, i32, i32) ++DEF_HELPER_3(movreg2cf_i64, void, env, i32, i64) ++ ++DEF_HELPER_2(cto_w, tl, env, tl) ++DEF_HELPER_2(ctz_w, tl, env, tl) ++DEF_HELPER_2(cto_d, tl, env, tl) ++DEF_HELPER_2(ctz_d, tl, env, tl) ++DEF_HELPER_2(bitrev_w, tl, env, tl) ++DEF_HELPER_2(bitrev_d, tl, env, tl) ++ ++DEF_HELPER_2(load_scr, i64, env, i32) ++DEF_HELPER_3(store_scr, void, env, i32, i64) ++ ++DEF_HELPER_3(asrtle_d, void, env, tl, tl) ++DEF_HELPER_3(asrtgt_d, void, env, tl, tl) ++ ++DEF_HELPER_4(fsel, i64, env, i64, i64, i32) ++ ++#ifndef CONFIG_USER_ONLY ++DEF_HELPER_4(iocsr, void, env, tl, tl, i32) ++#endif ++DEF_HELPER_3(memtrace_addr, void, env, tl, i32) ++DEF_HELPER_2(memtrace_val, void, env, tl) +diff --git a/target/loongarch64/insn.decode b/target/loongarch64/insn.decode +new file mode 100644 +index 0000000000..f194f70116 +--- /dev/null ++++ b/target/loongarch64/insn.decode +@@ -0,0 +1,514 @@ ++# Fields ++%sd 0:2 ++%rj 5:5 ++%rd 0:5 ++%sj 5:2 ++%ptr 5:3 ++%rk 10:5 ++%sa2 15:2 ++%sa3 15:3 ++%si5 10:s5 ++%code 0:15 ++%cond 10:4 ++%cond2 0:4 ++%ui5 10:5 ++%ui6 10:6 ++%ui3 10:3 ++%ui4 10:4 ++%op 5:5 ++%ui8 10:8 ++%msbw 16:5 ++%lsbw 10:5 ++%msbd 16:6 ++%lsbd 10:6 ++%fd 0:5 ++%fj 5:5 ++%fk 10:5 ++%fcsrd 0:5 ++%fcsrs 5:5 ++%cd 0:3 ++%cj 5:3 ++%si12 10:s12 ++%ui12 10:12 ++%csr 10:14 ++%cop 0:5 ++%level 10:8 ++%seq 10:8 ++%whint 0:15 ++%addr 10:5 ++%info 5:5 ++%invop 0:5 ++%fa 15:5 ++%vd 0:5 ++%vj 5:5 ++%vk 10:5 ++%va 15:5 ++%xd 0:5 ++%xj 5:5 ++%xk 10:5 ++%xa 15:5 ++%fcond 15:5 ++%ca 15:3 ++%vui5 15:5 ++%si16 10:s16 ++%si20 5:s20 ++%si14 10:s14 ++%hint 0:5 ++%si9 10:s9 ++%si10 10:s10 ++%si11 10:s11 ++%si8 10:s8 ++%idx1 18:1 ++%idx2 18:2 ++%idx3 18:3 ++%idx4 18:4 ++%idx 18:5 ++%offs21 0:s5 10:16 ++%offs16 10:s16 ++%offs 0:s10 10:16 ++%mode 5:5 ++%ui2 10:2 ++%ui1 10:1 ++%ui7 10:7 ++%i13 5:13 ++ ++# Argument sets ++&fmt_sdrj sd rj ++&fmt_rdsj rd sj ++&fmt_rdrj rd rj ++&fmt_empty ++&fmt_rjrk rj rk ++&fmt_rdrjrksa2 rd rj rk sa2 ++&fmt_rdrjrksa3 rd rj rk sa3 ++&fmt_rdrjrk rd rj rk ++&fmt_code code ++&fmt_rdrjui5 rd rj ui5 ++&fmt_rdrjui6 rd rj ui6 ++&fmt_rdrjmsbwlsbw rd rj msbw lsbw ++&fmt_rdrjmsbdlsbd rd rj msbd lsbd ++&fmt_fdfjfk fd fj fk ++&fmt_fdfj fd fj ++&fmt_fdrj fd rj ++&fmt_rdfj rd fj ++&fmt_fcsrdrj fcsrd rj ++&fmt_rdfcsrs rd fcsrs ++&fmt_cdfj cd fj ++&fmt_fdcj fd cj ++&fmt_cdrj cd rj ++&fmt_rdcj rd cj ++&fmt_rdrjsi12 rd rj si12 ++&fmt_rdrjui12 rd rj ui12 ++&fmt_rdrjcsr rd rj csr ++&fmt_coprjsi12 cop rj si12 ++&fmt_rdrjlevel rd rj level ++&fmt_rjseq rj seq ++&fmt_whint whint ++&fmt_invtlb addr info invop ++&fmt_fdfjfkfa fd fj fk fa ++&fmt_cdfjfkfcond cd fj fk fcond ++&fmt_fdfjfkca fd fj fk ca ++&fmt_rdrjsi16 rd rj si16 ++&fmt_rdsi20 rd si20 ++&fmt_rdrjsi14 rd rj si14 ++&fmt_hintrjsi12 hint rj si12 ++&fmt_fdrjsi12 fd rj si12 ++&fmt_fdrjrk fd rj rk ++&fmt_rjoffs21 rj offs21 ++&fmt_cjoffs21 cj offs21 ++&fmt_rdrjoffs16 rd rj offs16 ++&fmt_offs offs ++&fmt_rjrdoffs16 rj rd offs16 ++ ++# Formats ++@fmt_sdrj .... ........ ..... ..... ..... ... .. &fmt_sdrj %sd %rj ++@fmt_rdsj .... ........ ..... ..... ... .. ..... &fmt_rdsj %rd %sj ++@fmt_rdrj .... ........ ..... ..... ..... ..... &fmt_rdrj %rd %rj ++@fmt_empty .... ........ ..... ..... ..... ..... &fmt_empty ++@fmt_rjrk .... ........ ..... ..... ..... ..... &fmt_rjrk %rj %rk ++@fmt_rdrjrksa2 .... ........ ... .. ..... ..... ..... &fmt_rdrjrksa2 %rd %rj %rk %sa2 ++@fmt_rdrjrksa3 .... ........ .. ... ..... ..... ..... &fmt_rdrjrksa3 %rd %rj %rk %sa3 ++@fmt_rdrjrk .... ........ ..... ..... ..... ..... &fmt_rdrjrk %rd %rj %rk ++@fmt_code .... ........ ..... ............... &fmt_code %code ++@fmt_rdrjui5 .... ........ ..... ..... ..... ..... &fmt_rdrjui5 %rd %rj %ui5 ++@fmt_rdrjui6 .... ........ .... ...... ..... ..... &fmt_rdrjui6 %rd %rj %ui6 ++@fmt_rdrjmsbwlsbw .... ....... ..... . ..... ..... ..... &fmt_rdrjmsbwlsbw %rd %rj %msbw %lsbw ++@fmt_rdrjmsbdlsbd .... ...... ...... ...... ..... ..... &fmt_rdrjmsbdlsbd %rd %rj %msbd %lsbd ++@fmt_fdfjfk .... ........ ..... ..... ..... ..... &fmt_fdfjfk %fd %fj %fk ++@fmt_fdfj .... ........ ..... ..... ..... ..... &fmt_fdfj %fd %fj ++@fmt_fdrj .... ........ ..... ..... ..... ..... &fmt_fdrj %fd %rj ++@fmt_rdfj .... ........ ..... ..... ..... ..... &fmt_rdfj %rd %fj ++@fmt_fcsrdrj .... ........ ..... ..... ..... ..... &fmt_fcsrdrj %fcsrd %rj ++@fmt_rdfcsrs .... ........ ..... ..... ..... ..... &fmt_rdfcsrs %rd %fcsrs ++@fmt_cdfj .... ........ ..... ..... ..... .. ... &fmt_cdfj %cd %fj ++@fmt_fdcj .... ........ ..... ..... .. ... ..... &fmt_fdcj %fd %cj ++@fmt_cdrj .... ........ ..... ..... ..... .. ... &fmt_cdrj %cd %rj ++@fmt_rdcj .... ........ ..... ..... .. ... ..... &fmt_rdcj %rd %cj ++@fmt_rdrjsi12 .... ...... ............ ..... ..... &fmt_rdrjsi12 %rd %rj %si12 ++@fmt_rdrjui12 .... ...... ............ ..... ..... &fmt_rdrjui12 %rd %rj %ui12 ++@fmt_rdrjcsr .... .... .............. ..... ..... &fmt_rdrjcsr %rd %rj %csr ++@fmt_coprjsi12 .... ...... ............ ..... ..... &fmt_coprjsi12 %cop %rj %si12 ++@fmt_rdrjlevel .... ........ .. ........ ..... ..... &fmt_rdrjlevel %rd %rj %level ++@fmt_rjseq .... ........ .. ........ ..... ..... &fmt_rjseq %rj %seq ++@fmt_whint .... ........ ..... ............... &fmt_whint %whint ++@fmt_invtlb ...... ...... ..... ..... ..... ..... &fmt_invtlb %addr %info %invop ++@fmt_fdfjfkfa .... ........ ..... ..... ..... ..... &fmt_fdfjfkfa %fd %fj %fk %fa ++@fmt_cdfjfkfcond .... ........ ..... ..... ..... .. ... &fmt_cdfjfkfcond %cd %fj %fk %fcond ++@fmt_fdfjfkca .... ........ .. ... ..... ..... ..... &fmt_fdfjfkca %fd %fj %fk %ca ++@fmt_rdrjsi16 .... .. ................ ..... ..... &fmt_rdrjsi16 %rd %rj %si16 ++@fmt_rdsi20 .... ... .................... ..... &fmt_rdsi20 %rd %si20 ++@fmt_rdrjsi14 .... .... .............. ..... ..... &fmt_rdrjsi14 %rd %rj %si14 ++@fmt_hintrjsi12 .... ...... ............ ..... ..... &fmt_hintrjsi12 %hint %rj %si12 ++@fmt_fdrjsi12 .... ...... ............ ..... ..... &fmt_fdrjsi12 %fd %rj %si12 ++@fmt_fdrjrk .... ........ ..... ..... ..... ..... &fmt_fdrjrk %fd %rj %rk ++@fmt_rjoffs21 .... .. ................ ..... ..... &fmt_rjoffs21 %rj %offs21 ++@fmt_cjoffs21 .... .. ................ .. ... ..... &fmt_cjoffs21 %cj %offs21 ++@fmt_rdrjoffs16 .... .. ................ ..... ..... &fmt_rdrjoffs16 %rd %rj %offs16 ++@fmt_offs .... .. .......................... &fmt_offs %offs ++@fmt_rjrdoffs16 .... .. ................ ..... ..... &fmt_rjrdoffs16 %rj %rd %offs16 ++ ++# Instructions ++ ++# Fiexd point arithmetic Instructions ++gr2scr 0000 00000000 00000 00010 ..... 000 .. @fmt_sdrj ++scr2gr 0000 00000000 00000 00011 000 .. ..... @fmt_rdsj ++clo_w 0000 00000000 00000 00100 ..... ..... @fmt_rdrj ++clz_w 0000 00000000 00000 00101 ..... ..... @fmt_rdrj ++cto_w 0000 00000000 00000 00110 ..... ..... @fmt_rdrj ++ctz_w 0000 00000000 00000 00111 ..... ..... @fmt_rdrj ++clo_d 0000 00000000 00000 01000 ..... ..... @fmt_rdrj ++clz_d 0000 00000000 00000 01001 ..... ..... @fmt_rdrj ++cto_d 0000 00000000 00000 01010 ..... ..... @fmt_rdrj ++ctz_d 0000 00000000 00000 01011 ..... ..... @fmt_rdrj ++revb_2h 0000 00000000 00000 01100 ..... ..... @fmt_rdrj ++revb_4h 0000 00000000 00000 01101 ..... ..... @fmt_rdrj ++revb_2w 0000 00000000 00000 01110 ..... ..... @fmt_rdrj ++revb_d 0000 00000000 00000 01111 ..... ..... @fmt_rdrj ++revh_2w 0000 00000000 00000 10000 ..... ..... @fmt_rdrj ++revh_d 0000 00000000 00000 10001 ..... ..... @fmt_rdrj ++bitrev_4b 0000 00000000 00000 10010 ..... ..... @fmt_rdrj ++bitrev_8b 0000 00000000 00000 10011 ..... ..... @fmt_rdrj ++bitrev_w 0000 00000000 00000 10100 ..... ..... @fmt_rdrj ++bitrev_d 0000 00000000 00000 10101 ..... ..... @fmt_rdrj ++ext_w_h 0000 00000000 00000 10110 ..... ..... @fmt_rdrj ++ext_w_b 0000 00000000 00000 10111 ..... ..... @fmt_rdrj ++rdtime_d 0000 00000000 00000 11010 ..... ..... @fmt_rdrj ++cpucfg 0000 00000000 00000 11011 ..... ..... @fmt_rdrj ++asrtle_d 0000 00000000 00010 ..... ..... 00000 @fmt_rjrk ++asrtgt_d 0000 00000000 00011 ..... ..... 00000 @fmt_rjrk ++alsl_w 0000 00000000 010 .. ..... ..... ..... @fmt_rdrjrksa2 ++alsl_wu 0000 00000000 011 .. ..... ..... ..... @fmt_rdrjrksa2 ++bytepick_w 0000 00000000 100 .. ..... ..... ..... @fmt_rdrjrksa2 ++bytepick_d 0000 00000000 11 ... ..... ..... ..... @fmt_rdrjrksa3 ++add_w 0000 00000001 00000 ..... ..... ..... @fmt_rdrjrk ++add_d 0000 00000001 00001 ..... ..... ..... @fmt_rdrjrk ++sub_w 0000 00000001 00010 ..... ..... ..... @fmt_rdrjrk ++sub_d 0000 00000001 00011 ..... ..... ..... @fmt_rdrjrk ++slt 0000 00000001 00100 ..... ..... ..... @fmt_rdrjrk ++sltu 0000 00000001 00101 ..... ..... ..... @fmt_rdrjrk ++maskeqz 0000 00000001 00110 ..... ..... ..... @fmt_rdrjrk ++masknez 0000 00000001 00111 ..... ..... ..... @fmt_rdrjrk ++nor 0000 00000001 01000 ..... ..... ..... @fmt_rdrjrk ++and 0000 00000001 01001 ..... ..... ..... @fmt_rdrjrk ++or 0000 00000001 01010 ..... ..... ..... @fmt_rdrjrk ++xor 0000 00000001 01011 ..... ..... ..... @fmt_rdrjrk ++orn 0000 00000001 01100 ..... ..... ..... @fmt_rdrjrk ++andn 0000 00000001 01101 ..... ..... ..... @fmt_rdrjrk ++sll_w 0000 00000001 01110 ..... ..... ..... @fmt_rdrjrk ++srl_w 0000 00000001 01111 ..... ..... ..... @fmt_rdrjrk ++sra_w 0000 00000001 10000 ..... ..... ..... @fmt_rdrjrk ++sll_d 0000 00000001 10001 ..... ..... ..... @fmt_rdrjrk ++srl_d 0000 00000001 10010 ..... ..... ..... @fmt_rdrjrk ++sra_d 0000 00000001 10011 ..... ..... ..... @fmt_rdrjrk ++rotr_w 0000 00000001 10110 ..... ..... ..... @fmt_rdrjrk ++rotr_d 0000 00000001 10111 ..... ..... ..... @fmt_rdrjrk ++mul_w 0000 00000001 11000 ..... ..... ..... @fmt_rdrjrk ++mulh_w 0000 00000001 11001 ..... ..... ..... @fmt_rdrjrk ++mulh_wu 0000 00000001 11010 ..... ..... ..... @fmt_rdrjrk ++mul_d 0000 00000001 11011 ..... ..... ..... @fmt_rdrjrk ++mulh_d 0000 00000001 11100 ..... ..... ..... @fmt_rdrjrk ++mulh_du 0000 00000001 11101 ..... ..... ..... @fmt_rdrjrk ++mulw_d_w 0000 00000001 11110 ..... ..... ..... @fmt_rdrjrk ++mulw_d_wu 0000 00000001 11111 ..... ..... ..... @fmt_rdrjrk ++div_w 0000 00000010 00000 ..... ..... ..... @fmt_rdrjrk ++mod_w 0000 00000010 00001 ..... ..... ..... @fmt_rdrjrk ++div_wu 0000 00000010 00010 ..... ..... ..... @fmt_rdrjrk ++mod_wu 0000 00000010 00011 ..... ..... ..... @fmt_rdrjrk ++div_d 0000 00000010 00100 ..... ..... ..... @fmt_rdrjrk ++mod_d 0000 00000010 00101 ..... ..... ..... @fmt_rdrjrk ++div_du 0000 00000010 00110 ..... ..... ..... @fmt_rdrjrk ++mod_du 0000 00000010 00111 ..... ..... ..... @fmt_rdrjrk ++crc_w_b_w 0000 00000010 01000 ..... ..... ..... @fmt_rdrjrk ++crc_w_h_w 0000 00000010 01001 ..... ..... ..... @fmt_rdrjrk ++crc_w_w_w 0000 00000010 01010 ..... ..... ..... @fmt_rdrjrk ++crc_w_d_w 0000 00000010 01011 ..... ..... ..... @fmt_rdrjrk ++crcc_w_b_w 0000 00000010 01100 ..... ..... ..... @fmt_rdrjrk ++crcc_w_h_w 0000 00000010 01101 ..... ..... ..... @fmt_rdrjrk ++crcc_w_w_w 0000 00000010 01110 ..... ..... ..... @fmt_rdrjrk ++crcc_w_d_w 0000 00000010 01111 ..... ..... ..... @fmt_rdrjrk ++break 0000 00000010 10100 ............... @fmt_code ++dbcl 0000 00000010 10101 ............... @fmt_code ++syscall 0000 00000010 10110 ............... @fmt_code ++alsl_d 0000 00000010 110 .. ..... ..... ..... @fmt_rdrjrksa2 ++slli_w 0000 00000100 00001 ..... ..... ..... @fmt_rdrjui5 ++slli_d 0000 00000100 0001 ...... ..... ..... @fmt_rdrjui6 ++srli_w 0000 00000100 01001 ..... ..... ..... @fmt_rdrjui5 ++srli_d 0000 00000100 0101 ...... ..... ..... @fmt_rdrjui6 ++srai_w 0000 00000100 10001 ..... ..... ..... @fmt_rdrjui5 ++srai_d 0000 00000100 1001 ...... ..... ..... @fmt_rdrjui6 ++rotri_w 0000 00000100 11001 ..... ..... ..... @fmt_rdrjui5 ++rotri_d 0000 00000100 1101 ...... ..... ..... @fmt_rdrjui6 ++bstrins_w 0000 0000011 ..... 0 ..... ..... ..... @fmt_rdrjmsbwlsbw ++bstrpick_w 0000 0000011 ..... 1 ..... ..... ..... @fmt_rdrjmsbwlsbw ++bstrins_d 0000 000010 ...... ...... ..... ..... @fmt_rdrjmsbdlsbd ++bstrpick_d 0000 000011 ...... ...... ..... ..... @fmt_rdrjmsbdlsbd ++ ++# float Instructions ++fadd_s 0000 00010000 00001 ..... ..... ..... @fmt_fdfjfk ++fadd_d 0000 00010000 00010 ..... ..... ..... @fmt_fdfjfk ++fsub_s 0000 00010000 00101 ..... ..... ..... @fmt_fdfjfk ++fsub_d 0000 00010000 00110 ..... ..... ..... @fmt_fdfjfk ++fmul_s 0000 00010000 01001 ..... ..... ..... @fmt_fdfjfk ++fmul_d 0000 00010000 01010 ..... ..... ..... @fmt_fdfjfk ++fdiv_s 0000 00010000 01101 ..... ..... ..... @fmt_fdfjfk ++fdiv_d 0000 00010000 01110 ..... ..... ..... @fmt_fdfjfk ++fmax_s 0000 00010000 10001 ..... ..... ..... @fmt_fdfjfk ++fmax_d 0000 00010000 10010 ..... ..... ..... @fmt_fdfjfk ++fmin_s 0000 00010000 10101 ..... ..... ..... @fmt_fdfjfk ++fmin_d 0000 00010000 10110 ..... ..... ..... @fmt_fdfjfk ++fmaxa_s 0000 00010000 11001 ..... ..... ..... @fmt_fdfjfk ++fmaxa_d 0000 00010000 11010 ..... ..... ..... @fmt_fdfjfk ++fmina_s 0000 00010000 11101 ..... ..... ..... @fmt_fdfjfk ++fmina_d 0000 00010000 11110 ..... ..... ..... @fmt_fdfjfk ++fscaleb_s 0000 00010001 00001 ..... ..... ..... @fmt_fdfjfk ++fscaleb_d 0000 00010001 00010 ..... ..... ..... @fmt_fdfjfk ++fcopysign_s 0000 00010001 00101 ..... ..... ..... @fmt_fdfjfk ++fcopysign_d 0000 00010001 00110 ..... ..... ..... @fmt_fdfjfk ++fabs_s 0000 00010001 01000 00001 ..... ..... @fmt_fdfj ++fabs_d 0000 00010001 01000 00010 ..... ..... @fmt_fdfj ++fneg_s 0000 00010001 01000 00101 ..... ..... @fmt_fdfj ++fneg_d 0000 00010001 01000 00110 ..... ..... @fmt_fdfj ++flogb_s 0000 00010001 01000 01001 ..... ..... @fmt_fdfj ++flogb_d 0000 00010001 01000 01010 ..... ..... @fmt_fdfj ++fclass_s 0000 00010001 01000 01101 ..... ..... @fmt_fdfj ++fclass_d 0000 00010001 01000 01110 ..... ..... @fmt_fdfj ++fsqrt_s 0000 00010001 01000 10001 ..... ..... @fmt_fdfj ++fsqrt_d 0000 00010001 01000 10010 ..... ..... @fmt_fdfj ++frecip_s 0000 00010001 01000 10101 ..... ..... @fmt_fdfj ++frecip_d 0000 00010001 01000 10110 ..... ..... @fmt_fdfj ++frsqrt_s 0000 00010001 01000 11001 ..... ..... @fmt_fdfj ++frsqrt_d 0000 00010001 01000 11010 ..... ..... @fmt_fdfj ++fmov_s 0000 00010001 01001 00101 ..... ..... @fmt_fdfj ++fmov_d 0000 00010001 01001 00110 ..... ..... @fmt_fdfj ++movgr2fr_w 0000 00010001 01001 01001 ..... ..... @fmt_fdrj ++movgr2fr_d 0000 00010001 01001 01010 ..... ..... @fmt_fdrj ++movgr2frh_w 0000 00010001 01001 01011 ..... ..... @fmt_fdrj ++movfr2gr_s 0000 00010001 01001 01101 ..... ..... @fmt_rdfj ++movfr2gr_d 0000 00010001 01001 01110 ..... ..... @fmt_rdfj ++movfrh2gr_s 0000 00010001 01001 01111 ..... ..... @fmt_rdfj ++movgr2fcsr 0000 00010001 01001 10000 ..... ..... @fmt_fcsrdrj ++movfcsr2gr 0000 00010001 01001 10010 ..... ..... @fmt_rdfcsrs ++movfr2cf 0000 00010001 01001 10100 ..... 00 ... @fmt_cdfj ++movcf2fr 0000 00010001 01001 10101 00 ... ..... @fmt_fdcj ++movgr2cf 0000 00010001 01001 10110 ..... 00 ... @fmt_cdrj ++movcf2gr 0000 00010001 01001 10111 00 ... ..... @fmt_rdcj ++fcvt_s_d 0000 00010001 10010 00110 ..... ..... @fmt_fdfj ++fcvt_d_s 0000 00010001 10010 01001 ..... ..... @fmt_fdfj ++ftintrm_w_s 0000 00010001 10100 00001 ..... ..... @fmt_fdfj ++ftintrm_w_d 0000 00010001 10100 00010 ..... ..... @fmt_fdfj ++ftintrm_l_s 0000 00010001 10100 01001 ..... ..... @fmt_fdfj ++ftintrm_l_d 0000 00010001 10100 01010 ..... ..... @fmt_fdfj ++ftintrp_w_s 0000 00010001 10100 10001 ..... ..... @fmt_fdfj ++ftintrp_w_d 0000 00010001 10100 10010 ..... ..... @fmt_fdfj ++ftintrp_l_s 0000 00010001 10100 11001 ..... ..... @fmt_fdfj ++ftintrp_l_d 0000 00010001 10100 11010 ..... ..... @fmt_fdfj ++ftintrz_w_s 0000 00010001 10101 00001 ..... ..... @fmt_fdfj ++ftintrz_w_d 0000 00010001 10101 00010 ..... ..... @fmt_fdfj ++ftintrz_l_s 0000 00010001 10101 01001 ..... ..... @fmt_fdfj ++ftintrz_l_d 0000 00010001 10101 01010 ..... ..... @fmt_fdfj ++ftintrne_w_s 0000 00010001 10101 10001 ..... ..... @fmt_fdfj ++ftintrne_w_d 0000 00010001 10101 10010 ..... ..... @fmt_fdfj ++ftintrne_l_s 0000 00010001 10101 11001 ..... ..... @fmt_fdfj ++ftintrne_l_d 0000 00010001 10101 11010 ..... ..... @fmt_fdfj ++ftint_w_s 0000 00010001 10110 00001 ..... ..... @fmt_fdfj ++ftint_w_d 0000 00010001 10110 00010 ..... ..... @fmt_fdfj ++ftint_l_s 0000 00010001 10110 01001 ..... ..... @fmt_fdfj ++ftint_l_d 0000 00010001 10110 01010 ..... ..... @fmt_fdfj ++ffint_s_w 0000 00010001 11010 00100 ..... ..... @fmt_fdfj ++ffint_s_l 0000 00010001 11010 00110 ..... ..... @fmt_fdfj ++ffint_d_w 0000 00010001 11010 01000 ..... ..... @fmt_fdfj ++ffint_d_l 0000 00010001 11010 01010 ..... ..... @fmt_fdfj ++frint_s 0000 00010001 11100 10001 ..... ..... @fmt_fdfj ++frint_d 0000 00010001 11100 10010 ..... ..... @fmt_fdfj ++ ++# 12 bit immediate Instructions ++slti 0000 001000 ............ ..... ..... @fmt_rdrjsi12 ++sltui 0000 001001 ............ ..... ..... @fmt_rdrjsi12 ++addi_w 0000 001010 ............ ..... ..... @fmt_rdrjsi12 ++addi_d 0000 001011 ............ ..... ..... @fmt_rdrjsi12 ++lu52i_d 0000 001100 ............ ..... ..... @fmt_rdrjsi12 ++andi 0000 001101 ............ ..... ..... @fmt_rdrjui12 ++ori 0000 001110 ............ ..... ..... @fmt_rdrjui12 ++xori 0000 001111 ............ ..... ..... @fmt_rdrjui12 ++ ++# core Instructions ++csrxchg 0000 0100 .............. ..... ..... @fmt_rdrjcsr ++cacop 0000 011000 ............ ..... ..... @fmt_coprjsi12 ++lddir 0000 01100100 00 ........ ..... ..... @fmt_rdrjlevel ++ldpte 0000 01100100 01 ........ ..... 00000 @fmt_rjseq ++iocsrrd_b 0000 01100100 10000 00000 ..... ..... @fmt_rdrj ++iocsrrd_h 0000 01100100 10000 00001 ..... ..... @fmt_rdrj ++iocsrrd_w 0000 01100100 10000 00010 ..... ..... @fmt_rdrj ++iocsrrd_d 0000 01100100 10000 00011 ..... ..... @fmt_rdrj ++iocsrwr_b 0000 01100100 10000 00100 ..... ..... @fmt_rdrj ++iocsrwr_h 0000 01100100 10000 00101 ..... ..... @fmt_rdrj ++iocsrwr_w 0000 01100100 10000 00110 ..... ..... @fmt_rdrj ++iocsrwr_d 0000 01100100 10000 00111 ..... ..... @fmt_rdrj ++tlbclr 0000 01100100 10000 01000 00000 00000 @fmt_empty ++tlbflush 0000 01100100 10000 01001 00000 00000 @fmt_empty ++tlbsrch 0000 01100100 10000 01010 00000 00000 @fmt_empty ++tlbrd 0000 01100100 10000 01011 00000 00000 @fmt_empty ++tlbwr 0000 01100100 10000 01100 00000 00000 @fmt_empty ++tlbfill 0000 01100100 10000 01101 00000 00000 @fmt_empty ++ertn 0000 01100100 10000 01110 00000 00000 @fmt_empty ++idle 0000 01100100 10001 ............... @fmt_whint ++invtlb 0000 01100100 10011 ..... ..... ..... @fmt_invtlb ++ ++# foure Op Instructions ++fmadd_s 0000 10000001 ..... ..... ..... ..... @fmt_fdfjfkfa ++fmadd_d 0000 10000010 ..... ..... ..... ..... @fmt_fdfjfkfa ++fmsub_s 0000 10000101 ..... ..... ..... ..... @fmt_fdfjfkfa ++fmsub_d 0000 10000110 ..... ..... ..... ..... @fmt_fdfjfkfa ++fnmadd_s 0000 10001001 ..... ..... ..... ..... @fmt_fdfjfkfa ++fnmadd_d 0000 10001010 ..... ..... ..... ..... @fmt_fdfjfkfa ++fnmsub_s 0000 10001101 ..... ..... ..... ..... @fmt_fdfjfkfa ++fnmsub_d 0000 10001110 ..... ..... ..... ..... @fmt_fdfjfkfa ++fcmp_cond_s 0000 11000001 ..... ..... ..... 00 ... @fmt_cdfjfkfcond ++fcmp_cond_d 0000 11000010 ..... ..... ..... 00 ... @fmt_cdfjfkfcond ++fsel 0000 11010000 00 ... ..... ..... ..... @fmt_fdfjfkca ++ ++# loog immediate Instructions ++addu16i_d 0001 00 ................ ..... ..... @fmt_rdrjsi16 ++lu12i_w 0001 010 .................... ..... @fmt_rdsi20 ++lu32i_d 0001 011 .................... ..... @fmt_rdsi20 ++pcaddi 0001 100 .................... ..... @fmt_rdsi20 ++pcalau12i 0001 101 .................... ..... @fmt_rdsi20 ++pcaddu12i 0001 110 .................... ..... @fmt_rdsi20 ++pcaddu18i 0001 111 .................... ..... @fmt_rdsi20 ++ ++# load/store Instructions ++ll_w 0010 0000 .............. ..... ..... @fmt_rdrjsi14 ++sc_w 0010 0001 .............. ..... ..... @fmt_rdrjsi14 ++ll_d 0010 0010 .............. ..... ..... @fmt_rdrjsi14 ++sc_d 0010 0011 .............. ..... ..... @fmt_rdrjsi14 ++ldptr_w 0010 0100 .............. ..... ..... @fmt_rdrjsi14 ++stptr_w 0010 0101 .............. ..... ..... @fmt_rdrjsi14 ++ldptr_d 0010 0110 .............. ..... ..... @fmt_rdrjsi14 ++stptr_d 0010 0111 .............. ..... ..... @fmt_rdrjsi14 ++ld_b 0010 100000 ............ ..... ..... @fmt_rdrjsi12 ++ld_h 0010 100001 ............ ..... ..... @fmt_rdrjsi12 ++ld_w 0010 100010 ............ ..... ..... @fmt_rdrjsi12 ++ld_d 0010 100011 ............ ..... ..... @fmt_rdrjsi12 ++st_b 0010 100100 ............ ..... ..... @fmt_rdrjsi12 ++st_h 0010 100101 ............ ..... ..... @fmt_rdrjsi12 ++st_w 0010 100110 ............ ..... ..... @fmt_rdrjsi12 ++st_d 0010 100111 ............ ..... ..... @fmt_rdrjsi12 ++ld_bu 0010 101000 ............ ..... ..... @fmt_rdrjsi12 ++ld_hu 0010 101001 ............ ..... ..... @fmt_rdrjsi12 ++ld_wu 0010 101010 ............ ..... ..... @fmt_rdrjsi12 ++preld 0010 101011 ............ ..... ..... @fmt_hintrjsi12 ++fld_s 0010 101100 ............ ..... ..... @fmt_fdrjsi12 ++fst_s 0010 101101 ............ ..... ..... @fmt_fdrjsi12 ++fld_d 0010 101110 ............ ..... ..... @fmt_fdrjsi12 ++fst_d 0010 101111 ............ ..... ..... @fmt_fdrjsi12 ++ldx_b 0011 10000000 00000 ..... ..... ..... @fmt_rdrjrk ++ldx_h 0011 10000000 01000 ..... ..... ..... @fmt_rdrjrk ++ldx_w 0011 10000000 10000 ..... ..... ..... @fmt_rdrjrk ++ldx_d 0011 10000000 11000 ..... ..... ..... @fmt_rdrjrk ++stx_b 0011 10000001 00000 ..... ..... ..... @fmt_rdrjrk ++stx_h 0011 10000001 01000 ..... ..... ..... @fmt_rdrjrk ++stx_w 0011 10000001 10000 ..... ..... ..... @fmt_rdrjrk ++stx_d 0011 10000001 11000 ..... ..... ..... @fmt_rdrjrk ++ldx_bu 0011 10000010 00000 ..... ..... ..... @fmt_rdrjrk ++ldx_hu 0011 10000010 01000 ..... ..... ..... @fmt_rdrjrk ++ldx_wu 0011 10000010 10000 ..... ..... ..... @fmt_rdrjrk ++fldx_s 0011 10000011 00000 ..... ..... ..... @fmt_fdrjrk ++fldx_d 0011 10000011 01000 ..... ..... ..... @fmt_fdrjrk ++fstx_s 0011 10000011 10000 ..... ..... ..... @fmt_fdrjrk ++fstx_d 0011 10000011 11000 ..... ..... ..... @fmt_fdrjrk ++amswap_w 0011 10000110 00000 ..... ..... ..... @fmt_rdrjrk ++amswap_d 0011 10000110 00001 ..... ..... ..... @fmt_rdrjrk ++amadd_w 0011 10000110 00010 ..... ..... ..... @fmt_rdrjrk ++amadd_d 0011 10000110 00011 ..... ..... ..... @fmt_rdrjrk ++amand_w 0011 10000110 00100 ..... ..... ..... @fmt_rdrjrk ++amand_d 0011 10000110 00101 ..... ..... ..... @fmt_rdrjrk ++amor_w 0011 10000110 00110 ..... ..... ..... @fmt_rdrjrk ++amor_d 0011 10000110 00111 ..... ..... ..... @fmt_rdrjrk ++amxor_w 0011 10000110 01000 ..... ..... ..... @fmt_rdrjrk ++amxor_d 0011 10000110 01001 ..... ..... ..... @fmt_rdrjrk ++ammax_w 0011 10000110 01010 ..... ..... ..... @fmt_rdrjrk ++ammax_d 0011 10000110 01011 ..... ..... ..... @fmt_rdrjrk ++ammin_w 0011 10000110 01100 ..... ..... ..... @fmt_rdrjrk ++ammin_d 0011 10000110 01101 ..... ..... ..... @fmt_rdrjrk ++ammax_wu 0011 10000110 01110 ..... ..... ..... @fmt_rdrjrk ++ammax_du 0011 10000110 01111 ..... ..... ..... @fmt_rdrjrk ++ammin_wu 0011 10000110 10000 ..... ..... ..... @fmt_rdrjrk ++ammin_du 0011 10000110 10001 ..... ..... ..... @fmt_rdrjrk ++amswap_db_w 0011 10000110 10010 ..... ..... ..... @fmt_rdrjrk ++amswap_db_d 0011 10000110 10011 ..... ..... ..... @fmt_rdrjrk ++amadd_db_w 0011 10000110 10100 ..... ..... ..... @fmt_rdrjrk ++amadd_db_d 0011 10000110 10101 ..... ..... ..... @fmt_rdrjrk ++amand_db_w 0011 10000110 10110 ..... ..... ..... @fmt_rdrjrk ++amand_db_d 0011 10000110 10111 ..... ..... ..... @fmt_rdrjrk ++amor_db_w 0011 10000110 11000 ..... ..... ..... @fmt_rdrjrk ++amor_db_d 0011 10000110 11001 ..... ..... ..... @fmt_rdrjrk ++amxor_db_w 0011 10000110 11010 ..... ..... ..... @fmt_rdrjrk ++amxor_db_d 0011 10000110 11011 ..... ..... ..... @fmt_rdrjrk ++ammax_db_w 0011 10000110 11100 ..... ..... ..... @fmt_rdrjrk ++ammax_db_d 0011 10000110 11101 ..... ..... ..... @fmt_rdrjrk ++ammin_db_w 0011 10000110 11110 ..... ..... ..... @fmt_rdrjrk ++ammin_db_d 0011 10000110 11111 ..... ..... ..... @fmt_rdrjrk ++ammax_db_wu 0011 10000111 00000 ..... ..... ..... @fmt_rdrjrk ++ammax_db_du 0011 10000111 00001 ..... ..... ..... @fmt_rdrjrk ++ammin_db_wu 0011 10000111 00010 ..... ..... ..... @fmt_rdrjrk ++ammin_db_du 0011 10000111 00011 ..... ..... ..... @fmt_rdrjrk ++dbar 0011 10000111 00100 ............... @fmt_whint ++ibar 0011 10000111 00101 ............... @fmt_whint ++fldgt_s 0011 10000111 01000 ..... ..... ..... @fmt_fdrjrk ++fldgt_d 0011 10000111 01001 ..... ..... ..... @fmt_fdrjrk ++fldle_s 0011 10000111 01010 ..... ..... ..... @fmt_fdrjrk ++fldle_d 0011 10000111 01011 ..... ..... ..... @fmt_fdrjrk ++fstgt_s 0011 10000111 01100 ..... ..... ..... @fmt_fdrjrk ++fstgt_d 0011 10000111 01101 ..... ..... ..... @fmt_fdrjrk ++fstle_s 0011 10000111 01110 ..... ..... ..... @fmt_fdrjrk ++fstle_d 0011 10000111 01111 ..... ..... ..... @fmt_fdrjrk ++ldgt_b 0011 10000111 10000 ..... ..... ..... @fmt_rdrjrk ++ldgt_h 0011 10000111 10001 ..... ..... ..... @fmt_rdrjrk ++ldgt_w 0011 10000111 10010 ..... ..... ..... @fmt_rdrjrk ++ldgt_d 0011 10000111 10011 ..... ..... ..... @fmt_rdrjrk ++ldle_b 0011 10000111 10100 ..... ..... ..... @fmt_rdrjrk ++ldle_h 0011 10000111 10101 ..... ..... ..... @fmt_rdrjrk ++ldle_w 0011 10000111 10110 ..... ..... ..... @fmt_rdrjrk ++ldle_d 0011 10000111 10111 ..... ..... ..... @fmt_rdrjrk ++stgt_b 0011 10000111 11000 ..... ..... ..... @fmt_rdrjrk ++stgt_h 0011 10000111 11001 ..... ..... ..... @fmt_rdrjrk ++stgt_w 0011 10000111 11010 ..... ..... ..... @fmt_rdrjrk ++stgt_d 0011 10000111 11011 ..... ..... ..... @fmt_rdrjrk ++stle_b 0011 10000111 11100 ..... ..... ..... @fmt_rdrjrk ++stle_h 0011 10000111 11101 ..... ..... ..... @fmt_rdrjrk ++stle_w 0011 10000111 11110 ..... ..... ..... @fmt_rdrjrk ++stle_d 0011 10000111 11111 ..... ..... ..... @fmt_rdrjrk ++ ++# jump Instructions ++beqz 0100 00 ................ ..... ..... @fmt_rjoffs21 ++bnez 0100 01 ................ ..... ..... @fmt_rjoffs21 ++bceqz 0100 10 ................ 00 ... ..... @fmt_cjoffs21 ++bcnez 0100 10 ................ 01 ... ..... @fmt_cjoffs21 ++jirl 0100 11 ................ ..... ..... @fmt_rdrjoffs16 ++b 0101 00 .......................... @fmt_offs ++bl 0101 01 .......................... @fmt_offs ++beq 0101 10 ................ ..... ..... @fmt_rjrdoffs16 ++bne 0101 11 ................ ..... ..... @fmt_rjrdoffs16 ++blt 0110 00 ................ ..... ..... @fmt_rjrdoffs16 ++bge 0110 01 ................ ..... ..... @fmt_rjrdoffs16 ++bltu 0110 10 ................ ..... ..... @fmt_rjrdoffs16 ++bgeu 0110 11 ................ ..... ..... @fmt_rjrdoffs16 +diff --git a/target/loongarch64/instmap.h b/target/loongarch64/instmap.h +new file mode 100644 +index 0000000000..6e85847f8a +--- /dev/null ++++ b/target/loongarch64/instmap.h +@@ -0,0 +1,216 @@ ++/* ++ * Loongarch emulation for qemu: instruction opcode ++ * ++ * Copyright (c) 2020-2021 ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2 or later, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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 . ++ */ ++ ++#ifndef TARGET_LARCH_INSTMAP_H ++#define TARGET_LARCH_INSTMAP_H ++ ++enum { ++ /* fix opcodes */ ++ OPC_LARCH_CLO_W = (0x000004 << 10), ++ OPC_LARCH_CLZ_W = (0x000005 << 10), ++ OPC_LARCH_CLO_D = (0x000008 << 10), ++ OPC_LARCH_CLZ_D = (0x000009 << 10), ++ OPC_LARCH_REVB_2H = (0x00000C << 10), ++ OPC_LARCH_REVB_4H = (0x00000D << 10), ++ OPC_LARCH_REVH_D = (0x000011 << 10), ++ OPC_LARCH_BREV_4B = (0x000012 << 10), ++ OPC_LARCH_BREV_8B = (0x000013 << 10), ++ OPC_LARCH_EXT_WH = (0x000016 << 10), ++ OPC_LARCH_EXT_WB = (0x000017 << 10), ++ ++ OPC_LARCH_ADD_W = (0x00020 << 15), ++ OPC_LARCH_ADD_D = (0x00021 << 15), ++ OPC_LARCH_SUB_W = (0x00022 << 15), ++ OPC_LARCH_SUB_D = (0x00023 << 15), ++ OPC_LARCH_SLT = (0x00024 << 15), ++ OPC_LARCH_SLTU = (0x00025 << 15), ++ OPC_LARCH_MASKEQZ = (0x00026 << 15), ++ OPC_LARCH_MASKNEZ = (0x00027 << 15), ++ OPC_LARCH_NOR = (0x00028 << 15), ++ OPC_LARCH_AND = (0x00029 << 15), ++ OPC_LARCH_OR = (0x0002A << 15), ++ OPC_LARCH_XOR = (0x0002B << 15), ++ OPC_LARCH_SLL_W = (0x0002E << 15), ++ OPC_LARCH_SRL_W = (0x0002F << 15), ++ OPC_LARCH_SRA_W = (0x00030 << 15), ++ OPC_LARCH_SLL_D = (0x00031 << 15), ++ OPC_LARCH_SRL_D = (0x00032 << 15), ++ OPC_LARCH_SRA_D = (0x00033 << 15), ++ OPC_LARCH_ROTR_W = (0x00036 << 15), ++ OPC_LARCH_ROTR_D = (0x00037 << 15), ++ OPC_LARCH_MUL_W = (0x00038 << 15), ++ OPC_LARCH_MULH_W = (0x00039 << 15), ++ OPC_LARCH_MULH_WU = (0x0003A << 15), ++ OPC_LARCH_MUL_D = (0x0003B << 15), ++ OPC_LARCH_MULH_D = (0x0003C << 15), ++ OPC_LARCH_MULH_DU = (0x0003D << 15), ++ OPC_LARCH_DIV_W = (0x00040 << 15), ++ OPC_LARCH_MOD_W = (0x00041 << 15), ++ OPC_LARCH_DIV_WU = (0x00042 << 15), ++ OPC_LARCH_MOD_WU = (0x00043 << 15), ++ OPC_LARCH_DIV_D = (0x00044 << 15), ++ OPC_LARCH_MOD_D = (0x00045 << 15), ++ OPC_LARCH_DIV_DU = (0x00046 << 15), ++ OPC_LARCH_MOD_DU = (0x00047 << 15), ++ OPC_LARCH_SRLI_W = (0x00089 << 15), ++ OPC_LARCH_SRAI_W = (0x00091 << 15), ++ OPC_LARCH_ROTRI_W = (0x00099 << 15), ++ ++ OPC_LARCH_ALSL_W = (0x0002 << 17), ++ OPC_LARCH_ALSL_D = (0x0016 << 17), ++ ++ OPC_LARCH_TRINS_W = (0x003 << 21) | (0x0 << 15), ++ OPC_LARCH_TRPICK_W = (0x003 << 21) | (0x1 << 15), ++}; ++ ++enum { ++ /* float opcodes */ ++ OPC_LARCH_FABS_S = (0x004501 << 10), ++ OPC_LARCH_FABS_D = (0x004502 << 10), ++ OPC_LARCH_FNEG_S = (0x004505 << 10), ++ OPC_LARCH_FNEG_D = (0x004506 << 10), ++ OPC_LARCH_FCLASS_S = (0x00450D << 10), ++ OPC_LARCH_FCLASS_D = (0x00450E << 10), ++ OPC_LARCH_FSQRT_S = (0x004511 << 10), ++ OPC_LARCH_FSQRT_D = (0x004512 << 10), ++ OPC_LARCH_FRECIP_S = (0x004515 << 10), ++ OPC_LARCH_FRECIP_D = (0x004516 << 10), ++ OPC_LARCH_FRSQRT_S = (0x004519 << 10), ++ OPC_LARCH_FRSQRT_D = (0x00451A << 10), ++ OPC_LARCH_FMOV_S = (0x004525 << 10), ++ OPC_LARCH_FMOV_D = (0x004526 << 10), ++ OPC_LARCH_GR2FR_W = (0x004529 << 10), ++ OPC_LARCH_GR2FR_D = (0x00452A << 10), ++ OPC_LARCH_GR2FRH_W = (0x00452B << 10), ++ OPC_LARCH_FR2GR_S = (0x00452D << 10), ++ OPC_LARCH_FR2GR_D = (0x00452E << 10), ++ OPC_LARCH_FRH2GR_S = (0x00452F << 10), ++ ++ OPC_LARCH_FCVT_S_D = (0x004646 << 10), ++ OPC_LARCH_FCVT_D_S = (0x004649 << 10), ++ OPC_LARCH_FTINTRM_W_S = (0x004681 << 10), ++ OPC_LARCH_FTINTRM_W_D = (0x004682 << 10), ++ OPC_LARCH_FTINTRM_L_S = (0x004689 << 10), ++ OPC_LARCH_FTINTRM_L_D = (0x00468A << 10), ++ OPC_LARCH_FTINTRP_W_S = (0x004691 << 10), ++ OPC_LARCH_FTINTRP_W_D = (0x004692 << 10), ++ OPC_LARCH_FTINTRP_L_S = (0x004699 << 10), ++ OPC_LARCH_FTINTRP_L_D = (0x00469A << 10), ++ OPC_LARCH_FTINTRZ_W_S = (0x0046A1 << 10), ++ OPC_LARCH_FTINTRZ_W_D = (0x0046A2 << 10), ++ OPC_LARCH_FTINTRZ_L_S = (0x0046A9 << 10), ++ OPC_LARCH_FTINTRZ_L_D = (0x0046AA << 10), ++ OPC_LARCH_FTINTRNE_W_S = (0x0046B1 << 10), ++ OPC_LARCH_FTINTRNE_W_D = (0x0046B2 << 10), ++ OPC_LARCH_FTINTRNE_L_S = (0x0046B9 << 10), ++ OPC_LARCH_FTINTRNE_L_D = (0x0046BA << 10), ++ OPC_LARCH_FTINT_W_S = (0x0046C1 << 10), ++ OPC_LARCH_FTINT_W_D = (0x0046C2 << 10), ++ OPC_LARCH_FTINT_L_S = (0x0046C9 << 10), ++ OPC_LARCH_FTINT_L_D = (0x0046CA << 10), ++ OPC_LARCH_FFINT_S_W = (0x004744 << 10), ++ OPC_LARCH_FFINT_S_L = (0x004746 << 10), ++ OPC_LARCH_FFINT_D_W = (0x004748 << 10), ++ OPC_LARCH_FFINT_D_L = (0x00474A << 10), ++ OPC_LARCH_FRINT_S = (0x004791 << 10), ++ OPC_LARCH_FRINT_D = (0x004792 << 10), ++ ++ OPC_LARCH_FADD_S = (0x00201 << 15), ++ OPC_LARCH_FADD_D = (0x00202 << 15), ++ OPC_LARCH_FSUB_S = (0x00205 << 15), ++ OPC_LARCH_FSUB_D = (0x00206 << 15), ++ OPC_LARCH_FMUL_S = (0x00209 << 15), ++ OPC_LARCH_FMUL_D = (0x0020A << 15), ++ OPC_LARCH_FDIV_S = (0x0020D << 15), ++ OPC_LARCH_FDIV_D = (0x0020E << 15), ++ OPC_LARCH_FMAX_S = (0x00211 << 15), ++ OPC_LARCH_FMAX_D = (0x00212 << 15), ++ OPC_LARCH_FMIN_S = (0x00215 << 15), ++ OPC_LARCH_FMIN_D = (0x00216 << 15), ++ OPC_LARCH_FMAXA_S = (0x00219 << 15), ++ OPC_LARCH_FMAXA_D = (0x0021A << 15), ++ OPC_LARCH_FMINA_S = (0x0021D << 15), ++ OPC_LARCH_FMINA_D = (0x0021E << 15), ++}; ++ ++enum { ++ /* 12 bit immediate opcodes */ ++ OPC_LARCH_SLTI = (0x008 << 22), ++ OPC_LARCH_SLTIU = (0x009 << 22), ++ OPC_LARCH_ADDI_W = (0x00A << 22), ++ OPC_LARCH_ADDI_D = (0x00B << 22), ++ OPC_LARCH_ANDI = (0x00D << 22), ++ OPC_LARCH_ORI = (0x00E << 22), ++ OPC_LARCH_XORI = (0x00F << 22), ++}; ++ ++enum { ++ /* load/store opcodes */ ++ OPC_LARCH_FLDX_S = (0x07060 << 15), ++ OPC_LARCH_FLDX_D = (0x07068 << 15), ++ OPC_LARCH_FSTX_S = (0x07070 << 15), ++ OPC_LARCH_FSTX_D = (0x07078 << 15), ++ OPC_LARCH_FLDGT_S = (0x070E8 << 15), ++ OPC_LARCH_FLDGT_D = (0x070E9 << 15), ++ OPC_LARCH_FLDLE_S = (0x070EA << 15), ++ OPC_LARCH_FLDLE_D = (0x070EB << 15), ++ OPC_LARCH_FSTGT_S = (0x070EC << 15), ++ OPC_LARCH_FSTGT_D = (0x070ED << 15), ++ OPC_LARCH_FSTLE_S = (0x070EE << 15), ++ OPC_LARCH_FSTLE_D = (0x070EF << 15), ++ ++ OPC_LARCH_LD_B = (0x0A0 << 22), ++ OPC_LARCH_LD_H = (0x0A1 << 22), ++ OPC_LARCH_LD_W = (0x0A2 << 22), ++ OPC_LARCH_LD_D = (0x0A3 << 22), ++ OPC_LARCH_ST_B = (0x0A4 << 22), ++ OPC_LARCH_ST_H = (0x0A5 << 22), ++ OPC_LARCH_ST_W = (0x0A6 << 22), ++ OPC_LARCH_ST_D = (0x0A7 << 22), ++ OPC_LARCH_LD_BU = (0x0A8 << 22), ++ OPC_LARCH_LD_HU = (0x0A9 << 22), ++ OPC_LARCH_LD_WU = (0x0AA << 22), ++ OPC_LARCH_FLD_S = (0x0AC << 22), ++ OPC_LARCH_FST_S = (0x0AD << 22), ++ OPC_LARCH_FLD_D = (0x0AE << 22), ++ OPC_LARCH_FST_D = (0x0AF << 22), ++ ++ OPC_LARCH_LL_W = (0x20 << 24), ++ OPC_LARCH_SC_W = (0x21 << 24), ++ OPC_LARCH_LL_D = (0x22 << 24), ++ OPC_LARCH_SC_D = (0x23 << 24), ++ OPC_LARCH_LDPTR_W = (0x24 << 24), ++ OPC_LARCH_STPTR_W = (0x25 << 24), ++ OPC_LARCH_LDPTR_D = (0x26 << 24), ++ OPC_LARCH_STPTR_D = (0x27 << 24), ++}; ++ ++enum { ++ /* jump opcodes */ ++ OPC_LARCH_BEQZ = (0x10 << 26), ++ OPC_LARCH_BNEZ = (0x11 << 26), ++ OPC_LARCH_B = (0x14 << 26), ++ OPC_LARCH_BEQ = (0x16 << 26), ++ OPC_LARCH_BNE = (0x17 << 26), ++ OPC_LARCH_BLT = (0x18 << 26), ++ OPC_LARCH_BGE = (0x19 << 26), ++ OPC_LARCH_BLTU = (0x1A << 26), ++ OPC_LARCH_BGEU = (0x1B << 26), ++}; ++ ++#endif +diff --git a/target/loongarch64/internal.h b/target/loongarch64/internal.h +new file mode 100644 +index 0000000000..79a70e9d26 +--- /dev/null ++++ b/target/loongarch64/internal.h +@@ -0,0 +1,184 @@ ++#ifndef LOONGARCH_INTERNAL_H ++#define LOONGARCH_INTERNAL_H ++ ++#include "cpu-csr.h" ++ ++/* MMU types, the first four entries have the same layout as the ++ CP0C0_MT field. */ ++enum loongarch_mmu_types { ++ MMU_TYPE_NONE, ++ MMU_TYPE_LS3A5K, /* LISA CSR */ ++}; ++ ++ ++ ++struct loongarch_def_t { ++ const char *name; ++ int32_t CSR_PRid; ++ int32_t FCSR0; ++ int32_t FCSR0_rw_bitmask; ++ int32_t PABITS; ++ CPU_LOONGARCH_CSR ++ uint64_t insn_flags; ++ enum loongarch_mmu_types mmu_type; ++ int cpu_cfg[64]; ++}; ++ ++/* loongarch 3a5000 TLB entry */ ++struct ls3a5k_tlb_t { ++ target_ulong VPN; ++ uint64_t PageMask; /* CSR_TLBIDX[29:24] */ ++ uint32_t PageSize; ++ uint16_t ASID; ++ unsigned int G:1; /* CSR_TLBLO[6] */ ++ ++ unsigned int C0:3; /* CSR_TLBLO[5:4] */ ++ unsigned int C1:3; ++ ++ unsigned int V0:1; /* CSR_TLBLO[0] */ ++ unsigned int V1:1; ++ ++ unsigned int WE0:1; /* CSR_TLBLO[1] */ ++ unsigned int WE1:1; ++ ++ unsigned int XI0:1; /* CSR_TLBLO[62] */ ++ unsigned int XI1:1; ++ ++ unsigned int RI0:1; /* CSR_TLBLO[61] */ ++ unsigned int RI1:1; ++ ++ unsigned int EHINV:1;/* CSR_TLBIDX[31] */ ++ ++ unsigned int PLV0:2; /* CSR_TLBLO[3:2] */ ++ unsigned int PLV1:2; ++ ++ unsigned int RPLV0:1; ++ unsigned int RPLV1:1; /* CSR_TLBLO[63] */ ++ ++ uint64_t PPN0; /* CSR_TLBLO[47:12] */ ++ uint64_t PPN1; /* CSR_TLBLO[47:12] */ ++}; ++typedef struct ls3a5k_tlb_t ls3a5k_tlb_t; ++ ++ ++struct CPULOONGARCHTLBContext { ++ uint32_t nb_tlb; ++ uint32_t tlb_in_use; ++ int (*map_address)(struct CPULOONGARCHState *env, hwaddr *physical, int *prot, ++ target_ulong address, int rw, int access_type); ++ void (*helper_tlbwr)(struct CPULOONGARCHState *env); ++ void (*helper_tlbfill)(struct CPULOONGARCHState *env); ++ void (*helper_tlbsrch)(struct CPULOONGARCHState *env); ++ void (*helper_tlbrd)(struct CPULOONGARCHState *env); ++ void (*helper_tlbclr)(struct CPULOONGARCHState *env); ++ void (*helper_tlbflush)(struct CPULOONGARCHState *env); ++ void (*helper_invtlb)(struct CPULOONGARCHState *env, target_ulong addr, ++ target_ulong info, int op); ++ union { ++ struct { ++ uint64_t ftlb_mask; ++ uint32_t ftlb_size; /* at most : 8 * 256 = 2048 */ ++ uint32_t vtlb_size; /* at most : 64 */ ++ ls3a5k_tlb_t tlb[2048 + 64]; /* at most : 2048 FTLB + 64 VTLB */ ++ } ls3a5k; ++ } mmu; ++}; ++ ++enum { ++ TLBRET_PE = -7, ++ TLBRET_XI = -6, ++ TLBRET_RI = -5, ++ TLBRET_DIRTY = -4, ++ TLBRET_INVALID = -3, ++ TLBRET_NOMATCH = -2, ++ TLBRET_BADADDR = -1, ++ TLBRET_MATCH = 0 ++}; ++ ++ ++extern unsigned int ieee_rm[]; ++ ++static inline void restore_rounding_mode(CPULOONGARCHState *env) ++{ ++ set_float_rounding_mode(ieee_rm[(env->active_fpu.fcsr0 >> FCSR0_RM) & 0x3], ++ &env->active_fpu.fp_status); ++} ++ ++static inline void restore_flush_mode(CPULOONGARCHState *env) ++{ ++ set_flush_to_zero(0, &env->active_fpu.fp_status); ++} ++ ++static inline void restore_fp_status(CPULOONGARCHState *env) ++{ ++ restore_rounding_mode(env); ++ restore_flush_mode(env); ++} ++static inline void compute_hflags(CPULOONGARCHState *env) ++{ ++ env->hflags &= ~(LARCH_HFLAG_64 | LARCH_HFLAG_FPU | LARCH_HFLAG_KSU | ++ LARCH_HFLAG_AWRAP | LARCH_HFLAG_LSX | LARCH_HFLAG_LASX); ++ ++ env->hflags |= (env->CSR_CRMD & CSR_CRMD_PLV); ++ env->hflags |= LARCH_HFLAG_64; ++ ++ if (env->CSR_EUEN & CSR_EUEN_FPEN) { ++ env->hflags |= LARCH_HFLAG_FPU; ++ } ++ if (env->CSR_EUEN & CSR_EUEN_LSXEN) { ++ env->hflags |= LARCH_HFLAG_LSX; ++ } ++ if (env->CSR_EUEN & CSR_EUEN_LASXEN) { ++ env->hflags |= LARCH_HFLAG_LASX; ++ } ++ if (env->CSR_EUEN & CSR_EUEN_LBTEN) { ++ env->hflags |= LARCH_HFLAG_LBT; ++ } ++} ++ ++/* Check if there is pending and not masked out interrupt */ ++static inline bool cpu_loongarch_hw_interrupts_pending(CPULOONGARCHState *env) ++{ ++ int32_t pending; ++ int32_t status; ++ bool r; ++ ++ pending = env->CSR_ESTAT & CSR_ESTAT_IPMASK; ++ status = env->CSR_ECFG & CSR_ECFG_IPMASK; ++ ++ /* Configured with compatibility or VInt (Vectored Interrupts) ++ treats the pending lines as individual interrupt lines, the status ++ lines are individual masks. */ ++ r = (pending & status) != 0; ++ ++ return r; ++} ++ ++ ++/* stabletimer.c */ ++uint32_t cpu_loongarch_get_random_ls3a5k_tlb(uint32_t low, uint32_t high); ++uint64_t cpu_loongarch_get_stable_counter(CPULOONGARCHState *env); ++uint64_t cpu_loongarch_get_stable_timer_ticks(CPULOONGARCHState *env); ++void cpu_loongarch_store_stable_timer_config(CPULOONGARCHState *env, uint64_t value); ++int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, ++ int cpuid, void *opaque); ++ ++void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags); ++ ++/* TODO QOM'ify CPU reset and remove */ ++void cpu_state_reset(CPULOONGARCHState *s); ++void cpu_loongarch_realize_env(CPULOONGARCHState *env); ++ ++int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n); ++int loongarch_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); ++ ++#ifdef CONFIG_TCG ++#include "fpu_helper.h" ++#endif ++ ++#ifndef CONFIG_USER_ONLY ++extern const struct VMStateDescription vmstate_loongarch_cpu; ++hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); ++#endif ++ ++#endif +diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c +new file mode 100644 +index 0000000000..404a605eb6 +--- /dev/null ++++ b/target/loongarch64/kvm.c +@@ -0,0 +1,1622 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * KVM/LOONGARCH: LOONGARCH specific KVM APIs ++ * ++ * Copyright (C) 2012-2014 Imagination Technologies Ltd. ++ * Authors: Sanjay Lal ++*/ ++ ++#include "qemu/osdep.h" ++#include ++ ++#include ++ ++#include "qemu-common.h" ++#include "cpu.h" ++#include "internal.h" ++#include "qemu/error-report.h" ++#include "qemu/timer.h" ++#include "qemu/main-loop.h" ++#include "sysemu/sysemu.h" ++#include "sysemu/kvm.h" ++#include "sysemu/runstate.h" ++#include "sysemu/cpus.h" ++#include "kvm_larch.h" ++#include "exec/memattrs.h" ++#include "exec/gdbstub.h" ++ ++#define DEBUG_KVM 0 ++/* A 16384-byte buffer can hold the 8-byte kvm_msrs header, plus ++ * 2047 kvm_msr_entry structs */ ++#define MSR_BUF_SIZE 16384 ++ ++#define DPRINTF(fmt, ...) \ ++ do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0) ++ ++/* ++ * Define loongarch kvm version. ++ * Add version number when ++ * qemu/kvm interface changed ++ */ ++#define KVM_LOONGARCH_VERSION 1 ++ ++static struct { ++ target_ulong addr; ++ int len; ++ int type; ++} inst_breakpoint[8], data_breakpoint[8]; ++ ++int nb_data_breakpoint = 0, nb_inst_breakpoint = 0; ++static int kvm_loongarch_version_cap; ++ ++/* Hardware breakpoint control register ++ * 4:1 plv0-plv3 enable ++ * 6:5 config virtualization mode ++ * 9:8 load store */ ++static const int type_code[] = { ++ [GDB_BREAKPOINT_HW] = 0x5e, ++ [GDB_WATCHPOINT_READ] = (0x5e | 1 << 8), ++ [GDB_WATCHPOINT_WRITE] = (0x5e | 1 << 9), ++ [GDB_WATCHPOINT_ACCESS] = (0x5e | 1 << 8 | 1 << 9) ++}; ++ ++const KVMCapabilityInfo kvm_arch_required_capabilities[] = { ++ KVM_CAP_LAST_INFO ++}; ++ ++static void kvm_loongarch_update_state(void *opaque, bool running, RunState state); ++static inline int kvm_larch_putq(CPUState *cs, uint64_t reg_id, uint64_t *addr); ++ ++unsigned long kvm_arch_vcpu_id(CPUState *cs) ++{ ++ return cs->cpu_index; ++} ++ ++int kvm_arch_init(MachineState *ms, KVMState *s) ++{ ++ /* LOONGARCH has 128 signals */ ++ kvm_set_sigmask_len(s, 16); ++ ++ kvm_loongarch_version_cap = kvm_check_extension(s, KVM_CAP_LOONGARCH_VZ); ++ ++ if (kvm_loongarch_version_cap != KVM_LOONGARCH_VERSION) { ++ warn_report("QEMU/KVM version not match, qemu_la_version: lvz-%d,\ ++ kvm_la_version: lvz-%d \n", ++ KVM_LOONGARCH_VERSION, kvm_loongarch_version_cap); ++ } ++ return 0; ++} ++ ++int kvm_arch_irqchip_create(KVMState *s) ++{ ++ return 0; ++} ++ ++int kvm_arch_init_vcpu(CPUState *cs) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ int ret = 0; ++ ++ cpu->cpuStateEntry = qemu_add_vm_change_state_handler(kvm_loongarch_update_state, cs); ++ cpu->kvm_msr_buf = g_malloc0(MSR_BUF_SIZE); ++ DPRINTF("%s\n", __func__); ++ return ret; ++} ++ ++int kvm_arch_destroy_vcpu(CPUState *cs) ++{ ++ return 0; ++} ++ ++static void kvm_msr_buf_reset(LOONGARCHCPU *cpu) ++{ ++ memset(cpu->kvm_msr_buf, 0, MSR_BUF_SIZE); ++} ++ ++static void kvm_msr_entry_add(LOONGARCHCPU *cpu, uint32_t index, uint64_t value) ++{ ++ struct kvm_msrs *msrs = cpu->kvm_msr_buf; ++ void *limit = ((void *)msrs) + MSR_BUF_SIZE; ++ struct kvm_csr_entry *entry = &msrs->entries[msrs->ncsrs]; ++ ++ assert((void *)(entry + 1) <= limit); ++ ++ entry->index = index; ++ entry->reserved = 0; ++ entry->data = value; ++ msrs->ncsrs++; ++} ++ ++void kvm_loongarch_reset_vcpu(LOONGARCHCPU *cpu) ++{ ++ int ret = 0; ++ uint64_t reset = 1; ++ ++ if (CPU(cpu)->kvm_fd > 0) { ++ ret = kvm_larch_putq(CPU(cpu), KVM_REG_LOONGARCH_VCPU_RESET, &reset); ++ if (ret < 0) { ++ error_report("%s reset vcpu failed:%d", __func__, ret); ++ } ++ } ++ ++ DPRINTF("%s\n", __func__); ++} ++ ++void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg) ++{ ++ int n; ++ if (kvm_sw_breakpoints_active(cpu)) { ++ dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; ++ } ++ if (nb_data_breakpoint > 0) { ++ dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; ++ for (n = 0; n < nb_data_breakpoint; n++) { ++ dbg->arch.data_breakpoint[n].addr = data_breakpoint[n].addr; ++ dbg->arch.data_breakpoint[n].mask = 0; ++ dbg->arch.data_breakpoint[n].asid = 0; ++ dbg->arch.data_breakpoint[n].ctrl = type_code[data_breakpoint[n].type]; ++ } ++ dbg->arch.data_bp_nums = nb_data_breakpoint; ++ } else { ++ dbg->arch.data_bp_nums = 0; ++ } ++ if (nb_inst_breakpoint > 0) { ++ dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; ++ for (n = 0; n < nb_inst_breakpoint; n++) { ++ dbg->arch.inst_breakpoint[n].addr = inst_breakpoint[n].addr; ++ dbg->arch.inst_breakpoint[n].mask = 0; ++ dbg->arch.inst_breakpoint[n].asid = 0; ++ dbg->arch.inst_breakpoint[n].ctrl = type_code[inst_breakpoint[n].type]; ++ } ++ dbg->arch.inst_bp_nums = nb_inst_breakpoint; ++ } else { ++ dbg->arch.inst_bp_nums = 0; ++ } ++} ++ ++static const unsigned int brk_insn = 0x002b8005; ++ ++int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) ++{ ++ DPRINTF("%s\n", __func__); ++ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) || ++ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) { ++ error_report("%s failed", __func__); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) ++{ ++ static uint32_t brk; ++ ++ DPRINTF("%s\n", __func__); ++ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) || ++ brk != brk_insn || ++ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) { ++ error_report("%s failed", __func__); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int find_hw_breakpoint(uint64_t addr, int len, int type) ++{ ++ int n; ++ switch (type) { ++ case GDB_BREAKPOINT_HW: ++ if (nb_inst_breakpoint == 0) { ++ return -1; ++ } ++ for (n = 0; n < nb_inst_breakpoint; n++) { ++ if (inst_breakpoint[n].addr == addr && inst_breakpoint[n].type == type) { ++ return n; ++ } ++ } ++ break; ++ case GDB_WATCHPOINT_WRITE: ++ case GDB_WATCHPOINT_READ: ++ case GDB_WATCHPOINT_ACCESS: ++ if (nb_data_breakpoint == 0) { ++ return -1; ++ } ++ for (n = 0; n < nb_data_breakpoint; n++) { ++ if (data_breakpoint[n].addr == addr && data_breakpoint[n].type == type && ++ data_breakpoint[n].len == len) { ++ return n; ++ } ++ } ++ break; ++ default: ++ return -1; ++ } ++ return -1; ++} ++ ++int kvm_arch_insert_hw_breakpoint(target_ulong addr, ++ target_ulong len, int type) ++{ ++ switch (type) { ++ case GDB_BREAKPOINT_HW: ++ len = 1; ++ if (nb_inst_breakpoint == 8) { ++ return -ENOBUFS; ++ } ++ if (find_hw_breakpoint(addr, len, type) >= 0) { ++ return -EEXIST; ++ } ++ inst_breakpoint[nb_inst_breakpoint].addr = addr; ++ inst_breakpoint[nb_inst_breakpoint].len = len; ++ inst_breakpoint[nb_inst_breakpoint].type = type; ++ nb_inst_breakpoint++; ++ break; ++ case GDB_WATCHPOINT_WRITE: ++ case GDB_WATCHPOINT_READ: ++ case GDB_WATCHPOINT_ACCESS: ++ switch (len) { ++ case 1: ++ case 2: ++ case 4: ++ case 8: ++ if (addr & (len - 1)) { ++ return -EINVAL; ++ } ++ if (nb_data_breakpoint == 8) { ++ return -ENOBUFS; ++ } ++ if (find_hw_breakpoint(addr, len, type) >= 0) { ++ return -EEXIST; ++ } ++ data_breakpoint[nb_data_breakpoint].addr = addr; ++ data_breakpoint[nb_data_breakpoint].len = len; ++ data_breakpoint[nb_data_breakpoint].type = type; ++ nb_data_breakpoint++; ++ break; ++ default: ++ return -EINVAL; ++ } ++ break; ++ default: ++ return -ENOSYS; ++ } ++ return 0; ++} ++ ++int kvm_arch_remove_hw_breakpoint(target_ulong addr, ++ target_ulong len, int type) ++{ ++ int n; ++ n = find_hw_breakpoint(addr, (type == GDB_BREAKPOINT_HW) ? 1 : len, type); ++ if (n < 0) { ++ printf("err not find remove target\n"); ++ return -ENOENT; ++ } ++ switch (type) { ++ case GDB_BREAKPOINT_HW: ++ nb_inst_breakpoint--; ++ inst_breakpoint[n] = inst_breakpoint[nb_inst_breakpoint]; ++ break; ++ case GDB_WATCHPOINT_WRITE: ++ case GDB_WATCHPOINT_READ: ++ case GDB_WATCHPOINT_ACCESS: ++ nb_data_breakpoint--; ++ data_breakpoint[n] = data_breakpoint[nb_data_breakpoint]; ++ break; ++ default: ++ return -1; ++ } ++ return 0; ++} ++ ++void kvm_arch_remove_all_hw_breakpoints(void) ++{ ++ DPRINTF("%s\n", __func__); ++ nb_data_breakpoint = 0; ++ nb_inst_breakpoint = 0; ++} ++ ++static inline int cpu_loongarch_io_interrupts_pending(LOONGARCHCPU *cpu) ++{ ++ CPULOONGARCHState *env = &cpu->env; ++ ++ return env->CSR_ESTAT & (0x1 << 2); ++} ++ ++void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ int r; ++ struct kvm_loongarch_interrupt intr; ++ ++ qemu_mutex_lock_iothread(); ++ ++ if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && ++ cpu_loongarch_io_interrupts_pending(cpu)) { ++ intr.cpu = -1; ++ intr.irq = 2; ++ r = kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); ++ if (r < 0) { ++ error_report("%s: cpu %d: failed to inject IRQ %x", ++ __func__, cs->cpu_index, intr.irq); ++ } ++ } ++ ++ qemu_mutex_unlock_iothread(); ++} ++ ++MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) ++{ ++ return MEMTXATTRS_UNSPECIFIED; ++} ++ ++int kvm_arch_process_async_events(CPUState *cs) ++{ ++ return cs->halted; ++} ++ ++static CPUWatchpoint hw_watchpoint; ++ ++static bool kvm_loongarch_handle_debug(CPUState *cs, struct kvm_run *run) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ int i; ++ bool ret = false; ++ kvm_cpu_synchronize_state(cs); ++ if (cs->singlestep_enabled) { ++ return true; ++ } ++ if (kvm_find_sw_breakpoint(cs, env->active_tc.PC)) { ++ return true; ++ } ++ /* hw breakpoint */ ++ if (run->debug.arch.exception == EXCCODE_WATCH) { ++ for (i = 0; i < 8; i++) { ++ if (run->debug.arch.fwps & (1 << i)) { ++ ret = true; ++ break; ++ } ++ } ++ for (i = 0; i < 8; i++) { ++ if (run->debug.arch.mwps & (1 << i)) { ++ cs->watchpoint_hit = &hw_watchpoint; ++ hw_watchpoint.vaddr = data_breakpoint[i].addr; ++ switch (data_breakpoint[i].type) { ++ case GDB_WATCHPOINT_READ: ++ ret = true; ++ hw_watchpoint.flags = BP_MEM_READ; ++ break; ++ case GDB_WATCHPOINT_WRITE: ++ ret = true; ++ hw_watchpoint.flags = BP_MEM_WRITE; ++ break; ++ case GDB_WATCHPOINT_ACCESS: ++ ret = true; ++ hw_watchpoint.flags = BP_MEM_ACCESS; ++ break; ++ } ++ } ++ } ++ run->debug.arch.exception = 0; ++ run->debug.arch.fwps = 0; ++ run->debug.arch.mwps = 0; ++ } ++ return ret; ++} ++ ++int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) ++{ ++ int ret; ++ ++ DPRINTF("%s\n", __func__); ++ switch (run->exit_reason) { ++ case KVM_EXIT_HYPERCALL: ++ DPRINTF("handle LOONGARCH hypercall\n"); ++ ret = 0; ++ run->hypercall.ret = ret; ++ break; ++ ++ case KVM_EXIT_DEBUG: ++ ret = 0; ++ if (kvm_loongarch_handle_debug(cs, run)) { ++ ret = EXCP_DEBUG; ++ } ++ break; ++ default: ++ error_report("%s: unknown exit reason %d", ++ __func__, run->exit_reason); ++ ret = -1; ++ break; ++ } ++ ++ return ret; ++} ++ ++bool kvm_arch_stop_on_emulation_error(CPUState *cs) ++{ ++ DPRINTF("%s\n", __func__); ++ return true; ++} ++/* ++#if 0 ++int kvmloongarch_load_kernel(CPUState *env, void *ram_base) ++{ ++ int ret; ++ ++ ret = kvm_vcpu_ioctl(env, KVM_LOAD_KERNEL, ram_base); ++ ++ return ret; ++} ++#endif ++*/ ++void kvm_arch_init_irq_routing(KVMState *s) ++{ ++} ++ ++int kvm_loongarch_set_interrupt(LOONGARCHCPU *cpu, int irq, int level) ++{ ++ CPUState *cs = CPU(cpu); ++ struct kvm_loongarch_interrupt intr; ++ ++ if (!kvm_enabled()) { ++ return 0; ++ } ++ ++ intr.cpu = -1; ++ ++ if (level) { ++ intr.irq = irq; ++ } else { ++ intr.irq = -irq; ++ } ++ ++ kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); ++ ++ return 0; ++} ++ ++int kvm_loongarch_set_ipi_interrupt(LOONGARCHCPU *cpu, int irq, int level) ++{ ++ CPUState *cs = current_cpu; ++ CPUState *dest_cs = CPU(cpu); ++ struct kvm_loongarch_interrupt intr; ++ ++ if (!kvm_enabled()) { ++ return 0; ++ } ++ ++ intr.cpu = dest_cs->cpu_index; ++ ++ if (level) { ++ intr.irq = irq; ++ } else { ++ intr.irq = -irq; ++ } ++ ++ DPRINTF("%s: IRQ: %d\n", __func__, intr.irq); ++ if (!current_cpu) { ++ cs = dest_cs; ++ } ++ kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); ++ ++ return 0; ++} ++ ++static inline int kvm_loongarch_put_one_reg(CPUState *cs, uint64_t reg_id, ++ int32_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_put_one_ureg(CPUState *cs, uint64_t reg_id, ++ uint32_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_put_one_ulreg(CPUState *cs, uint64_t reg_id, ++ target_ulong *addr) ++{ ++ uint64_t val64 = *addr; ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)&val64 ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_put_one_reg64(CPUState *cs, int64_t reg_id, ++ int64_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_larch_putq(CPUState *cs, uint64_t reg_id, ++ uint64_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_get_one_reg(CPUState *cs, uint64_t reg_id, ++ int32_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_get_one_ureg(CPUState *cs, uint64_t reg_id, ++ uint32_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_get_one_ulreg(CPUState *cs, uint64_t reg_id, ++ target_ulong *addr) ++{ ++ int ret; ++ uint64_t val64 = 0; ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)&val64 ++ }; ++ ++ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); ++ if (ret >= 0) { ++ *addr = val64; ++ } ++ return ret; ++} ++ ++static inline int kvm_loongarch_get_one_reg64(CPUState *cs, int64_t reg_id, ++ int64_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_larch_getq(CPUState *cs, uint64_t reg_id, ++ uint64_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_change_one_reg(CPUState *cs, uint64_t reg_id, ++ int32_t *addr, int32_t mask) ++{ ++ int err; ++ int32_t tmp, change; ++ ++ err = kvm_loongarch_get_one_reg(cs, reg_id, &tmp); ++ if (err < 0) { ++ return err; ++ } ++ ++ /* only change bits in mask */ ++ change = (*addr ^ tmp) & mask; ++ if (!change) { ++ return 0; ++ } ++ ++ tmp = tmp ^ change; ++ return kvm_loongarch_put_one_reg(cs, reg_id, &tmp); ++} ++ ++static inline int kvm_loongarch_change_one_reg64(CPUState *cs, uint64_t reg_id, ++ int64_t *addr, int64_t mask) ++{ ++ int err; ++ int64_t tmp, change; ++ ++ err = kvm_loongarch_get_one_reg64(cs, reg_id, &tmp); ++ if (err < 0) { ++ DPRINTF("%s: Failed to get CSR_CONFIG7 (%d)\n", __func__, err); ++ return err; ++ } ++ ++ /* only change bits in mask */ ++ change = (*addr ^ tmp) & mask; ++ if (!change) { ++ return 0; ++ } ++ ++ tmp = tmp ^ change; ++ return kvm_loongarch_put_one_reg64(cs, reg_id, &tmp); ++} ++/* ++ * Handle the VM clock being started or stopped ++ */ ++static void kvm_loongarch_update_state(void *opaque, bool running, RunState state) ++{ ++ CPUState *cs = opaque; ++ int ret; ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ ++ /* ++ * If state is already dirty (synced to QEMU) then the KVM timer state is ++ * already saved and can be restored when it is synced back to KVM. ++ */ ++ if (!running) { ++ ret = kvm_larch_getq(cs, ++ KVM_REG_LOONGARCH_COUNTER, &cpu->counter_value); ++ if (ret < 0) { ++ printf("%s: Failed to get counter_value (%d)\n", __func__, ret); ++ } ++ ++ } else { ++ ret = kvm_larch_putq(cs, KVM_REG_LOONGARCH_COUNTER, ++ &(LOONGARCH_CPU(cs))->counter_value); ++ if (ret < 0) { ++ printf("%s: Failed to put counter_value (%d)\n", __func__, ret); ++ } ++ } ++} ++ ++static int kvm_loongarch_put_fpu_registers(CPUState *cs, int level) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ int err, ret = 0; ++ unsigned int i; ++ struct kvm_fpu fpu; ++ ++ fpu.fcsr = env->active_fpu.fcsr0; ++ for (i = 0; i < 32; i++) { ++ memcpy(&fpu.fpr[i], &env->active_fpu.fpr[i], sizeof(struct kvm_fpureg)); ++ } ++ for (i = 0; i < 8; i++) { ++ ((char *)&fpu.fcc)[i] = env->active_fpu.cf[i]; ++ } ++ fpu.vcsr = env->active_fpu.vcsr16; ++ ++ err = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu); ++ if (err < 0) { ++ DPRINTF("%s: Failed to get FPU (%d)\n", __func__, err); ++ ret = err; ++ } ++ ++ return ret; ++} ++ ++static int kvm_loongarch_get_fpu_registers(CPUState *cs) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ int err, ret = 0; ++ unsigned int i; ++ struct kvm_fpu fpu; ++ ++ err = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu); ++ if (err < 0) { ++ DPRINTF("%s: Failed to get FPU (%d)\n", __func__, err); ++ ret = err; ++ } else { ++ env->active_fpu.fcsr0 = fpu.fcsr; ++ for (i = 0; i < 32; i++) { ++ memcpy(&env->active_fpu.fpr[i], &fpu.fpr[i], sizeof(struct kvm_fpureg)); ++ } ++ for (i = 0; i < 8; i++) { ++ env->active_fpu.cf[i] = ((char *)&fpu.fcc)[i]; ++ } ++ env->active_fpu.vcsr16 = fpu.vcsr; ++ } ++ ++ return ret; ++} ++ ++#define KVM_PUT_ONE_UREG64(cs, regidx, addr) \ ++ ({ \ ++ int err; \ ++ uint64_t csrid = 0; \ ++ csrid = (KVM_IOC_CSRID(regidx)); \ ++ err = kvm_larch_putq(cs, csrid, addr); \ ++ if (err < 0) { \ ++ DPRINTF("%s: Failed to put regidx 0x%x err:%d\n", __func__, regidx, err); \ ++ } \ ++ err; \ ++ }) ++ ++ ++static int kvm_loongarch_put_csr_registers(CPUState *cs, int level) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ int ret = 0; ++ ++ (void)level; ++ ++ kvm_msr_buf_reset(cpu); ++ ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CRMD, env->CSR_CRMD); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRMD, env->CSR_PRMD); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_EUEN, env->CSR_EUEN); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_MISC, env->CSR_MISC); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ECFG, env->CSR_ECFG); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ESTAT, env->CSR_ESTAT); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERA, env->CSR_ERA); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADV, env->CSR_BADV); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADI, env->CSR_BADI); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_EEPN, env->CSR_EEPN); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, env->CSR_TLBIDX); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, env->CSR_TLBEHI); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, env->CSR_TLBELO0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, env->CSR_TLBELO1); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GTLBC, env->CSR_GTLBC); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TRGP, env->CSR_TRGP); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ASID, env->CSR_ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDL, env->CSR_PGDL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDH, env->CSR_PGDH); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGD, env->CSR_PGD); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, env->CSR_PWCTL0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, env->CSR_PWCTL1); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, env->CSR_STLBPGSIZE); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_RVACFG, env->CSR_RVACFG); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CPUID, env->CSR_CPUID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, env->CSR_PRCFG1); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, env->CSR_PRCFG2); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, env->CSR_PRCFG3); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS0, env->CSR_KS0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS1, env->CSR_KS1); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS2, env->CSR_KS2); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS3, env->CSR_KS3); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS4, env->CSR_KS4); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS5, env->CSR_KS5); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS6, env->CSR_KS6); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS7, env->CSR_KS7); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TMID, env->CSR_TMID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CNTC, env->CSR_CNTC); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, env->CSR_TINTCLR); ++ ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GSTAT, env->CSR_GSTAT); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCFG, env->CSR_GCFG); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GINTC, env->CSR_GINTC); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCNTC, env->CSR_GCNTC); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, env->CSR_LLBCTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, env->CSR_IMPCTL1); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, env->CSR_IMPCTL2); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GNMI, env->CSR_GNMI); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, env->CSR_TLBRENT); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, env->CSR_TLBRBADV); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, env->CSR_TLBRERA); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, env->CSR_TLBRSAVE); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, env->CSR_TLBRELO0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, env->CSR_TLBRELO1); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, env->CSR_TLBREHI); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, env->CSR_TLBRPRMD); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, env->CSR_ERRCTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, env->CSR_ERRINFO); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, env->CSR_ERRINFO1); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRENT, env->CSR_ERRENT); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRERA, env->CSR_ERRERA); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, env->CSR_ERRSAVE); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CTAG, env->CSR_CTAG); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, env->CSR_DMWIN0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, env->CSR_DMWIN1); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, env->CSR_DMWIN2); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, env->CSR_DMWIN3); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, env->CSR_PERFCTRL0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, env->CSR_PERFCNTR0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, env->CSR_PERFCTRL1); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, env->CSR_PERFCNTR1); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, env->CSR_PERFCTRL2); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, env->CSR_PERFCNTR2); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, env->CSR_PERFCTRL3); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, env->CSR_PERFCNTR3); ++ ++ /* debug */ ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPC, env->CSR_MWPC); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPS, env->CSR_MWPS); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, env->CSR_DB0ADDR); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, env->CSR_DB0MASK); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, env->CSR_DB0CTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, env->CSR_DB0ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, env->CSR_DB1ADDR); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, env->CSR_DB1MASK); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, env->CSR_DB1CTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, env->CSR_DB1ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, env->CSR_DB2ADDR); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, env->CSR_DB2MASK); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, env->CSR_DB2CTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, env->CSR_DB2ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, env->CSR_DB3ADDR); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, env->CSR_DB3MASK); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, env->CSR_DB3CTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, env->CSR_DB3ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPC, env->CSR_FWPC); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPS, env->CSR_FWPS); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, env->CSR_IB0ADDR); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, env->CSR_IB0MASK); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, env->CSR_IB0CTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, env->CSR_IB0ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, env->CSR_IB1ADDR); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, env->CSR_IB1MASK); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, env->CSR_IB1CTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, env->CSR_IB1ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, env->CSR_IB2ADDR); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, env->CSR_IB2MASK); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, env->CSR_IB2CTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, env->CSR_IB2ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, env->CSR_IB3ADDR); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, env->CSR_IB3MASK); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, env->CSR_IB3CTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, env->CSR_IB3ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, env->CSR_IB4ADDR); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, env->CSR_IB4MASK); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, env->CSR_IB4CTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, env->CSR_IB4ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, env->CSR_IB5ADDR); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, env->CSR_IB5MASK); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, env->CSR_IB5CTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, env->CSR_IB5ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, env->CSR_IB6ADDR); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, env->CSR_IB6MASK); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, env->CSR_IB6CTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, env->CSR_IB6ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, env->CSR_IB7ADDR); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, env->CSR_IB7MASK); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, env->CSR_IB7CTL); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, env->CSR_IB7ASID); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DEBUG, env->CSR_DEBUG); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DERA, env->CSR_DERA); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DESAVE, env->CSR_DESAVE); ++ ++ ret = kvm_vcpu_ioctl(cs, KVM_SET_MSRS, cpu->kvm_msr_buf); ++ if (ret < cpu->kvm_msr_buf->ncsrs) { ++ struct kvm_csr_entry *e = &cpu->kvm_msr_buf->entries[ret]; ++ printf("error: failed to set CSR 0x%" PRIx32 " to 0x%" PRIx64"\n", ++ (uint32_t)e->index, (uint64_t)e->data); ++ } ++ ++ /* ++ * timer cfg must be put at last since it is used to enable ++ * guest timer ++ */ ++ ret |= KVM_PUT_ONE_UREG64(cs, LOONGARCH_CSR_TVAL, &env->CSR_TVAL); ++ ret |= KVM_PUT_ONE_UREG64(cs, LOONGARCH_CSR_TCFG, &env->CSR_TCFG); ++ return ret; ++} ++ ++#define KVM_GET_ONE_UREG64(cs, regidx, addr) \ ++ ({ \ ++ int err; \ ++ uint64_t csrid = 0; \ ++ csrid = (KVM_IOC_CSRID(regidx)); \ ++ err = kvm_larch_getq(cs, csrid, addr); \ ++ if (err < 0) { \ ++ DPRINTF("%s: Failed to put regidx 0x%x err:%d\n", __func__, regidx, err); \ ++ } \ ++ err; \ ++ }) ++ ++static int kvm_loongarch_get_csr_registers(CPUState *cs) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ int ret = 0, i; ++ struct kvm_csr_entry *csrs = cpu->kvm_msr_buf->entries; ++ ++ kvm_msr_buf_reset(cpu); ++ ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CRMD, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRMD, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_EUEN, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_MISC, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ECFG, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ESTAT, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERA, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADV, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_BADI, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_EEPN, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GTLBC, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TRGP, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGDH, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PGD, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_RVACFG, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CPUID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS0, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS1, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS2, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS3, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS4, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS5, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS6, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_KS7, 0); ++ ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TMID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CNTC, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GSTAT, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCFG, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GINTC, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GCNTC, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_GNMI, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRENT, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRERA, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_CTAG, 0); ++ ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, 0); ++ ++ /* debug */ ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPC, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_MWPS, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPC, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_FWPS, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DEBUG, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DERA, 0); ++ kvm_msr_entry_add(cpu, LOONGARCH_CSR_DESAVE, 0); ++ ++ ret = kvm_vcpu_ioctl(cs, KVM_GET_MSRS, cpu->kvm_msr_buf); ++ if (ret < cpu->kvm_msr_buf->ncsrs) { ++ struct kvm_csr_entry *e = &cpu->kvm_msr_buf->entries[ret]; ++ printf("error: failed to get CSR 0x%" PRIx32"\n", ++ (uint32_t)e->index); ++ } ++ ++ for (i = 0; i < ret; i++) { ++ uint32_t index = csrs[i].index; ++ ++ switch (index) { ++ case LOONGARCH_CSR_CRMD: ++ env->CSR_CRMD = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PRMD: ++ env->CSR_PRMD = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_EUEN: ++ env->CSR_EUEN = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_MISC: ++ env->CSR_MISC = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_ECFG: ++ env->CSR_ECFG = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_ESTAT: ++ env->CSR_ESTAT = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_ERA: ++ env->CSR_ERA = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_BADV: ++ env->CSR_BADV = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_BADI: ++ env->CSR_BADI = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_EEPN: ++ env->CSR_EEPN = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TLBIDX: ++ env->CSR_TLBIDX = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TLBEHI: ++ env->CSR_TLBEHI = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TLBELO0: ++ env->CSR_TLBELO0 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TLBELO1: ++ env->CSR_TLBELO1 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_GTLBC: ++ env->CSR_GTLBC = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TRGP: ++ env->CSR_TRGP = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_ASID: ++ env->CSR_ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PGDL: ++ env->CSR_PGDL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PGDH: ++ env->CSR_PGDH = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PGD: ++ env->CSR_PGD = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PWCTL0: ++ env->CSR_PWCTL0 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PWCTL1: ++ env->CSR_PWCTL1 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_STLBPGSIZE: ++ env->CSR_STLBPGSIZE = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_RVACFG: ++ env->CSR_RVACFG = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_CPUID: ++ env->CSR_CPUID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PRCFG1: ++ env->CSR_PRCFG1 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PRCFG2: ++ env->CSR_PRCFG2 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PRCFG3: ++ env->CSR_PRCFG3 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_KS0: ++ env->CSR_KS0 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_KS1: ++ env->CSR_KS1 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_KS2: ++ env->CSR_KS2 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_KS3: ++ env->CSR_KS3 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_KS4: ++ env->CSR_KS4 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_KS5: ++ env->CSR_KS5 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_KS6: ++ env->CSR_KS6 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_KS7: ++ env->CSR_KS7 = csrs[i].data; ++ break; ++ ++ case LOONGARCH_CSR_TMID: ++ env->CSR_TMID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_CNTC: ++ env->CSR_CNTC = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TINTCLR: ++ env->CSR_TINTCLR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_GSTAT: ++ env->CSR_GSTAT = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_GCFG: ++ env->CSR_GCFG = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_GINTC: ++ env->CSR_GINTC = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_GCNTC: ++ env->CSR_GCNTC = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_LLBCTL: ++ env->CSR_LLBCTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IMPCTL1: ++ env->CSR_IMPCTL1 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IMPCTL2: ++ env->CSR_IMPCTL2 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_GNMI: ++ env->CSR_GNMI = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TLBRENT: ++ env->CSR_TLBRENT = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TLBRBADV: ++ env->CSR_TLBRBADV = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TLBRERA: ++ env->CSR_TLBRERA = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TLBRSAVE: ++ env->CSR_TLBRSAVE = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TLBRELO0: ++ env->CSR_TLBRELO0 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TLBRELO1: ++ env->CSR_TLBRELO1 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TLBREHI: ++ env->CSR_TLBREHI = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_TLBRPRMD: ++ env->CSR_TLBRPRMD = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_ERRCTL: ++ env->CSR_ERRCTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_ERRINFO: ++ env->CSR_ERRINFO = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_ERRINFO1: ++ env->CSR_ERRINFO1 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_ERRENT: ++ env->CSR_ERRENT = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_ERRERA: ++ env->CSR_ERRERA = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_ERRSAVE: ++ env->CSR_ERRSAVE = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_CTAG: ++ env->CSR_CTAG = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DMWIN0: ++ env->CSR_DMWIN0 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DMWIN1: ++ env->CSR_DMWIN1 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DMWIN2: ++ env->CSR_DMWIN2 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DMWIN3: ++ env->CSR_DMWIN3 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PERFCTRL0: ++ env->CSR_PERFCTRL0 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PERFCNTR0: ++ env->CSR_PERFCNTR0 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PERFCTRL1: ++ env->CSR_PERFCTRL1 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PERFCNTR1: ++ env->CSR_PERFCNTR1 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PERFCTRL2: ++ env->CSR_PERFCTRL2 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PERFCNTR2: ++ env->CSR_PERFCNTR2 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PERFCTRL3: ++ env->CSR_PERFCTRL3 = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_PERFCNTR3: ++ env->CSR_PERFCNTR3 = csrs[i].data; ++ break; ++ ++ case LOONGARCH_CSR_MWPC: ++ env->CSR_MWPC = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_MWPS: ++ env->CSR_MWPS = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB0ADDR: ++ env->CSR_DB0ADDR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB0MASK: ++ env->CSR_DB0MASK = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB0CTL: ++ env->CSR_DB0CTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB0ASID: ++ env->CSR_DB0ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB1ADDR: ++ env->CSR_DB1ADDR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB1MASK: ++ env->CSR_DB1MASK = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB1CTL: ++ env->CSR_DB1CTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB1ASID: ++ env->CSR_DB1ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB2ADDR: ++ env->CSR_DB2ADDR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB2MASK: ++ env->CSR_DB2MASK = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB2CTL: ++ env->CSR_DB2CTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB2ASID: ++ env->CSR_DB2ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB3ADDR: ++ env->CSR_DB3ADDR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB3MASK: ++ env->CSR_DB3MASK = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB3CTL: ++ env->CSR_DB3CTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DB3ASID: ++ env->CSR_DB3ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_FWPC: ++ env->CSR_FWPC = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_FWPS: ++ env->CSR_FWPS = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB0ADDR: ++ env->CSR_IB0ADDR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB0MASK: ++ env->CSR_IB0MASK = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB0CTL: ++ env->CSR_IB0CTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB0ASID: ++ env->CSR_IB0ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB1ADDR: ++ env->CSR_IB1ADDR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB1MASK: ++ env->CSR_IB1MASK = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB1CTL: ++ env->CSR_IB1CTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB1ASID: ++ env->CSR_IB1ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB2ADDR: ++ env->CSR_IB2ADDR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB2MASK: ++ env->CSR_IB2MASK = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB2CTL: ++ env->CSR_IB2CTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB2ASID: ++ env->CSR_IB2ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB3ADDR: ++ env->CSR_IB3ADDR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB3MASK: ++ env->CSR_IB3MASK = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB3CTL: ++ env->CSR_IB3CTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB3ASID: ++ env->CSR_IB3ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB4ADDR: ++ env->CSR_IB4ADDR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB4MASK: ++ env->CSR_IB4MASK = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB4CTL: ++ env->CSR_IB4CTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB4ASID: ++ env->CSR_IB4ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB5ADDR: ++ env->CSR_IB5ADDR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB5MASK: ++ env->CSR_IB5MASK = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB5CTL: ++ env->CSR_IB5CTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB5ASID: ++ env->CSR_IB5ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB6ADDR: ++ env->CSR_IB6ADDR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB6MASK: ++ env->CSR_IB6MASK = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB6CTL: ++ env->CSR_IB6CTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB6ASID: ++ env->CSR_IB6ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB7ADDR: ++ env->CSR_IB7ADDR = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB7MASK: ++ env->CSR_IB7MASK = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB7CTL: ++ env->CSR_IB7CTL = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_IB7ASID: ++ env->CSR_IB7ASID = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DEBUG: ++ env->CSR_DEBUG = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DERA: ++ env->CSR_DERA = csrs[i].data; ++ break; ++ case LOONGARCH_CSR_DESAVE: ++ env->CSR_DESAVE = csrs[i].data; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ ret |= KVM_GET_ONE_UREG64(cs, LOONGARCH_CSR_TVAL, &env->CSR_TVAL); ++ ret |= KVM_GET_ONE_UREG64(cs, LOONGARCH_CSR_TCFG, &env->CSR_TCFG); ++ return ret; ++} ++ ++int kvm_loongarch_put_pvtime(LOONGARCHCPU *cpu) ++{ ++ CPULOONGARCHState *env = &cpu->env; ++ int err; ++ struct kvm_device_attr attr = { ++ .group = KVM_LARCH_VCPU_PVTIME_CTRL, ++ .attr = KVM_LARCH_VCPU_PVTIME_IPA, ++ .addr = (uint64_t)&env->st.guest_addr, ++ }; ++ ++ err = kvm_vcpu_ioctl(CPU(cpu), KVM_HAS_DEVICE_ATTR, attr); ++ if (err != 0) { ++ /* It's ok even though kvm has not such attr */ ++ return 0; ++ } ++ ++ err = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_DEVICE_ATTR, attr); ++ if (err != 0) { ++ error_report("PVTIME IPA: KVM_SET_DEVICE_ATTR: %s", strerror(-err)); ++ return err; ++ } ++ ++ return 0; ++} ++ ++int kvm_loongarch_get_pvtime(LOONGARCHCPU *cpu) ++{ ++ CPULOONGARCHState *env = &cpu->env; ++ int err; ++ struct kvm_device_attr attr = { ++ .group = KVM_LARCH_VCPU_PVTIME_CTRL, ++ .attr = KVM_LARCH_VCPU_PVTIME_IPA, ++ .addr = (uint64_t)&env->st.guest_addr, ++ }; ++ ++ err = kvm_vcpu_ioctl(CPU(cpu), KVM_HAS_DEVICE_ATTR, attr); ++ if (err != 0) { ++ /* It's ok even though kvm has not such attr */ ++ return 0; ++ } ++ ++ err = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_DEVICE_ATTR, attr); ++ if (err != 0) { ++ error_report("PVTIME IPA: KVM_GET_DEVICE_ATTR: %s", strerror(-err)); ++ return err; ++ } ++ ++ return 0; ++} ++ ++int kvm_arch_put_registers(CPUState *cs, int level) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ struct kvm_regs regs; ++ int ret; ++ int i; ++ ++ /* Set the registers based on QEMU's view of things */ ++ for (i = 0; i < 32; i++) { ++ regs.gpr[i] = (int64_t)(target_long)env->active_tc.gpr[i]; ++ } ++ ++ regs.pc = (int64_t)(target_long)env->active_tc.PC; ++ ++ ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s); ++ ++ if (ret < 0) { ++ return ret; ++ } ++ ++ ret = kvm_loongarch_put_csr_registers(cs, level); ++ if (ret < 0) { ++ return ret; ++ } ++ ++ ret = kvm_loongarch_put_fpu_registers(cs, level); ++ if (ret < 0) { ++ return ret; ++ } ++ ++ return ret; ++} ++ ++int kvm_arch_get_registers(CPUState *cs) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ int ret = 0; ++ struct kvm_regs regs; ++ int i; ++ ++ /* Get the current register set as KVM seems it */ ++ ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, ®s); ++ ++ if (ret < 0) { ++ return ret; ++ } ++ ++ for (i = 0; i < 32; i++) { ++ env->active_tc.gpr[i] = regs.gpr[i]; ++ } ++ ++ env->active_tc.PC = regs.pc; ++ ++ kvm_loongarch_get_csr_registers(cs); ++ kvm_loongarch_get_fpu_registers(cs); ++ ++ return ret; ++} ++ ++int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, ++ uint64_t address, uint32_t data, PCIDevice *dev) ++{ ++ return 0; ++} ++ ++int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, ++ int vector, PCIDevice *dev) ++{ ++ return 0; ++} ++ ++bool kvm_arch_cpu_check_are_resettable(void) ++{ ++ return true; ++} ++ ++int kvm_arch_release_virq_post(int virq) ++{ ++ return 0; ++} ++ ++int kvm_arch_msi_data_to_gsi(uint32_t data) ++{ ++ abort(); ++} +diff --git a/target/loongarch64/kvm_larch.h b/target/loongarch64/kvm_larch.h +new file mode 100644 +index 0000000000..a56026d10c +--- /dev/null ++++ b/target/loongarch64/kvm_larch.h +@@ -0,0 +1,41 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * KVM/LOONGARCH: LOONGARCH specific KVM APIs ++ * ++ * Copyright (C) 2012-2014 Imagination Technologies Ltd. ++ * Authors: Sanjay Lal ++*/ ++ ++#ifndef KVM_LOONGARCH_H ++#define KVM_LOONGARCH_H ++ ++/** ++ * kvm_loongarch_reset_vcpu: ++ * @cpu: LOONGARCHCPU ++ * ++ * Called at reset time to set kernel registers to their initial values. ++ */ ++void kvm_loongarch_reset_vcpu(LOONGARCHCPU *cpu); ++ ++int kvm_loongarch_set_interrupt(LOONGARCHCPU *cpu, int irq, int level); ++int kvm_loongarch_set_ipi_interrupt(LOONGARCHCPU *cpu, int irq, int level); ++ ++int kvm_loongarch_put_pvtime(LOONGARCHCPU *cpu); ++int kvm_loongarch_get_pvtime(LOONGARCHCPU *cpu); ++ ++#ifndef KVM_INTERRUPT_SET ++#define KVM_INTERRUPT_SET -1 ++#endif ++ ++#ifndef KVM_INTERRUPT_UNSET ++#define KVM_INTERRUPT_UNSET -2 ++#endif ++ ++#ifndef KVM_INTERRUPT_SET_LEVEL ++#define KVM_INTERRUPT_SET_LEVEL -3 ++#endif ++ ++#endif /* KVM_LOONGARCH_H */ +diff --git a/target/loongarch64/larch-defs.h b/target/loongarch64/larch-defs.h +new file mode 100644 +index 0000000000..d3a61cf255 +--- /dev/null ++++ b/target/loongarch64/larch-defs.h +@@ -0,0 +1,27 @@ ++#ifndef QEMU_LOONGARCH_DEFS_H ++#define QEMU_LOONGARCH_DEFS_H ++ ++/* If we want to use host float regs... */ ++/* #define USE_HOST_FLOAT_REGS */ ++ ++/* Real pages are variable size... */ ++#define TARGET_PAGE_BITS 14 ++ ++#define LOONGARCH_TLB_MAX 2112 ++ ++#define TARGET_LONG_BITS 64 ++#define TARGET_PHYS_ADDR_SPACE_BITS 48 ++#define TARGET_VIRT_ADDR_SPACE_BITS 48 ++ ++/* ++ * bit definitions for insn_flags (ISAs/ASEs flags) ++ * ------------------------------------------------ ++ */ ++#define ISA_LARCH32 0x00000001ULL ++#define ISA_LARCH64 0x00000002ULL ++#define INSN_LOONGARCH 0x00010000ULL ++ ++#define CPU_LARCH32 (ISA_LARCH32) ++#define CPU_LARCH64 (ISA_LARCH32 | ISA_LARCH64) ++ ++#endif /* QEMU_LOONGARCH_DEFS_H */ +diff --git a/target/loongarch64/machine.c b/target/loongarch64/machine.c +new file mode 100644 +index 0000000000..b69bca6a9b +--- /dev/null ++++ b/target/loongarch64/machine.c +@@ -0,0 +1,416 @@ ++#include "qemu/osdep.h" ++#include "qemu-common.h" ++#include "cpu.h" ++#include "internal.h" ++#include "hw/hw.h" ++#include "kvm_larch.h" ++#include "migration/cpu.h" ++#include "linux/kvm.h" ++#include "sysemu/kvm.h" ++#include "qemu/error-report.h" ++ ++static int cpu_post_load(void *opaque, int version_id) ++{ ++ LOONGARCHCPU *cpu = opaque; ++ CPULOONGARCHState *env = &cpu->env; ++ int r = 0; ++ ++#ifdef CONFIG_KVM ++ struct kvm_loongarch_vcpu_state vcpu_state; ++ int i; ++ ++ vcpu_state.online_vcpus = cpu->online_vcpus; ++ vcpu_state.is_migrate = cpu->is_migrate; ++ vcpu_state.cpu_freq = cpu->cpu_freq; ++ vcpu_state.count_ctl = cpu->count_ctl; ++ vcpu_state.pending_exceptions = cpu->pending_exceptions; ++ vcpu_state.pending_exceptions_clr = cpu->pending_exceptions_clr; ++ for (i = 0; i < 4; i++) { ++ vcpu_state.core_ext_ioisr[i] = cpu->core_ext_ioisr[i]; ++ } ++ r = kvm_vcpu_ioctl(CPU(cpu), KVM_LARCH_SET_VCPU_STATE, &vcpu_state); ++ if (r) { ++ error_report("set vcpu state failed %d", r); ++ } ++ ++ kvm_loongarch_put_pvtime(cpu); ++#endif ++ ++ restore_fp_status(env); ++ compute_hflags(env); ++ ++ return r; ++} ++ ++static int cpu_pre_save(void *opaque) ++{ ++#ifdef CONFIG_KVM ++ LOONGARCHCPU *cpu = opaque; ++ struct kvm_loongarch_vcpu_state vcpu_state; ++ int i, r = 0; ++ ++ r = kvm_vcpu_ioctl(CPU(cpu), KVM_LARCH_GET_VCPU_STATE, &vcpu_state); ++ if (r < 0) { ++ error_report("get vcpu state failed %d", r); ++ return r; ++ } ++ ++ cpu->online_vcpus = vcpu_state.online_vcpus; ++ cpu->is_migrate = vcpu_state.is_migrate; ++ cpu->cpu_freq = vcpu_state.cpu_freq; ++ cpu->count_ctl = vcpu_state.count_ctl; ++ cpu->pending_exceptions = vcpu_state.pending_exceptions; ++ cpu->pending_exceptions_clr = vcpu_state.pending_exceptions_clr; ++ for (i = 0; i < 4; i++) { ++ cpu->core_ext_ioisr[i] = vcpu_state.core_ext_ioisr[i]; ++ } ++ ++ kvm_loongarch_get_pvtime(cpu); ++#endif ++ return 0; ++} ++ ++/* FPU state */ ++ ++static int get_fpr(QEMUFile *f, void *pv, size_t size, ++ const VMStateField *field) ++{ ++ fpr_t *v = pv; ++ qemu_get_be64s(f, &v->d); ++ return 0; ++} ++ ++static int put_fpr(QEMUFile *f, void *pv, size_t size, ++ const VMStateField *field, JSONWriter *vmdesc) ++{ ++ fpr_t *v = pv; ++ qemu_put_be64s(f, &v->d); ++ return 0; ++} ++ ++const VMStateInfo vmstate_info_fpr = { ++ .name = "fpr", ++ .get = get_fpr, ++ .put = put_fpr, ++}; ++ ++#define VMSTATE_FPR_ARRAY_V(_f, _s, _n, _v) \ ++ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_fpr, fpr_t) ++ ++#define VMSTATE_FPR_ARRAY(_f, _s, _n) \ ++ VMSTATE_FPR_ARRAY_V(_f, _s, _n, 0) ++ ++static VMStateField vmstate_fpu_fields[] = { ++ VMSTATE_FPR_ARRAY(fpr, CPULOONGARCHFPUContext, 32), ++ VMSTATE_UINT32(fcsr0, CPULOONGARCHFPUContext), ++ VMSTATE_END_OF_LIST() ++}; ++ ++const VMStateDescription vmstate_fpu = { ++ .name = "cpu/fpu", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = vmstate_fpu_fields ++}; ++ ++const VMStateDescription vmstate_inactive_fpu = { ++ .name = "cpu/inactive_fpu", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = vmstate_fpu_fields ++}; ++ ++/* TC state */ ++ ++static VMStateField vmstate_tc_fields[] = { ++ VMSTATE_UINTTL_ARRAY(gpr, TCState, 32), ++ VMSTATE_UINTTL(PC, TCState), ++ VMSTATE_END_OF_LIST() ++}; ++ ++const VMStateDescription vmstate_tc = { ++ .name = "cpu/tc", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = vmstate_tc_fields ++}; ++ ++const VMStateDescription vmstate_inactive_tc = { ++ .name = "cpu/inactive_tc", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = vmstate_tc_fields ++}; ++ ++/* TLB state */ ++ ++static int get_tlb(QEMUFile *f, void *pv, size_t size, ++ const VMStateField *field) ++{ ++ ls3a5k_tlb_t *v = pv; ++ uint32_t flags; ++ ++ qemu_get_betls(f, &v->VPN); ++ qemu_get_be64s(f, &v->PageMask); ++ qemu_get_be32s(f, &v->PageSize); ++ qemu_get_be16s(f, &v->ASID); ++ qemu_get_be32s(f, &flags); ++ v->RPLV1 = (flags >> 21) & 1; ++ v->RPLV0 = (flags >> 20) & 1; ++ v->PLV1 = (flags >> 18) & 3; ++ v->PLV0 = (flags >> 16) & 3; ++ v->EHINV = (flags >> 15) & 1; ++ v->RI1 = (flags >> 14) & 1; ++ v->RI0 = (flags >> 13) & 1; ++ v->XI1 = (flags >> 12) & 1; ++ v->XI0 = (flags >> 11) & 1; ++ v->WE1 = (flags >> 10) & 1; ++ v->WE0 = (flags >> 9) & 1; ++ v->V1 = (flags >> 8) & 1; ++ v->V0 = (flags >> 7) & 1; ++ v->C1 = (flags >> 4) & 7; ++ v->C0 = (flags >> 1) & 7; ++ v->G = (flags >> 0) & 1; ++ qemu_get_be64s(f, &v->PPN0); ++ qemu_get_be64s(f, &v->PPN1); ++ ++ return 0; ++} ++ ++static int put_tlb(QEMUFile *f, void *pv, size_t size, ++ const VMStateField *field, JSONWriter *vmdesc) ++{ ++ ls3a5k_tlb_t *v = pv; ++ ++ uint16_t asid = v->ASID; ++ uint32_t flags = ((v->RPLV1 << 21) | ++ (v->RPLV0 << 20) | ++ (v->PLV1 << 18) | ++ (v->PLV0 << 16) | ++ (v->EHINV << 15) | ++ (v->RI1 << 14) | ++ (v->RI0 << 13) | ++ (v->XI1 << 12) | ++ (v->XI0 << 11) | ++ (v->WE1 << 10) | ++ (v->WE0 << 9) | ++ (v->V1 << 8) | ++ (v->V0 << 7) | ++ (v->C1 << 4) | ++ (v->C0 << 1) | ++ (v->G << 0)); ++ ++ qemu_put_betls(f, &v->VPN); ++ qemu_put_be64s(f, &v->PageMask); ++ qemu_put_be32s(f, &v->PageSize); ++ qemu_put_be16s(f, &asid); ++ qemu_put_be32s(f, &flags); ++ qemu_put_be64s(f, &v->PPN0); ++ qemu_put_be64s(f, &v->PPN1); ++ ++ return 0; ++} ++ ++const VMStateInfo vmstate_info_tlb = { ++ .name = "tlb_entry", ++ .get = get_tlb, ++ .put = put_tlb, ++}; ++ ++#define VMSTATE_TLB_ARRAY_V(_f, _s, _n, _v) \ ++ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_tlb, ls3a5k_tlb_t) ++ ++#define VMSTATE_TLB_ARRAY(_f, _s, _n) \ ++ VMSTATE_TLB_ARRAY_V(_f, _s, _n, 0) ++ ++const VMStateDescription vmstate_tlb = { ++ .name = "cpu/tlb", ++ .version_id = 2, ++ .minimum_version_id = 2, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT32(nb_tlb, CPULOONGARCHTLBContext), ++ VMSTATE_UINT32(tlb_in_use, CPULOONGARCHTLBContext), ++ VMSTATE_TLB_ARRAY(mmu.ls3a5k.tlb, CPULOONGARCHTLBContext, LOONGARCH_TLB_MAX), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++/* LOONGARCH CPU state */ ++ ++const VMStateDescription vmstate_loongarch_cpu = { ++ .name = "cpu", ++ .version_id = 15, ++ .minimum_version_id = 15, ++ .post_load = cpu_post_load, ++ .pre_save = cpu_pre_save, ++ .fields = (VMStateField[]) { ++ /* Active TC */ ++ VMSTATE_STRUCT(env.active_tc, LOONGARCHCPU, 1, vmstate_tc, TCState), ++ ++ /* Active FPU */ ++ VMSTATE_STRUCT(env.active_fpu, LOONGARCHCPU, 1, vmstate_fpu, ++ CPULOONGARCHFPUContext), ++ ++ /* TLB */ ++ VMSTATE_STRUCT_POINTER(env.tlb, LOONGARCHCPU, vmstate_tlb, ++ CPULOONGARCHTLBContext), ++ /* CPU metastate */ ++ VMSTATE_UINT32(env.current_tc, LOONGARCHCPU), ++ VMSTATE_INT32(env.error_code, LOONGARCHCPU), ++ VMSTATE_UINTTL(env.btarget, LOONGARCHCPU), ++ VMSTATE_UINTTL(env.bcond, LOONGARCHCPU), ++ ++ VMSTATE_UINT64(env.lladdr, LOONGARCHCPU), ++ ++ /* PV time */ ++ VMSTATE_UINT64(env.st.guest_addr, LOONGARCHCPU), ++ ++ /* Remaining CSR registers */ ++ 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_EEPN, 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_TLBWIRED, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_GTLBC, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_TRGP, 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_PWCTL0, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_PWCTL1, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_STLBPGSIZE, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_RVACFG, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_CPUID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_PRCFG1, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_PRCFG2, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_PRCFG3, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_KS0, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_KS1, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_KS2, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_KS3, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_KS4, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_KS5, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_KS6, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_KS7, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_TMID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_TCFG, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_TVAL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_CNTC, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_TINTCLR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_GSTAT, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_GCFG, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_GINTC, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_GCNTC, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_LLBCTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IMPCTL1, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IMPCTL2, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_GNMI, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_TLBRENT, 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_ERRCTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_ERRINFO, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_ERRINFO1, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_ERRENT, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_ERRERA, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_ERRSAVE, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_CTAG, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DMWIN0, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DMWIN1, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DMWIN2, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DMWIN3, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_PERFCTRL0, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_PERFCNTR0, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_PERFCTRL1, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_PERFCNTR1, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_PERFCTRL2, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_PERFCNTR2, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_PERFCTRL3, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_PERFCNTR3, LOONGARCHCPU), ++ /* debug */ ++ VMSTATE_UINT64(env.CSR_MWPC, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_MWPS, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB0ADDR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB0MASK, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB0CTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB0ASID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB1ADDR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB1MASK, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB1CTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB1ASID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB2ADDR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB2MASK, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB2CTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB2ASID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB3ADDR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB3MASK, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB3CTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DB3ASID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_FWPC, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_FWPS, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB0ADDR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB0MASK, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB0CTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB0ASID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB1ADDR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB1MASK, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB1CTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB1ASID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB2ADDR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB2MASK, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB2CTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB2ASID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB3ADDR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB3MASK, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB3CTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB3ASID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB4ADDR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB4MASK, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB4CTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB4ASID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB5ADDR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB5MASK, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB5CTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB5ASID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB6ADDR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB6MASK, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB6CTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB6ASID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB7ADDR, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB7MASK, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB7CTL, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_IB7ASID, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DEBUG, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DERA, LOONGARCHCPU), ++ VMSTATE_UINT64(env.CSR_DESAVE, LOONGARCHCPU), ++ ++ VMSTATE_STRUCT_ARRAY(env.fpus, LOONGARCHCPU, LOONGARCH_FPU_MAX, 1, ++ vmstate_inactive_fpu, CPULOONGARCHFPUContext), ++ VMSTATE_UINT8(online_vcpus, LOONGARCHCPU), ++ VMSTATE_UINT8(is_migrate, LOONGARCHCPU), ++ VMSTATE_UINT64(counter_value, LOONGARCHCPU), ++ VMSTATE_UINT32(cpu_freq, LOONGARCHCPU), ++ VMSTATE_UINT32(count_ctl, LOONGARCHCPU), ++ VMSTATE_UINT64(pending_exceptions, LOONGARCHCPU), ++ VMSTATE_UINT64(pending_exceptions_clr, LOONGARCHCPU), ++ VMSTATE_UINT64_ARRAY(core_ext_ioisr, LOONGARCHCPU, 4), ++ ++ VMSTATE_END_OF_LIST() ++ }, ++}; +diff --git a/target/loongarch64/meson.build b/target/loongarch64/meson.build +new file mode 100644 +index 0000000000..6badf4484e +--- /dev/null ++++ b/target/loongarch64/meson.build +@@ -0,0 +1,35 @@ ++loongarch_user_ss = ss.source_set() ++loongarch_softmmu_ss = ss.source_set() ++loongarch_ss = ss.source_set() ++loongarch_ss.add(files( ++ 'cpu.c', ++ 'fpu.c', ++ 'gdbstub.c', ++)) ++ ++gen = [ ++ decodetree.process('insn.decode', extra_args: [ '--decode', 'decode_insn', ++ '--insnwidth', '32' ]) ++] ++ ++loongarch_ss.add(gen) ++loongarch_ss.add(when: 'CONFIG_TCG', if_true: files( ++ 'helper.c', ++ 'translate.c', ++ 'op_helper.c', ++ 'fpu_helper.c', ++ 'tlb_helper.c', ++ 'csr_helper.c', ++)) ++ ++loongarch_softmmu_ss.add(when: 'CONFIG_SOFTMMU', if_true: files( ++ 'machine.c', ++ 'stabletimer.c', ++ 'arch_dump.c', ++)) ++ ++loongarch_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) ++ ++target_arch += {'loongarch64': loongarch_ss} ++target_softmmu_arch += {'loongarch64': loongarch_softmmu_ss} ++target_user_arch += {'loongarch64': loongarch_user_ss} +diff --git a/target/loongarch64/op_helper.c b/target/loongarch64/op_helper.c +new file mode 100644 +index 0000000000..9a34c0d25e +--- /dev/null ++++ b/target/loongarch64/op_helper.c +@@ -0,0 +1,533 @@ ++/* ++ * LOONGARCH emulation helpers for qemu. ++ * ++ * Copyright (c) 2004-2005 Jocelyn Mayer ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#include "qemu/osdep.h" ++#include "qemu/main-loop.h" ++#include "cpu.h" ++#include "internal.h" ++#include "qemu/host-utils.h" ++#include "exec/helper-proto.h" ++#include "exec/exec-all.h" ++#include "exec/cpu_ldst.h" ++#include "sysemu/kvm.h" ++#include "qemu/crc32c.h" ++#include ++#include "hw/irq.h" ++#include "hw/core/cpu.h" ++#include "instmap.h" ++ ++/*****************************************************************************/ ++/* Exceptions processing helpers */ ++ ++void helper_raise_exception_err(CPULOONGARCHState *env, uint32_t exception, ++ int error_code) ++{ ++ do_raise_exception_err(env, exception, error_code, 0); ++} ++ ++void helper_raise_exception(CPULOONGARCHState *env, uint32_t exception) ++{ ++ do_raise_exception(env, exception, GETPC()); ++} ++ ++void helper_raise_exception_debug(CPULOONGARCHState *env) ++{ ++ do_raise_exception(env, EXCP_DEBUG, 0); ++} ++ ++static void raise_exception(CPULOONGARCHState *env, uint32_t exception) ++{ ++ do_raise_exception(env, exception, 0); ++} ++ ++#if defined(CONFIG_USER_ONLY) ++#define HELPER_LD(name, insn, type) \ ++static inline type do_##name(CPULOONGARCHState *env, target_ulong addr, \ ++ int mem_idx, uintptr_t retaddr) \ ++{ \ ++ return (type) cpu_##insn##_data_ra(env, addr, retaddr); \ ++} ++#else ++ ++#define HF_SMAP_SHIFT 23 /* CR4.SMAP */ ++#define HF_SMAP_MASK (1 << HF_SMAP_SHIFT) ++#define MMU_KNOSMAP_IDX 2 ++#define HF_CPL_SHIFT 0 ++#define HF_CPL_MASK (3 << HF_CPL_SHIFT) ++#define AC_MASK 0x00040000 ++#define MMU_KSMAP_IDX 0 ++static inline int cpu_mmu_index_kernel(CPULOONGARCHState *env) ++{ ++ return !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP_IDX : ++ ((env->hflags & HF_CPL_MASK) < 3 && (env->hflags & AC_MASK)) ++ ? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX; ++} ++ ++#define cpu_ldl_kernel_ra(e, p, r) \ ++ cpu_ldl_mmuidx_ra(e, p, cpu_mmu_index_kernel(e), r) ++ ++#define HELPER_LD(name, insn, type) \ ++static inline type do_##name(CPULOONGARCHState *env, target_ulong addr, \ ++ int mem_idx, uintptr_t retaddr) \ ++{ \ ++/* \ ++ switch (mem_idx) { \ ++ case 0: return (type) cpu_##insn##_kernel_ra(env, addr, retaddr); \ ++ case 1: return (type) cpu_##insn##_super_ra(env, addr, retaddr); \ ++ default: \ ++ case 2: return (type) cpu_##insn##_user_ra(env, addr, retaddr); \ ++ case 3: return (type) cpu_##insn##_error_ra(env, addr, retaddr); \ ++ } \ ++*/ \ ++} ++#endif ++#if 0 ++HELPER_LD(lw, ldl, int32_t) ++HELPER_LD(ld, ldq, int64_t) ++#endif ++#undef HELPER_LD ++ ++#if defined(CONFIG_USER_ONLY) ++#define HELPER_ST(name, insn, type) \ ++static inline void do_##name(CPULOONGARCHState *env, target_ulong addr, \ ++ type val, int mem_idx, uintptr_t retaddr) \ ++{ \ ++/* \ ++ cpu_##insn##_data_ra(env, addr, val, retaddr); \ ++*/ \ ++} ++#else ++#define HELPER_ST(name, insn, type) \ ++static inline void do_##name(CPULOONGARCHState *env, target_ulong addr, \ ++ type val, int mem_idx, uintptr_t retaddr) \ ++{ \ ++/* \ ++ switch (mem_idx) { \ ++ case 0: \ ++ cpu_##insn##_kernel_ra(env, addr, val, retaddr); \ ++ break; \ ++ case 1: \ ++ cpu_##insn##_super_ra(env, addr, val, retaddr); \ ++ break; \ ++ default: \ ++ case 2: \ ++ cpu_##insn##_user_ra(env, addr, val, retaddr); \ ++ break; \ ++ case 3: \ ++ cpu_##insn##_error_ra(env, addr, val, retaddr); \ ++ break; \ ++ } \ ++*/ \ ++} ++#endif ++#if 0 ++HELPER_ST(sb, stb, uint8_t) ++HELPER_ST(sw, stl, uint32_t) ++HELPER_ST(sd, stq, uint64_t) ++#endif ++#undef HELPER_ST ++ ++static inline target_ulong bitswap(target_ulong v) ++{ ++ v = ((v >> 1) & (target_ulong)0x5555555555555555ULL) | ++ ((v & (target_ulong)0x5555555555555555ULL) << 1); ++ v = ((v >> 2) & (target_ulong)0x3333333333333333ULL) | ++ ((v & (target_ulong)0x3333333333333333ULL) << 2); ++ v = ((v >> 4) & (target_ulong)0x0F0F0F0F0F0F0F0FULL) | ++ ((v & (target_ulong)0x0F0F0F0F0F0F0F0FULL) << 4); ++ return v; ++} ++ ++target_ulong helper_dbitswap(target_ulong rt) ++{ ++ return bitswap(rt); ++} ++ ++target_ulong helper_bitswap(target_ulong rt) ++{ ++ return (int32_t)bitswap(rt); ++} ++ ++/* these crc32 functions are based on target/arm/helper-a64.c */ ++target_ulong helper_crc32(target_ulong val, target_ulong m, uint32_t sz) ++{ ++ uint8_t buf[8]; ++ target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1); ++ ++ m &= mask; ++ stq_le_p(buf, m); ++ return (int32_t) (crc32(val ^ 0xffffffff, buf, sz) ^ 0xffffffff); ++} ++ ++target_ulong helper_crc32c(target_ulong val, target_ulong m, uint32_t sz) ++{ ++ uint8_t buf[8]; ++ target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1); ++ m &= mask; ++ stq_le_p(buf, m); ++ return (int32_t) (crc32c(val, buf, sz) ^ 0xffffffff); ++} ++ ++#ifndef CONFIG_USER_ONLY ++ ++#define HELPER_LD_ATOMIC(name, insn, almask) \ ++target_ulong helper_##name(CPULOONGARCHState *env, target_ulong arg, int mem_idx) \ ++{ \ ++/* \ ++ if (arg & almask) { \ ++ env->CSR_BADV = arg; \ ++ do_raise_exception(env, EXCP_AdEL, GETPC()); \ ++ } \ ++ env->lladdr = arg; \ ++ env->llval = do_##insn(env, arg, mem_idx, GETPC()); \ ++ return env->llval; \ ++*/ \ ++} ++#if 0 ++HELPER_LD_ATOMIC(ll, lw, 0x3) ++HELPER_LD_ATOMIC(lld, ld, 0x7) ++#endif ++#undef HELPER_LD_ATOMIC ++#endif ++ ++#ifndef CONFIG_USER_ONLY ++void helper_drdtime(CPULOONGARCHState *env, target_ulong rd, target_ulong rs) ++{ ++ env->active_tc.gpr[rd] = cpu_loongarch_get_stable_counter(env); ++ env->active_tc.gpr[rs] = env->CSR_TMID; ++} ++#endif ++ ++#ifndef CONFIG_USER_ONLY ++static void debug_pre_ertn(CPULOONGARCHState *env) ++{ ++ if (qemu_loglevel_mask(CPU_LOG_EXEC)) { ++ qemu_log("ERTN: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx, ++ env->active_tc.PC, env->CSR_ERA); ++ qemu_log("\n"); ++ } ++} ++ ++static void debug_post_ertn(CPULOONGARCHState *env) ++{ ++ if (qemu_loglevel_mask(CPU_LOG_EXEC)) { ++ qemu_log("ERTN: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx, ++ env->active_tc.PC, env->CSR_ERA); ++ } ++} ++ ++static void set_pc(CPULOONGARCHState *env, target_ulong error_pc) ++{ ++ env->active_tc.PC = error_pc & ~(target_ulong)1; ++} ++ ++static inline void exception_return(CPULOONGARCHState *env) ++{ ++ debug_pre_ertn(env); ++ ++ if (cpu_refill_state(env)) { ++ env->CSR_CRMD &= (~0x7); ++ env->CSR_CRMD |= (env->CSR_TLBRPRMD & 0x7); ++ /* Clear Refill flag and set pc */ ++ env->CSR_TLBRERA &= (~0x1); ++ set_pc(env, env->CSR_TLBRERA); ++ if (qemu_loglevel_mask(CPU_LOG_INT)) { ++ qemu_log("%s: TLBRERA 0x%lx\n", __func__, env->CSR_TLBRERA); ++ } ++ } else { ++ env->CSR_CRMD &= (~0x7); ++ env->CSR_CRMD |= (env->CSR_PRMD & 0x7); ++ /* Clear Refill flag and set pc*/ ++ set_pc(env, env->CSR_ERA); ++ if (qemu_loglevel_mask(CPU_LOG_INT)) { ++ qemu_log("%s: ERA 0x%lx\n", __func__, env->CSR_ERA); ++ } ++ } ++ ++ compute_hflags(env); ++ debug_post_ertn(env); ++} ++ ++void helper_ertn(CPULOONGARCHState *env) ++{ ++ exception_return(env); ++ env->lladdr = 1; ++} ++ ++#endif /* !CONFIG_USER_ONLY */ ++ ++void helper_idle(CPULOONGARCHState *env) ++{ ++ CPUState *cs = CPU(loongarch_env_get_cpu(env)); ++ ++ cs->halted = 1; ++ cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE); ++ /* Last instruction in the block, PC was updated before ++ - no need to recover PC and icount */ ++ raise_exception(env, EXCP_HLT); ++} ++ ++#if !defined(CONFIG_USER_ONLY) ++ ++void loongarch_cpu_do_unaligned_access(CPUState *cs, vaddr addr, ++ MMUAccessType access_type, ++ int mmu_idx, uintptr_t retaddr) ++{ ++ while(1); ++} ++ ++#endif /* !CONFIG_USER_ONLY */ ++ ++void helper_store_scr(CPULOONGARCHState *env, uint32_t n, target_ulong val) ++{ ++ env->scr[n & 0x3] = val; ++} ++ ++target_ulong helper_load_scr(CPULOONGARCHState *env, uint32_t n) ++{ ++ return env->scr[n & 0x3]; ++} ++ ++/* loongarch assert op */ ++void helper_asrtle_d(CPULOONGARCHState *env, target_ulong rs, target_ulong rt) ++{ ++ if (rs > rt) { ++ do_raise_exception(env, EXCP_AdEL, GETPC()); ++ } ++} ++ ++void helper_asrtgt_d(CPULOONGARCHState *env, target_ulong rs, target_ulong rt) ++{ ++ if (rs <= rt) { ++ do_raise_exception(env, EXCP_AdEL, GETPC()); ++ } ++} ++ ++target_ulong helper_cto_w(CPULOONGARCHState *env, target_ulong a0) ++{ ++ uint32_t v = (uint32_t)a0; ++ int temp = 0; ++ ++ while ((v & 0x1) == 1) { ++ temp++; ++ v = v >> 1; ++ } ++ ++ return (target_ulong)temp; ++} ++ ++target_ulong helper_ctz_w(CPULOONGARCHState *env, target_ulong a0) ++{ ++ uint32_t v = (uint32_t)a0; ++ ++ if (v == 0) { ++ return 32; ++ } ++ ++ int temp = 0; ++ while ((v & 0x1) == 0) { ++ temp++; ++ v = v >> 1; ++ } ++ ++ return (target_ulong)temp; ++} ++ ++target_ulong helper_cto_d(CPULOONGARCHState *env, target_ulong a0) ++{ ++ uint64_t v = a0; ++ int temp = 0; ++ ++ while ((v & 0x1) == 1) { ++ temp++; ++ v = v >> 1; ++ } ++ ++ return (target_ulong)temp; ++} ++ ++target_ulong helper_ctz_d(CPULOONGARCHState *env, target_ulong a0) ++{ ++ uint64_t v = a0; ++ ++ if (v == 0) { ++ return 64; ++ } ++ ++ int temp = 0; ++ while ((v & 0x1) == 0) { ++ temp++; ++ v = v >> 1; ++ } ++ ++ return (target_ulong)temp; ++} ++ ++target_ulong helper_bitrev_w(CPULOONGARCHState *env, target_ulong a0) ++{ ++ int32_t v = (int32_t)a0; ++ const int SIZE = 32; ++ uint8_t bytes[SIZE]; ++ ++ int i; ++ for (i = 0; i < SIZE; i++) { ++ bytes[i] = v & 0x1; ++ v = v >> 1; ++ } ++ /* v == 0 */ ++ for (i = 0; i < SIZE; i++) { ++ v = v | ((uint32_t)bytes[i] << (SIZE - 1 - i)); ++ } ++ ++ return (target_ulong)(int32_t)v; ++} ++ ++target_ulong helper_bitrev_d(CPULOONGARCHState *env, target_ulong a0) ++{ ++ uint64_t v = a0; ++ const int SIZE = 64; ++ uint8_t bytes[SIZE]; ++ ++ int i; ++ for (i = 0; i < SIZE; i++) { ++ bytes[i] = v & 0x1; ++ v = v >> 1; ++ } ++ /* v == 0 */ ++ for (i = 0; i < SIZE; i++) { ++ v = v | ((uint64_t)bytes[i] << (SIZE - 1 - i)); ++ } ++ ++ return (target_ulong)v; ++} ++ ++void helper_memtrace_addr(CPULOONGARCHState *env, ++ target_ulong address, uint32_t op) ++{ ++ qemu_log("[cpu %d asid 0x%lx pc 0x%lx] addr 0x%lx op", ++ CPU(loongarch_env_get_cpu(env))->cpu_index, ++ env->CSR_ASID, env->active_tc.PC, address); ++ switch (op) { ++ case OPC_LARCH_LDPTR_D: ++ qemu_log("OPC_LARCH_LDPTR_D"); ++ break; ++ case OPC_LARCH_LD_D: ++ qemu_log("OPC_LARCH_LD_D"); ++ break; ++ case OPC_LARCH_LDPTR_W: ++ qemu_log("OPC_LARCH_LDPTR_W"); ++ break; ++ case OPC_LARCH_LD_W: ++ qemu_log("OPC_LARCH_LD_W"); ++ break; ++ case OPC_LARCH_LD_H: ++ qemu_log("OPC_LARCH_LD_H"); ++ break; ++ case OPC_LARCH_LD_B: ++ qemu_log("OPC_LARCH_LD_B"); ++ break; ++ case OPC_LARCH_LD_WU: ++ qemu_log("OPC_LARCH_LD_WU"); ++ break; ++ case OPC_LARCH_LD_HU: ++ qemu_log("OPC_LARCH_LD_HU"); ++ break; ++ case OPC_LARCH_LD_BU: ++ qemu_log("OPC_LARCH_LD_BU"); ++ break; ++ case OPC_LARCH_STPTR_D: ++ qemu_log("OPC_LARCH_STPTR_D"); ++ break; ++ case OPC_LARCH_ST_D: ++ qemu_log("OPC_LARCH_ST_D"); ++ break; ++ case OPC_LARCH_STPTR_W: ++ qemu_log("OPC_LARCH_STPTR_W"); ++ break; ++ case OPC_LARCH_ST_W: ++ qemu_log("OPC_LARCH_ST_W"); ++ break; ++ case OPC_LARCH_ST_H: ++ qemu_log("OPC_LARCH_ST_H"); ++ break; ++ case OPC_LARCH_ST_B: ++ qemu_log("OPC_LARCH_ST_B"); ++ break; ++ case OPC_LARCH_FLD_S: ++ qemu_log("OPC_LARCH_FLD_S"); ++ break; ++ case OPC_LARCH_FLD_D: ++ qemu_log("OPC_LARCH_FLD_D"); ++ break; ++ case OPC_LARCH_FST_S: ++ qemu_log("OPC_LARCH_FST_S"); ++ break; ++ case OPC_LARCH_FST_D: ++ qemu_log("OPC_LARCH_FST_D"); ++ break; ++ case OPC_LARCH_FLDX_S: ++ qemu_log("OPC_LARCH_FLDX_S"); ++ break; ++ case OPC_LARCH_FLDGT_S: ++ qemu_log("OPC_LARCH_FLDGT_S"); ++ break; ++ case OPC_LARCH_FLDLE_S: ++ qemu_log("OPC_LARCH_FLDLE_S"); ++ break;; ++ case OPC_LARCH_FSTX_S: ++ qemu_log("OPC_LARCH_FSTX_S"); ++ break; ++ case OPC_LARCH_FSTGT_S: ++ qemu_log("OPC_LARCH_FSTGT_S"); ++ break; ++ case OPC_LARCH_FSTLE_S: ++ qemu_log("OPC_LARCH_FSTLE_S"); ++ break; ++ case OPC_LARCH_FLDX_D: ++ qemu_log("OPC_LARCH_FLDX_D"); ++ break; ++ case OPC_LARCH_FLDGT_D: ++ qemu_log("OPC_LARCH_FLDGT_D"); ++ break; ++ case OPC_LARCH_FLDLE_D: ++ qemu_log("OPC_LARCH_FLDLE_D"); ++ break;; ++ case OPC_LARCH_FSTX_D: ++ qemu_log("OPC_LARCH_FSTX_D"); ++ break; ++ case OPC_LARCH_FSTGT_D: ++ qemu_log("OPC_LARCH_FSTGT_D"); ++ break; ++ case OPC_LARCH_FSTLE_D: ++ qemu_log("OPC_LARCH_FSTLE_D"); ++ break; ++ case OPC_LARCH_LL_W: ++ qemu_log("OPC_LARCH_LL_W"); ++ break; ++ case OPC_LARCH_LL_D: ++ qemu_log("OPC_LARCH_LL_D"); ++ break; ++ default: ++ qemu_log("0x%x", op); ++ } ++} ++ ++void helper_memtrace_val(CPULOONGARCHState *env, target_ulong val) ++{ ++ qemu_log("val 0x%lx\n", val); ++} +diff --git a/target/loongarch64/stabletimer.c b/target/loongarch64/stabletimer.c +new file mode 100644 +index 0000000000..b86fecf899 +--- /dev/null ++++ b/target/loongarch64/stabletimer.c +@@ -0,0 +1,122 @@ ++/* ++ * QEMU LOONGARCH timer support ++ * ++ * 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 "hw/loongarch/cpudevs.h" ++#include "qemu/timer.h" ++#include "sysemu/kvm.h" ++#include "internal.h" ++#include "hw/irq.h" ++ ++ ++#ifdef DEBUG_TIMER ++#define debug_timer(fmt, args...) printf("%s(%d)-%s -> " #fmt "\n", \ ++ __FILE__, __LINE__, __func__, ##args); ++#else ++#define debug_timer(fmt, args...) ++#endif ++ ++#define TIMER_PERIOD 10 /* 10 ns period for 100 Mhz frequency */ ++#define STABLETIMER_TICK_MASK 0xfffffffffffcUL ++#define STABLETIMER_ENABLE 0x1UL ++#define STABLETIMER_PERIOD 0x2UL ++ ++/* return random value in [low, high] */ ++uint32_t cpu_loongarch_get_random_ls3a5k_tlb(uint32_t low, uint32_t high) ++{ ++ static uint32_t seed = 5; ++ static uint32_t prev_idx; ++ uint32_t idx; ++ uint32_t nb_rand_tlb = high - low + 1; ++ ++ do { ++ seed = 1103515245 * seed + 12345; ++ idx = (seed >> 16) % nb_rand_tlb + low; ++ } while (idx == prev_idx); ++ prev_idx = idx; ++ ++ return idx; ++} ++ ++/* LOONGARCH timer */ ++uint64_t cpu_loongarch_get_stable_counter(CPULOONGARCHState *env) ++{ ++ return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / TIMER_PERIOD; ++} ++ ++uint64_t cpu_loongarch_get_stable_timer_ticks(CPULOONGARCHState *env) ++{ ++ uint64_t now, expire; ++ ++ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ++ expire = timer_expire_time_ns(env->timer); ++ ++ return (expire - now) / TIMER_PERIOD; ++} ++ ++void cpu_loongarch_store_stable_timer_config(CPULOONGARCHState *env, ++ uint64_t value) ++{ ++ uint64_t now, next; ++ ++ env->CSR_TCFG = value; ++ if (value & STABLETIMER_ENABLE) { ++ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ++ next = now + (value & STABLETIMER_TICK_MASK) * TIMER_PERIOD; ++ timer_mod(env->timer, next); ++ } ++ debug_timer("0x%lx 0x%lx now 0x%lx, next 0x%lx", ++ value, env->CSR_TCFG, now, next); ++} ++ ++static void loongarch_stable_timer_cb(void *opaque) ++{ ++ CPULOONGARCHState *env; ++ uint64_t now, next; ++ ++ env = opaque; ++ debug_timer(); ++ if (env->CSR_TCFG & STABLETIMER_PERIOD) { ++ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ++ next = now + (env->CSR_TCFG & STABLETIMER_TICK_MASK) * TIMER_PERIOD; ++ timer_mod(env->timer, next); ++ } else { ++ env->CSR_TCFG &= ~STABLETIMER_ENABLE; ++ } ++ ++ qemu_irq_raise(env->irq[IRQ_TIMER]); ++ ++} ++ ++void cpu_loongarch_clock_init(LOONGARCHCPU *cpu) ++{ ++ CPULOONGARCHState *env = &cpu->env; ++ ++ /* ++ * If we're in KVM mode, don't create the periodic timer, that is handled in ++ * kernel. ++ */ ++ if (!kvm_enabled()) { ++ env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ++ &loongarch_stable_timer_cb, env); ++ } ++} +diff --git a/target/loongarch64/tlb_helper.c b/target/loongarch64/tlb_helper.c +new file mode 100644 +index 0000000000..f5e68349a9 +--- /dev/null ++++ b/target/loongarch64/tlb_helper.c +@@ -0,0 +1,729 @@ ++/* ++ * loongarch tlb emulation helpers for qemu. ++ * ++ * Copyright (c) 2020 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#include "qemu/osdep.h" ++#include "qemu/main-loop.h" ++#include "cpu.h" ++#include "internal.h" ++#include "qemu/host-utils.h" ++#include "exec/helper-proto.h" ++#include "exec/exec-all.h" ++#include "exec/cpu_ldst.h" ++ ++#ifndef CONFIG_USER_ONLY ++ ++#define HELPER_LD(name, insn, type) \ ++static inline type do_##name(CPULOONGARCHState *env, target_ulong addr, \ ++ int mem_idx, uintptr_t retaddr) \ ++{ \ ++/* \ ++ switch (mem_idx) { \ ++ case 0: return (type) cpu_##insn##_kernel_ra(env, addr, retaddr); \ ++ case 1: return (type) cpu_##insn##_super_ra(env, addr, retaddr); \ ++ default: \ ++ case 2: return (type) cpu_##insn##_user_ra(env, addr, retaddr); \ ++ case 3: return (type) cpu_##insn##_error_ra(env, addr, retaddr); \ ++ } \ ++*/ \ ++} ++#if 0 ++HELPER_LD(lw, ldl, int32_t) ++HELPER_LD(ld, ldq, int64_t) ++#endif ++ ++void helper_lddir(CPULOONGARCHState *env, target_ulong base, target_ulong rt, ++ target_ulong level, uint32_t mem_idx) ++{ ++#if 0 ++ target_ulong pointer = env->active_tc.gpr[base]; ++ target_ulong badvaddr; ++ target_ulong index; ++ target_ulong vaddr; ++ int shift; ++ ++ badvaddr = env->CSR_TLBRBADV; ++ ++ /* 0:8B, 1:16B, 2:32B, 3:64B */ ++ shift = (env->CSR_PWCTL0 >> 30) & 0x3; ++ shift = (shift + 1) * 3; ++ ++ switch (level) { ++ case 1: ++ index = (badvaddr >> ((env->CSR_PWCTL0 >> 10) & 0x1f)) & \ ++ ((1 << ((env->CSR_PWCTL0 >> 15) & 0x1f)) - 1); ++ break; ++ case 3: ++ index = (badvaddr >> ((env->CSR_PWCTL1 >> 0) & 0x3f)) & \ ++ ((1 << ((env->CSR_PWCTL1 >> 6) & 0x3f)) - 1); ++ break; ++ default: ++ do_raise_exception(env, EXCP_RI, GETPC()); ++ return; ++ } ++ ++ vaddr = pointer | index << shift; ++ env->active_tc.gpr[rt] = do_ld(env, vaddr, mem_idx, GETPC()); ++ return; ++#endif ++} ++ ++void helper_ldpte(CPULOONGARCHState *env, target_ulong base, target_ulong odd, ++ uint32_t mem_idx) ++{ ++#if 0 ++ target_ulong pointer = env->active_tc.gpr[base]; ++ target_ulong vaddr; ++ target_ulong tmp0 = 1; ++ target_ulong ptindex, ptoffset0, ptoffset1; ++ target_ulong pagesize; ++ target_ulong badv; ++ int shift; ++ bool huge = pointer & LOONGARCH_PAGE_HUGE; ++ ++ if (huge) { ++ /* Huge Page. pointer is paddr */ ++ tmp0 = pointer ^ LOONGARCH_PAGE_HUGE; ++ /* move Global bit */ ++ tmp0 |= ((tmp0 & LOONGARCH_HUGE_GLOBAL) ++ >> (LOONGARCH_HUGE_GLOBAL_SH - CSR_TLBLO0_GLOBAL_SHIFT)); ++ pagesize = (env->CSR_PWCTL0 & 0x1f) + ++ ((env->CSR_PWCTL0 >> 5) & 0x1f) - 1; ++ if (odd) { ++ tmp0 += (1 << pagesize); ++ } ++ } else { ++ /* 0:8B, 1:16B, 2:32B, 3:64B */ ++ shift = (env->CSR_PWCTL0 >> 30) & 0x3; ++ shift = (shift + 1) * 3; ++ badv = env->CSR_TLBRBADV; ++ ++ ptindex = (badv >> (env->CSR_PWCTL0 & 0x1f)) & ++ ((1 << ((env->CSR_PWCTL0 >> 5) & 0x1f)) - 1); ++ ptindex = ptindex & ~0x1; /* clear bit 0 */ ++ ptoffset0 = ptindex << shift; ++ ptoffset1 = (ptindex + 1) << shift; ++ ++ vaddr = pointer | (odd ? ptoffset1 : ptoffset0); ++ tmp0 = do_ld(env, vaddr, mem_idx, GETPC()); ++ pagesize = (env->CSR_PWCTL0 & 0x1f); ++ } ++ if (odd) { ++ env->CSR_TLBRELO1 = tmp0; ++ } else { ++ env->CSR_TLBRELO0 = tmp0; ++ } ++ env->CSR_TLBREHI = env->CSR_TLBREHI & (~0x3f); ++ env->CSR_TLBREHI = env->CSR_TLBREHI | pagesize; ++#endif ++ return; ++} ++ ++target_ulong helper_read_pgd(CPULOONGARCHState *env) ++{ ++ uint64_t badv; ++ ++ assert(env->CSR_TLBRERA & 0x1); ++ ++ if (env->CSR_TLBRERA & 0x1) { ++ badv = env->CSR_TLBRBADV; ++ } else { ++ badv = env->CSR_BADV; ++ } ++ ++ if ((badv >> 63) & 0x1) { ++ return env->CSR_PGDH; ++ } else { ++ return env->CSR_PGDL; ++ } ++} ++ ++/* TLB management */ ++static uint64_t ls3a5k_pagesize_to_mask(int pagesize) ++{ ++ /* 4KB - 1GB */ ++ if (pagesize < 12 && pagesize > 30) { ++ printf("[ERROR] unsupported page size %d\n", pagesize); ++ exit(-1); ++ } ++ ++ return (1 << (pagesize + 1)) - 1; ++} ++ ++static void ls3a5k_fill_tlb_entry(CPULOONGARCHState *env, ++ ls3a5k_tlb_t *tlb, int is_ftlb) ++{ ++ uint64_t page_mask; /* 0000...00001111...1111 */ ++ uint32_t page_size; ++ uint64_t entryhi; ++ uint64_t lo0, lo1; ++ ++ if (env->CSR_TLBRERA & 0x1) { ++ page_size = env->CSR_TLBREHI & 0x3f; ++ entryhi = env->CSR_TLBREHI; ++ lo0 = env->CSR_TLBRELO0; ++ lo1 = env->CSR_TLBRELO1; ++ } else { ++ page_size = (env->CSR_TLBIDX >> CSR_TLBIDX_PS_SHIFT) & 0x3f; ++ entryhi = env->CSR_TLBEHI; ++ lo0 = env->CSR_TLBELO0; ++ lo1 = env->CSR_TLBELO1; ++ } ++ ++ if (page_size == 0) { ++ printf("Warning: page_size is 0\n"); ++ } ++ ++ /* 15-12 11-8 7-4 3-0 ++ * 4KB: 0001 1111 1111 1111 // double 4KB mask [12:0] ++ * 16KB: 0111 1111 1111 1111 // double 16KB mask [14:0] ++ */ ++ if (is_ftlb) { ++ page_mask = env->tlb->mmu.ls3a5k.ftlb_mask; ++ } else { ++ page_mask = ls3a5k_pagesize_to_mask(page_size); ++ } ++ ++ tlb->VPN = entryhi & 0xffffffffe000 & ~page_mask; ++ ++ tlb->ASID = env->CSR_ASID & 0x3ff; /* CSR_ASID[9:0] */ ++ tlb->EHINV = 0; ++ tlb->G = (lo0 >> CSR_TLBLO0_GLOBAL_SHIFT) & /* CSR_TLBLO[6] */ ++ (lo1 >> CSR_TLBLO1_GLOBAL_SHIFT) & 1; ++ ++ tlb->PageMask = page_mask; ++ tlb->PageSize = page_size; ++ ++ tlb->V0 = (lo0 >> CSR_TLBLO0_V_SHIFT) & 0x1; /* [0] */ ++ tlb->WE0 = (lo0 >> CSR_TLBLO0_WE_SHIFT) & 0x1; /* [1] */ ++ tlb->PLV0 = (lo0 >> CSR_TLBLO0_PLV_SHIFT) & 0x3; /* [3:2] */ ++ tlb->C0 = (lo0 >> CSR_TLBLO0_CCA_SHIFT) & 0x3; /* [5:4] */ ++ tlb->PPN0 = (lo0 & 0xfffffffff000 & ~(page_mask >> 1)); ++ tlb->RI0 = (lo0 >> CSR_TLBLO0_RI_SHIFT) & 0x1; /* [61] */ ++ tlb->XI0 = (lo0 >> CSR_TLBLO0_XI_SHIFT) & 0x1; /* [62] */ ++ tlb->RPLV0 = (lo0 >> CSR_TLBLO0_RPLV_SHIFT) & 0x1; /* [63] */ ++ ++ tlb->V1 = (lo1 >> CSR_TLBLO1_V_SHIFT) & 0x1; /* [0] */ ++ tlb->WE1 = (lo1 >> CSR_TLBLO1_WE_SHIFT) & 0x1; /* [1] */ ++ tlb->PLV1 = (lo1 >> CSR_TLBLO1_PLV_SHIFT) & 0x3; /* [3:2] */ ++ tlb->C1 = (lo1 >> CSR_TLBLO1_CCA_SHIFT) & 0x3; /* [5:4] */ ++ tlb->PPN1 = (lo1 & 0xfffffffff000 & ~(page_mask >> 1)); ++ tlb->RI1 = (lo1 >> CSR_TLBLO1_RI_SHIFT) & 0x1; /* [61] */ ++ tlb->XI1 = (lo1 >> CSR_TLBLO1_XI_SHIFT) & 0x1; /* [62] */ ++ tlb->RPLV1 = (lo1 >> CSR_TLBLO1_RPLV_SHIFT) & 0x1; /* [63] */ ++} ++ ++static void ls3a5k_fill_tlb(CPULOONGARCHState *env, int idx, bool tlbwr) ++{ ++ ls3a5k_tlb_t *tlb; ++ ++ tlb = &env->tlb->mmu.ls3a5k.tlb[idx]; ++ if (tlbwr) { ++ if ((env->CSR_TLBIDX >> CSR_TLBIDX_EHINV_SHIFT) & 0x1) { ++ tlb->EHINV = 1; ++ return; ++ } ++ } ++ ++ if (idx < 2048) { ++ ls3a5k_fill_tlb_entry(env, tlb, 1); ++ } else { ++ ls3a5k_fill_tlb_entry(env, tlb, 0); ++ } ++} ++ ++void ls3a5k_flush_vtlb(CPULOONGARCHState *env) ++{ ++ uint32_t ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; ++ uint32_t vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; ++ int i; ++ ++ ls3a5k_tlb_t *tlb; ++ ++ for (i = ftlb_size; i < ftlb_size + vtlb_size; ++i) { ++ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ tlb->EHINV = 1; ++ } ++ ++ cpu_loongarch_tlb_flush(env); ++} ++ ++void ls3a5k_flush_ftlb(CPULOONGARCHState *env) ++{ ++ uint32_t ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; ++ int i; ++ ++ ls3a5k_tlb_t *tlb; ++ ++ for (i = 0; i < ftlb_size; ++i) { ++ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ tlb->EHINV = 1; ++ } ++ ++ cpu_loongarch_tlb_flush(env); ++} ++ ++void ls3a5k_helper_tlbclr(CPULOONGARCHState *env) ++{ ++ int i; ++ uint16_t asid; ++ int vsize, fsize, index; ++ int start = 0, end = -1; ++ ++ asid = env->CSR_ASID & 0x3ff; ++ vsize = env->tlb->mmu.ls3a5k.vtlb_size; ++ fsize = env->tlb->mmu.ls3a5k.ftlb_size; ++ index = env->CSR_TLBIDX & CSR_TLBIDX_IDX; ++ ++ if (index < fsize) { ++ /* FTLB. One line per operation */ ++ int set = index % 256; ++ start = set * 8; ++ end = start + 7; ++ } else if (index < (fsize + vsize)) { ++ /* VTLB. All entries */ ++ start = fsize; ++ end = fsize + vsize - 1; ++ } else { ++ /* Ignore */ ++ } ++ ++ for (i = start; i <= end; i++) { ++ ls3a5k_tlb_t *tlb; ++ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ if (!tlb->G && tlb->ASID == asid) { ++ tlb->EHINV = 1; ++ } ++ } ++ ++ cpu_loongarch_tlb_flush(env); ++} ++ ++void ls3a5k_helper_tlbflush(CPULOONGARCHState *env) ++{ ++ int i; ++ int vsize, fsize, index; ++ int start = 0, end = -1; ++ ++ vsize = env->tlb->mmu.ls3a5k.vtlb_size; ++ fsize = env->tlb->mmu.ls3a5k.ftlb_size; ++ index = env->CSR_TLBIDX & CSR_TLBIDX_IDX; ++ ++ if (index < fsize) { ++ /* FTLB. One line per operation */ ++ int set = index % 256; ++ start = set * 8; ++ end = start + 7; ++ } else if (index < (fsize + vsize)) { ++ /* VTLB. All entries */ ++ start = fsize; ++ end = fsize + vsize - 1; ++ } else { ++ /* Ignore */ ++ } ++ ++ for (i = start; i <= end; i++) { ++ env->tlb->mmu.ls3a5k.tlb[i].EHINV = 1; ++ } ++ ++ cpu_loongarch_tlb_flush(env); ++} ++ ++void ls3a5k_helper_invtlb(CPULOONGARCHState *env, target_ulong addr, ++ target_ulong info, int op) ++{ ++ uint32_t asid = info & 0x3ff; ++ int i; ++ ++ switch (op) { ++ case 0: ++ case 1: ++ for (i = 0; i < env->tlb->nb_tlb; i++) { ++ env->tlb->mmu.ls3a5k.tlb[i].EHINV = 1; ++ } ++ break; ++ case 4: { ++ int i; ++ for (i = 0; i < env->tlb->nb_tlb; i++) { ++ struct ls3a5k_tlb_t *tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ ++ if (!tlb->G && tlb->ASID == asid) { ++ tlb->EHINV = 1; ++ } ++ } ++ break; ++ } ++ ++ case 5: { ++ int i; ++ for (i = 0; i < env->tlb->nb_tlb; i++) { ++ struct ls3a5k_tlb_t *tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ uint64_t vpn = addr & 0xffffffffe000 & ~tlb->PageMask; ++ ++ if (!tlb->G && tlb->ASID == asid && vpn == tlb->VPN) { ++ tlb->EHINV = 1; ++ } ++ } ++ break; ++ } ++ case 6: { ++ int i; ++ for (i = 0; i < env->tlb->nb_tlb; i++) { ++ struct ls3a5k_tlb_t *tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ uint64_t vpn = addr & 0xffffffffe000 & ~tlb->PageMask; ++ ++ if ((tlb->G || tlb->ASID == asid) && vpn == tlb->VPN) { ++ tlb->EHINV = 1; ++ } ++ } ++ break; ++ } ++ default: ++ helper_raise_exception(env, EXCP_RI); ++ } ++ ++ cpu_loongarch_tlb_flush(env); ++} ++ ++static void ls3a5k_invalidate_tlb_entry(CPULOONGARCHState *env, ++ ls3a5k_tlb_t *tlb) ++{ ++ LOONGARCHCPU *cpu = loongarch_env_get_cpu(env); ++ CPUState *cs = CPU(cpu); ++ target_ulong addr; ++ target_ulong end; ++ target_ulong mask; ++ ++ mask = tlb->PageMask; /* 000...000111...111 */ ++ ++ if (tlb->V0) { ++ addr = tlb->VPN & ~mask; /* xxx...xxx[0]000..0000 */ ++ end = addr | (mask >> 1); /* xxx...xxx[0]111..1111 */ ++ while (addr < end) { ++ tlb_flush_page(cs, addr); ++ addr += TARGET_PAGE_SIZE; ++ } ++ } ++ ++ if (tlb->V1) { ++ /* xxx...xxx[1]000..0000 */ ++ addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1); ++ end = addr | mask; /* xxx...xxx[1]111..1111 */ ++ while (addr - 1 < end) { ++ tlb_flush_page(cs, addr); ++ addr += TARGET_PAGE_SIZE; ++ } ++ } ++} ++ ++void ls3a5k_invalidate_tlb(CPULOONGARCHState *env, int idx) ++{ ++ ls3a5k_tlb_t *tlb; ++ int asid = env->CSR_ASID & 0x3ff; ++ tlb = &env->tlb->mmu.ls3a5k.tlb[idx]; ++ if (tlb->G == 0 && tlb->ASID != asid) { ++ return; ++ } ++ ls3a5k_invalidate_tlb_entry(env, tlb); ++} ++ ++void ls3a5k_helper_tlbwr(CPULOONGARCHState *env) ++{ ++ int idx = env->CSR_TLBIDX & CSR_TLBIDX_IDX; /* [11:0] */ ++ ++ /* Convert idx if in FTLB */ ++ if (idx < env->tlb->mmu.ls3a5k.ftlb_size) { ++ /* ++ * 0 3 6 0 1 2 ++ * 1 4 7 => 3 4 5 ++ * 2 5 8 6 7 8 ++ */ ++ int set = idx % 256; ++ int way = idx / 256; ++ idx = set * 8 + way; ++ } ++ ls3a5k_invalidate_tlb(env, idx); ++ ls3a5k_fill_tlb(env, idx, true); ++} ++ ++void ls3a5k_helper_tlbfill(CPULOONGARCHState *env) ++{ ++ uint64_t mask; ++ uint64_t address; ++ int idx; ++ int set, ftlb_idx; ++ ++ uint64_t entryhi; ++ uint32_t pagesize; ++ ++ if (env->CSR_TLBRERA & 0x1) { ++ entryhi = env->CSR_TLBREHI & ~0x3f; ++ pagesize = env->CSR_TLBREHI & 0x3f; ++ } else { ++ entryhi = env->CSR_TLBEHI; ++ pagesize = (env->CSR_TLBIDX >> CSR_TLBIDX_PS_SHIFT) & 0x3f; ++ } ++ ++ uint32_t ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; ++ uint32_t vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; ++ ++ mask = ls3a5k_pagesize_to_mask(pagesize); ++ ++ if (mask == env->tlb->mmu.ls3a5k.ftlb_mask && ++ env->tlb->mmu.ls3a5k.ftlb_size > 0) { ++ /* only write into FTLB */ ++ address = entryhi & 0xffffffffe000; /* [47:13] */ ++ ++ /* choose one set ramdomly */ ++ set = cpu_loongarch_get_random_ls3a5k_tlb(0, 7); ++ ++ /* index in one set */ ++ ftlb_idx = (address >> 15) & 0xff; /* [0,255] */ ++ ++ /* final idx */ ++ idx = ftlb_idx * 8 + set; /* max is 7 + 8 * 255 = 2047 */ ++ } else { ++ /* only write into VTLB */ ++ int wired_nr = env->CSR_TLBWIRED & 0x3f; ++ idx = cpu_loongarch_get_random_ls3a5k_tlb( ++ ftlb_size + wired_nr, ftlb_size + vtlb_size - 1); ++ } ++ ++ ls3a5k_invalidate_tlb(env, idx); ++ ls3a5k_fill_tlb(env, idx, false); ++} ++ ++void ls3a5k_helper_tlbsrch(CPULOONGARCHState *env) ++{ ++ uint64_t mask; ++ uint64_t vpn; ++ uint64_t tag; ++ uint16_t asid; ++ ++ int ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; ++ int vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; ++ int i; ++ int ftlb_idx; /* [0,255] 2^8 0xff */ ++ ++ ls3a5k_tlb_t *tlb; ++ ++ asid = env->CSR_ASID & 0x3ff; ++ ++ /* search VTLB */ ++ for (i = ftlb_size; i < ftlb_size + vtlb_size; ++i) { ++ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ mask = tlb->PageMask; ++ ++ vpn = env->CSR_TLBEHI & 0xffffffffe000 & ~mask; ++ tag = tlb->VPN & ~mask; ++ ++ if ((tlb->G == 1 || tlb->ASID == asid) && vpn == tag && tlb->EHINV != 1) ++ { ++ env->CSR_TLBIDX = (i & 0xfff) | ++ ((tlb->PageSize & 0x3f) << CSR_TLBIDX_PS_SHIFT); ++ goto _MATCH_OUT_; ++ } ++ } ++ ++ if (ftlb_size == 0) { ++ goto _NO_MATCH_OUT_; ++ } ++ ++ /* search FTLB */ ++ mask = env->tlb->mmu.ls3a5k.ftlb_mask; ++ vpn = env->CSR_TLBEHI & 0xffffffffe000 & ~mask; ++ ++ ftlb_idx = (env->CSR_TLBEHI & 0xffffffffe000) >> 15; /* 16 KB */ ++ ftlb_idx = ftlb_idx & 0xff; /* [0,255] */ ++ ++ for (i = 0; i < 8; ++i) { ++ tlb = &env->tlb->mmu.ls3a5k.tlb[ftlb_idx * 8 + i]; ++ tag = tlb->VPN & ~mask; ++ ++ if ((tlb->G == 1 || tlb->ASID == asid) && vpn == tag && tlb->EHINV != 1) ++ { ++ env->CSR_TLBIDX = ((i * 256 + ftlb_idx) & 0xfff) | ++ ((tlb->PageSize & 0x3f) << CSR_TLBIDX_PS_SHIFT); ++ goto _MATCH_OUT_; ++ } ++ } ++ ++_NO_MATCH_OUT_: ++ env->CSR_TLBIDX = 1 << CSR_TLBIDX_EHINV_SHIFT; ++_MATCH_OUT_: ++ return; ++} ++ ++void ls3a5k_helper_tlbrd(CPULOONGARCHState *env) ++{ ++ ls3a5k_tlb_t *tlb; ++ int idx; ++ uint16_t asid; ++ ++ idx = env->CSR_TLBIDX & CSR_TLBIDX_IDX; ++ if (idx < env->tlb->mmu.ls3a5k.ftlb_size) { ++ int set = idx % 256; ++ int way = idx / 256; ++ idx = set * 8 + way; ++ } ++ ++ tlb = &env->tlb->mmu.ls3a5k.tlb[idx]; ++ ++ asid = env->CSR_ASID & 0x3ff; ++ ++ if (asid != tlb->ASID) { ++ cpu_loongarch_tlb_flush(env); ++ } ++ ++ if (tlb->EHINV) { ++ /* invalid TLB entry */ ++ env->CSR_TLBIDX = 1 << CSR_TLBIDX_EHINV_SHIFT; ++ env->CSR_TLBEHI = 0; ++ env->CSR_TLBELO0 = 0; ++ env->CSR_TLBELO1 = 0; ++ } else { ++ /* valid TLB entry */ ++ env->CSR_TLBIDX = (env->CSR_TLBIDX & 0xfff) | ++ ((tlb->PageSize & 0x3f) << CSR_TLBIDX_PS_SHIFT); ++ env->CSR_TLBEHI = tlb->VPN; ++ env->CSR_TLBELO0 = (tlb->V0 << CSR_TLBLO0_V_SHIFT) | ++ (tlb->WE0 << CSR_TLBLO0_WE_SHIFT) | ++ (tlb->PLV0 << CSR_TLBLO0_PLV_SHIFT) | ++ (tlb->C0 << CSR_TLBLO0_CCA_SHIFT) | ++ (tlb->G << CSR_TLBLO0_GLOBAL_SHIFT) | ++ (tlb->PPN0 & 0xfffffffff000) | ++ ((uint64_t)tlb->RI0 << CSR_TLBLO0_RI_SHIFT) | ++ ((uint64_t)tlb->XI0 << CSR_TLBLO0_XI_SHIFT) | ++ ((uint64_t)tlb->RPLV0 << CSR_TLBLO0_RPLV_SHIFT); ++ env->CSR_TLBELO1 = (tlb->V1 << CSR_TLBLO1_V_SHIFT) | ++ (tlb->WE1 << CSR_TLBLO1_WE_SHIFT) | ++ (tlb->PLV1 << CSR_TLBLO1_PLV_SHIFT) | ++ (tlb->C1 << CSR_TLBLO1_CCA_SHIFT) | ++ (tlb->G << CSR_TLBLO0_GLOBAL_SHIFT) | ++ (tlb->PPN1 & 0xfffffffff000) | ++ ((uint64_t)tlb->RI1 << CSR_TLBLO1_RI_SHIFT) | ++ ((uint64_t)tlb->XI1 << CSR_TLBLO1_XI_SHIFT) | ++ ((uint64_t)tlb->RPLV1 << CSR_TLBLO1_RPLV_SHIFT); ++ env->CSR_ASID = (tlb->ASID << CSR_ASID_ASID_SHIFT) | ++ (env->CSR_ASID & 0xff0000); ++ } ++} ++ ++void helper_tlbwr(CPULOONGARCHState *env) ++{ ++ env->tlb->helper_tlbwr(env); ++} ++ ++void helper_tlbfill(CPULOONGARCHState *env) ++{ ++ env->tlb->helper_tlbfill(env); ++} ++ ++void helper_tlbsrch(CPULOONGARCHState *env) ++{ ++ env->tlb->helper_tlbsrch(env); ++} ++ ++void helper_tlbrd(CPULOONGARCHState *env) ++{ ++ env->tlb->helper_tlbrd(env); ++} ++ ++void helper_tlbclr(CPULOONGARCHState *env) ++{ ++ env->tlb->helper_tlbclr(env); ++} ++ ++void helper_tlbflush(CPULOONGARCHState *env) ++{ ++ env->tlb->helper_tlbflush(env); ++} ++ ++void helper_invtlb(CPULOONGARCHState *env, target_ulong addr, target_ulong info, ++ target_ulong op) ++{ ++ env->tlb->helper_invtlb(env, addr, info, op); ++} ++ ++static void ls3a5k_mmu_init(CPULOONGARCHState *env, const loongarch_def_t *def) ++{ ++ /* number of VTLB */ ++ env->tlb->nb_tlb = 64; ++ env->tlb->mmu.ls3a5k.vtlb_size = 64; ++ ++ /* number of FTLB */ ++ env->tlb->nb_tlb += 2048; ++ env->tlb->mmu.ls3a5k.ftlb_size = 2048; ++ env->tlb->mmu.ls3a5k.ftlb_mask = (1 << 15) - 1; /* 16 KB */ ++ /* ++ * page_size | ftlb_mask | party field ++ * ---------------------------------------------------------------- ++ * 4 KB = 12 | ( 1 << 13 ) - 1 = [12:0] | [12] ++ * 16 KB = 14 | ( 1 << 15 ) - 1 = [14:0] | [14] ++ * 64 KB = 16 | ( 1 << 17 ) - 1 = [16:0] | [16] ++ * 256 KB = 18 | ( 1 << 19 ) - 1 = [18:0] | [18] ++ * 1 MB = 20 | ( 1 << 21 ) - 1 = [20:0] | [20] ++ * 4 MB = 22 | ( 1 << 23 ) - 1 = [22:0] | [22] ++ * 16 MB = 24 | ( 1 << 25 ) - 1 = [24:0] | [24] ++ * 64 MB = 26 | ( 1 << 27 ) - 1 = [26:0] | [26] ++ * 256 MB = 28 | ( 1 << 29 ) - 1 = [28:0] | [28] ++ * 1 GB = 30 | ( 1 << 31 ) - 1 = [30:0] | [30] ++ * ---------------------------------------------------------------- ++ * take party field index as @n. eg. For 16 KB, n = 14 ++ * ---------------------------------------------------------------- ++ * tlb->VPN = TLBEHI & 0xffffffffe000[47:13] & ~mask = [47:n+1] ++ * tlb->PPN = TLBLO0 & 0xffffffffe000[47:13] & ~mask = [47:n+1] ++ * tlb->PPN = TLBLO1 & 0xffffffffe000[47:13] & ~mask = [47:n+1] ++ * ---------------------------------------------------------------- ++ * On mapping : ++ * > vpn = address & 0xffffffffe000[47:13] & ~mask = [47:n+1] ++ * > tag = tlb->VPN & ~mask = [47:n+1] ++ * ---------------------------------------------------------------- ++ * physical address = [47:n+1] | [n:0] ++ * physical address = tlb->PPN0 | (address & mask) ++ * physical address = tlb->PPN1 | (address & mask) ++ */ ++ ++ int i; ++ for (i = 0; i < env->tlb->nb_tlb; i++) { ++ env->tlb->mmu.ls3a5k.tlb[i].EHINV = 1; ++ } ++ ++ /* TLB's helper functions */ ++ env->tlb->map_address = &ls3a5k_map_address; ++ env->tlb->helper_tlbwr = ls3a5k_helper_tlbwr; ++ env->tlb->helper_tlbfill = ls3a5k_helper_tlbfill; ++ env->tlb->helper_tlbsrch = ls3a5k_helper_tlbsrch; ++ env->tlb->helper_tlbrd = ls3a5k_helper_tlbrd; ++ env->tlb->helper_tlbclr = ls3a5k_helper_tlbclr; ++ env->tlb->helper_tlbflush = ls3a5k_helper_tlbflush; ++ env->tlb->helper_invtlb = ls3a5k_helper_invtlb; ++} ++ ++void mmu_init(CPULOONGARCHState *env, const loongarch_def_t *def) ++{ ++ env->tlb = g_malloc0(sizeof(CPULOONGARCHTLBContext)); ++ ++ switch (def->mmu_type) { ++ case MMU_TYPE_LS3A5K: ++ ls3a5k_mmu_init(env, def); ++ break; ++ default: ++ cpu_abort(CPU(loongarch_env_get_cpu(env)), "MMU type not supported\n"); ++ } ++} ++#endif /* !CONFIG_USER_ONLY */ +diff --git a/target/loongarch64/trace-events b/target/loongarch64/trace-events +new file mode 100644 +index 0000000000..e0bca4f82e +--- /dev/null ++++ b/target/loongarch64/trace-events +@@ -0,0 +1,3 @@ ++# See docs/devel/tracing.txt for syntax documentation. ++ ++# target/loongarch/translate.c +diff --git a/target/loongarch64/trans.inc.c b/target/loongarch64/trans.inc.c +new file mode 100644 +index 0000000000..e50670be47 +--- /dev/null ++++ b/target/loongarch64/trans.inc.c +@@ -0,0 +1,3472 @@ ++static bool trans_syscall(DisasContext *ctx, arg_syscall *a) ++{ ++ generate_exception_end(ctx, EXCP_SYSCALL); ++ return true; ++} ++ ++static bool trans_break(DisasContext *ctx, arg_break *a) ++{ ++ generate_exception_end(ctx, EXCP_BREAK); ++ return true; ++} ++ ++static bool trans_dbcl(DisasContext *ctx, arg_dbcl *a) ++{ ++ /* ++ * dbcl instruction is not support in tcg ++ */ ++ generate_exception_end(ctx, EXCP_RI); ++ return true; ++} ++ ++static bool trans_addi_w(DisasContext *ctx, arg_addi_w *a) ++{ ++ gen_arith_imm(ctx, OPC_LARCH_ADDI_W, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_addi_d(DisasContext *ctx, arg_addi_d *a) ++{ ++ gen_arith_imm(ctx, OPC_LARCH_ADDI_D, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_slli_d(DisasContext *ctx, arg_slli_d *a) ++{ ++ if (a->rd == 0) { ++ /* Nop */ ++ return true; ++ } ++ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ tcg_gen_shli_tl(cpu_gpr[a->rd], t0, a->ui6); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_andi(DisasContext *ctx, arg_andi *a) ++{ ++ gen_logic_imm(ctx, OPC_LARCH_ANDI, a->rd, a->rj, a->ui12); ++ return true; ++} ++ ++static bool trans_srli_d(DisasContext *ctx, arg_srli_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ tcg_gen_shri_tl(cpu_gpr[a->rd], t0, a->ui6); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_slli_w(DisasContext *ctx, arg_slli_w *a) ++{ ++ if (a->rd == 0) { ++ /* Nop */ ++ return true; ++ } ++ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ tcg_gen_shli_tl(t0, t0, a->ui5); ++ tcg_gen_ext32s_tl(cpu_gpr[a->rd], t0); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_addu16i_d(DisasContext *ctx, arg_addu16i_d *a) ++{ ++ if (a->rj != 0) { ++ tcg_gen_addi_tl(cpu_gpr[a->rd], cpu_gpr[a->rj], a->si16 << 16); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[a->rd], a->si16 << 16); ++ } ++ return true; ++} ++ ++static bool trans_lu12i_w(DisasContext *ctx, arg_lu12i_w *a) ++{ ++ tcg_gen_movi_tl(cpu_gpr[a->rd], a->si20 << 12); ++ return true; ++} ++ ++static bool trans_lu32i_d(DisasContext *ctx, arg_lu32i_d *a) ++{ ++ TCGv_i64 t0, t1; ++ t0 = tcg_temp_new_i64(); ++ t1 = tcg_temp_new_i64(); ++ ++ tcg_gen_movi_tl(t0, a->si20); ++ tcg_gen_concat_tl_i64(t1, cpu_gpr[a->rd], t0); ++ gen_store_gpr(t1, a->rd); ++ ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_pcaddi(DisasContext *ctx, arg_pcaddi *a) ++{ ++ target_ulong pc = ctx->base.pc_next; ++ target_ulong addr = pc + (a->si20 << 2); ++ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); ++ return true; ++} ++ ++static bool trans_pcalau12i(DisasContext *ctx, arg_pcalau12i *a) ++{ ++ target_ulong pc = ctx->base.pc_next; ++ target_ulong addr = (pc + (a->si20 << 12)) & ~0xfff; ++ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); ++ return true; ++} ++ ++static bool trans_pcaddu12i(DisasContext *ctx, arg_pcaddu12i *a) ++{ ++ target_ulong pc = ctx->base.pc_next; ++ target_ulong addr = pc + (a->si20 << 12); ++ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); ++ return true; ++} ++ ++static bool trans_pcaddu18i(DisasContext *ctx, arg_pcaddu18i *a) ++{ ++ target_ulong pc = ctx->base.pc_next; ++ target_ulong addr = pc + ((target_ulong)(a->si20) << 18); ++ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); ++ return true; ++} ++ ++static bool trans_slti(DisasContext *ctx, arg_slti *a) ++{ ++ gen_slt_imm(ctx, OPC_LARCH_SLTI, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_sltui(DisasContext *ctx, arg_sltui *a) ++{ ++ gen_slt_imm(ctx, OPC_LARCH_SLTIU, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_lu52i_d(DisasContext *ctx, arg_lu52i_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ ++ gen_load_gpr(t1, a->rj); ++ ++ tcg_gen_movi_tl(t0, a->si12); ++ tcg_gen_shli_tl(t0, t0, 52); ++ tcg_gen_andi_tl(t1, t1, 0xfffffffffffffU); ++ tcg_gen_or_tl(cpu_gpr[a->rd], t0, t1); ++ ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_ori(DisasContext *ctx, arg_ori *a) ++{ ++ gen_logic_imm(ctx, OPC_LARCH_ORI, a->rd, a->rj, a->ui12); ++ return true; ++} ++ ++static bool trans_xori(DisasContext *ctx, arg_xori *a) ++{ ++ gen_logic_imm(ctx, OPC_LARCH_XORI, a->rd, a->rj, a->ui12); ++ return true; ++} ++ ++static bool trans_bstrins_d(DisasContext *ctx, arg_bstrins_d *a) ++{ ++ int lsb = a->lsbd; ++ int msb = a->msbd; ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ ++ if (lsb > msb) { ++ return false; ++ } ++ ++ gen_load_gpr(t1, a->rj); ++ gen_load_gpr(t0, a->rd); ++ tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); ++ gen_store_gpr(t0, a->rd); ++ ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_bstrpick_d(DisasContext *ctx, arg_bstrpick_d *a) ++{ ++ int lsb = a->lsbd; ++ int msb = a->msbd; ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ ++ if (lsb > msb) { ++ return false; ++ } ++ ++ gen_load_gpr(t1, a->rj); ++ gen_load_gpr(t0, a->rd); ++ tcg_gen_extract_tl(t0, t1, lsb, msb - lsb + 1); ++ gen_store_gpr(t0, a->rd); ++ ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_bstrins_w(DisasContext *ctx, arg_bstrins_w *a) ++{ ++ gen_bitops(ctx, OPC_LARCH_TRINS_W, a->rd, a->rj, a->lsbw, a->msbw); ++ return true; ++} ++ ++static bool trans_bstrpick_w(DisasContext *ctx, arg_bstrpick_w *a) ++{ ++ if (a->lsbw > a->msbw) { ++ return false; ++ } ++ gen_bitops(ctx, OPC_LARCH_TRPICK_W, ++ a->rd, a->rj, a->lsbw, a->msbw - a->lsbw); ++ return true; ++} ++ ++static bool trans_ldptr_w(DisasContext *ctx, arg_ldptr_w *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LDPTR_W, a->rd, a->rj, a->si14 << 2); ++ return true; ++} ++ ++static bool trans_stptr_w(DisasContext *ctx, arg_stptr_w *a) ++{ ++ gen_st(ctx, OPC_LARCH_STPTR_W, a->rd, a->rj, a->si14 << 2); ++ return true; ++} ++ ++static bool trans_ldptr_d(DisasContext *ctx, arg_ldptr_d *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LDPTR_D, a->rd, a->rj, a->si14 << 2); ++ return true; ++} ++ ++static bool trans_stptr_d(DisasContext *ctx, arg_stptr_d *a) ++{ ++ gen_st(ctx, OPC_LARCH_STPTR_D, a->rd, a->rj, a->si14 << 2); ++ return true; ++} ++ ++static bool trans_ld_b(DisasContext *ctx, arg_ld_b *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_B, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ld_h(DisasContext *ctx, arg_ld_h *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_H, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ld_w(DisasContext *ctx, arg_ld_w *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_W, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ld_d(DisasContext *ctx, arg_ld_d *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_D, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_st_b(DisasContext *ctx, arg_st_b *a) ++{ ++ gen_st(ctx, OPC_LARCH_ST_B, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_st_h(DisasContext *ctx, arg_st_h *a) ++{ ++ gen_st(ctx, OPC_LARCH_ST_H, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_st_w(DisasContext *ctx, arg_st_w *a) ++{ ++ gen_st(ctx, OPC_LARCH_ST_W, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_st_d(DisasContext *ctx, arg_st_d *a) ++{ ++ gen_st(ctx, OPC_LARCH_ST_D, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ld_bu(DisasContext *ctx, arg_ld_bu *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_BU, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ld_hu(DisasContext *ctx, arg_ld_hu *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_HU, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ld_wu(DisasContext *ctx, arg_ld_wu *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_WU, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_preld(DisasContext *ctx, arg_preld *a) ++{ ++ /* Treat as NOP. */ ++ return true; ++} ++ ++static bool trans_ll_w(DisasContext *ctx, arg_ll_w *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LL_W, a->rd, a->rj, a->si14 << 2); ++ return true; ++} ++ ++static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a) ++{ ++ gen_st_cond(ctx, a->rd, a->rj, a->si14 << 2, MO_TESL, false); ++ return true; ++} ++ ++static bool trans_ll_d(DisasContext *ctx, arg_ll_d *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LL_D, a->rd, a->rj, a->si14 << 2); ++ return true; ++} ++ ++static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a) ++{ ++ gen_st_cond(ctx, a->rd, a->rj, a->si14 << 2, MO_TEQ, false); ++ return true; ++} ++ ++static bool trans_fld_s(DisasContext *ctx, arg_fld_s *a) ++{ ++ gen_fp_ldst(ctx, OPC_LARCH_FLD_S, a->fd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_fst_s(DisasContext *ctx, arg_fst_s *a) ++{ ++ gen_fp_ldst(ctx, OPC_LARCH_FST_S, a->fd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_fld_d(DisasContext *ctx, arg_fld_d *a) ++{ ++ gen_fp_ldst(ctx, OPC_LARCH_FLD_D, a->fd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_fst_d(DisasContext *ctx, arg_fst_d *a) ++{ ++ gen_fp_ldst(ctx, OPC_LARCH_FST_D, a->fd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ldx_b(DisasContext *ctx, arg_ldx_b *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_SB); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_ldx_h(DisasContext *ctx, arg_ldx_h *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TESW | ctx->default_tcg_memop_mask); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_ldx_w(DisasContext *ctx, arg_ldx_w *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TESL | ctx->default_tcg_memop_mask); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_ldx_d(DisasContext *ctx, arg_ldx_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TEQ | ctx->default_tcg_memop_mask); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_stx_b(DisasContext *ctx, arg_stx_b *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ gen_load_gpr(t1, a->rd); ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_stx_h(DisasContext *ctx, arg_stx_h *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ gen_load_gpr(t1, a->rd); ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | ++ ctx->default_tcg_memop_mask); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_stx_w(DisasContext *ctx, arg_stx_w *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ gen_load_gpr(t1, a->rd); ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | ++ ctx->default_tcg_memop_mask); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_stx_d(DisasContext *ctx, arg_stx_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ gen_load_gpr(t1, a->rd); ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ | ++ ctx->default_tcg_memop_mask); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_ldx_bu(DisasContext *ctx, arg_ldx_bu *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_ldx_hu(DisasContext *ctx, arg_ldx_hu *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TEUW | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_ldx_wu(DisasContext *ctx, arg_ldx_wu *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TEUL | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_fldx_s(DisasContext *ctx, arg_fldx_s *a) ++{ ++ gen_flt3_ldst(ctx, OPC_LARCH_FLDX_S, a->fd, 0, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fldx_d(DisasContext *ctx, arg_fldx_d *a) ++{ ++ gen_flt3_ldst(ctx, OPC_LARCH_FLDX_D, a->fd, 0, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fstx_s(DisasContext *ctx, arg_fstx_s *a) ++{ ++ gen_flt3_ldst(ctx, OPC_LARCH_FSTX_S, 0, a->fd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fstx_d(DisasContext *ctx, arg_fstx_d *a) ++{ ++ gen_flt3_ldst(ctx, OPC_LARCH_FSTX_D, 0, a->fd, a->rj, a->rk); ++ return true; ++} ++ ++#define TRANS_AM_W(name, op) \ ++static bool trans_ ## name(DisasContext *ctx, arg_ ## name * a) \ ++{ \ ++ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ ++ printf("%s: warning, register equal\n", __func__); \ ++ return false; \ ++ } \ ++ int mem_idx = ctx->mem_idx; \ ++ TCGv addr = tcg_temp_new(); \ ++ TCGv val = tcg_temp_new(); \ ++ TCGv ret = tcg_temp_new(); \ ++\ ++ gen_load_gpr(addr, a->rj); \ ++ gen_load_gpr(val, a->rk); \ ++ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, MO_TESL | \ ++ ctx->default_tcg_memop_mask); \ ++ gen_store_gpr(ret, a->rd); \ ++\ ++ tcg_temp_free(addr); \ ++ tcg_temp_free(val); \ ++ tcg_temp_free(ret); \ ++ return true; \ ++} ++#define TRANS_AM_D(name, op) \ ++static bool trans_ ## name(DisasContext *ctx, arg_ ## name * a) \ ++{ \ ++ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ ++ printf("%s: warning, register equal\n", __func__); \ ++ return false; \ ++ } \ ++ int mem_idx = ctx->mem_idx; \ ++ TCGv addr = tcg_temp_new(); \ ++ TCGv val = tcg_temp_new(); \ ++ TCGv ret = tcg_temp_new(); \ ++\ ++ gen_load_gpr(addr, a->rj); \ ++ gen_load_gpr(val, a->rk); \ ++ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, MO_TEQ | \ ++ ctx->default_tcg_memop_mask); \ ++ gen_store_gpr(ret, a->rd); \ ++\ ++ tcg_temp_free(addr); \ ++ tcg_temp_free(val); \ ++ tcg_temp_free(ret); \ ++ return true; \ ++} ++#define TRANS_AM(name, op) \ ++ TRANS_AM_W(name##_w, op) \ ++ TRANS_AM_D(name##_d, op) ++TRANS_AM(amswap, xchg) /* trans_amswap_w, trans_amswap_d */ ++TRANS_AM(amadd, fetch_add) /* trans_amadd_w, trans_amadd_d */ ++TRANS_AM(amand, fetch_and) /* trans_amand_w, trans_amand_d */ ++TRANS_AM(amor, fetch_or) /* trans_amor_w, trans_amor_d */ ++TRANS_AM(amxor, fetch_xor) /* trans_amxor_w, trans_amxor_d */ ++TRANS_AM(ammax, fetch_smax) /* trans_ammax_w, trans_ammax_d */ ++TRANS_AM(ammin, fetch_smin) /* trans_ammin_w, trans_ammin_d */ ++TRANS_AM_W(ammax_wu, fetch_umax) /* trans_ammax_wu */ ++TRANS_AM_D(ammax_du, fetch_umax) /* trans_ammax_du */ ++TRANS_AM_W(ammin_wu, fetch_umin) /* trans_ammin_wu */ ++TRANS_AM_D(ammin_du, fetch_umin) /* trans_ammin_du */ ++#undef TRANS_AM ++#undef TRANS_AM_W ++#undef TRANS_AM_D ++ ++#define TRANS_AM_DB_W(name, op) \ ++static bool trans_ ## name(DisasContext *ctx, arg_ ## name * a) \ ++{ \ ++ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ ++ printf("%s: warning, register equal\n", __func__); \ ++ return false; \ ++ } \ ++ int mem_idx = ctx->mem_idx; \ ++ TCGv addr = tcg_temp_new(); \ ++ TCGv val = tcg_temp_new(); \ ++ TCGv ret = tcg_temp_new(); \ ++\ ++ gen_sync(0x10); /* TCG_MO_ALL */ \ ++ gen_load_gpr(addr, a->rj); \ ++ gen_load_gpr(val, a->rk); \ ++ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, MO_TESL | \ ++ ctx->default_tcg_memop_mask); \ ++ gen_store_gpr(ret, a->rd); \ ++\ ++ tcg_temp_free(addr); \ ++ tcg_temp_free(val); \ ++ tcg_temp_free(ret); \ ++ return true; \ ++} ++#define TRANS_AM_DB_D(name, op) \ ++static bool trans_ ## name(DisasContext *ctx, arg_ ## name * a) \ ++{ \ ++ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ ++ printf("%s: warning, register equal\n", __func__); \ ++ return false; \ ++ } \ ++ int mem_idx = ctx->mem_idx; \ ++ TCGv addr = tcg_temp_new(); \ ++ TCGv val = tcg_temp_new(); \ ++ TCGv ret = tcg_temp_new(); \ ++\ ++ gen_sync(0x10); /* TCG_MO_ALL */ \ ++ gen_load_gpr(addr, a->rj); \ ++ gen_load_gpr(val, a->rk); \ ++ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, MO_TEQ | \ ++ ctx->default_tcg_memop_mask); \ ++ gen_store_gpr(ret, a->rd); \ ++\ ++ tcg_temp_free(addr); \ ++ tcg_temp_free(val); \ ++ tcg_temp_free(ret); \ ++ return true; \ ++} ++#define TRANS_AM_DB(name, op) \ ++ TRANS_AM_DB_W(name##_db_w, op) \ ++ TRANS_AM_DB_D(name##_db_d, op) ++TRANS_AM_DB(amswap, xchg) /* trans_amswap_db_w, trans_amswap_db_d */ ++TRANS_AM_DB(amadd, fetch_add) /* trans_amadd_db_w, trans_amadd_db_d */ ++TRANS_AM_DB(amand, fetch_and) /* trans_amand_db_w, trans_amand_db_d */ ++TRANS_AM_DB(amor, fetch_or) /* trans_amor_db_w, trans_amor_db_d */ ++TRANS_AM_DB(amxor, fetch_xor) /* trans_amxor_db_w, trans_amxor_db_d */ ++TRANS_AM_DB(ammax, fetch_smax) /* trans_ammax_db_w, trans_ammax_db_d */ ++TRANS_AM_DB(ammin, fetch_smin) /* trans_ammin_db_w, trans_ammin_db_d */ ++TRANS_AM_DB_W(ammax_db_wu, fetch_umax) /* trans_ammax_db_wu */ ++TRANS_AM_DB_D(ammax_db_du, fetch_umax) /* trans_ammax_db_du */ ++TRANS_AM_DB_W(ammin_db_wu, fetch_umin) /* trans_ammin_db_wu */ ++TRANS_AM_DB_D(ammin_db_du, fetch_umin) /* trans_ammin_db_du */ ++#undef TRANS_AM_DB ++#undef TRANS_AM_DB_W ++#undef TRANS_AM_DB_D ++ ++static bool trans_dbar(DisasContext *ctx, arg_dbar * a) ++{ ++ gen_sync(a->whint); ++ return true; ++} ++ ++static bool trans_ibar(DisasContext *ctx, arg_ibar *a) ++{ ++ /* ++ * FENCE_I is a no-op in QEMU, ++ * however we need to end the translation block ++ */ ++ ctx->base.is_jmp = DISAS_STOP; ++ return true; ++} ++ ++#define ASRTGT \ ++do { \ ++ TCGv t1 = tcg_temp_new(); \ ++ TCGv t2 = tcg_temp_new(); \ ++ gen_load_gpr(t1, a->rj); \ ++ gen_load_gpr(t2, a->rk); \ ++ gen_helper_asrtgt_d(cpu_env, t1, t2); \ ++ tcg_temp_free(t1); \ ++ tcg_temp_free(t2); \ ++} while (0) ++ ++#define ASRTLE \ ++do {\ ++ TCGv t1 = tcg_temp_new(); \ ++ TCGv t2 = tcg_temp_new(); \ ++ gen_load_gpr(t1, a->rj); \ ++ gen_load_gpr(t2, a->rk); \ ++ gen_helper_asrtle_d(cpu_env, t1, t2); \ ++ tcg_temp_free(t1); \ ++ tcg_temp_free(t2); \ ++} while (0) ++ ++static bool trans_fldgt_s(DisasContext *ctx, arg_fldgt_s *a) ++{ ++ ASRTGT; ++ gen_flt3_ldst(ctx, OPC_LARCH_FLDGT_S, a->fd, 0, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fldgt_d(DisasContext *ctx, arg_fldgt_d *a) ++{ ++ ASRTGT; ++ gen_flt3_ldst(ctx, OPC_LARCH_FLDGT_D, a->fd, 0, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fldle_s(DisasContext *ctx, arg_fldle_s *a) ++{ ++ ASRTLE; ++ gen_flt3_ldst(ctx, OPC_LARCH_FLDLE_S, a->fd, 0, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fldle_d(DisasContext *ctx, arg_fldle_d *a) ++{ ++ ASRTLE; ++ gen_flt3_ldst(ctx, OPC_LARCH_FLDLE_D, a->fd, 0, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fstgt_s(DisasContext *ctx, arg_fstgt_s *a) ++{ ++ ASRTGT; ++ gen_flt3_ldst(ctx, OPC_LARCH_FSTGT_S, 0, a->fd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fstgt_d(DisasContext *ctx, arg_fstgt_d *a) ++{ ++ ASRTGT; ++ gen_flt3_ldst(ctx, OPC_LARCH_FSTGT_D, 0, a->fd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fstle_s(DisasContext *ctx, arg_fstle_s *a) ++{ ++ ASRTLE; ++ gen_flt3_ldst(ctx, OPC_LARCH_FSTLE_S, 0, a->fd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fstle_d(DisasContext *ctx, arg_fstle_d *a) ++{ ++ ASRTLE; ++ gen_flt3_ldst(ctx, OPC_LARCH_FSTLE_D, 0, a->fd, a->rj, a->rk); ++ return true; ++} ++ ++#define DECL_ARG(name) \ ++ arg_ ## name arg = { \ ++ .rd = a->rd, \ ++ .rj = a->rj, \ ++ .rk = a->rk, \ ++ }; ++ ++static bool trans_ldgt_b(DisasContext *ctx, arg_ldgt_b *a) ++{ ++ ASRTGT; ++ DECL_ARG(ldx_b) ++ trans_ldx_b(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldgt_h(DisasContext *ctx, arg_ldgt_h *a) ++{ ++ ASRTGT; ++ DECL_ARG(ldx_h) ++ trans_ldx_h(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldgt_w(DisasContext *ctx, arg_ldgt_w *a) ++{ ++ ASRTGT; ++ DECL_ARG(ldx_w) ++ trans_ldx_w(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldgt_d(DisasContext *ctx, arg_ldgt_d *a) ++{ ++ ASRTGT; ++ DECL_ARG(ldx_d) ++ trans_ldx_d(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldle_b(DisasContext *ctx, arg_ldle_b *a) ++{ ++ ASRTLE; ++ DECL_ARG(ldx_b) ++ trans_ldx_b(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldle_h(DisasContext *ctx, arg_ldle_h *a) ++{ ++ ASRTLE; ++ DECL_ARG(ldx_h) ++ trans_ldx_h(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldle_w(DisasContext *ctx, arg_ldle_w *a) ++{ ++ ASRTLE; ++ DECL_ARG(ldx_w) ++ trans_ldx_w(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldle_d(DisasContext *ctx, arg_ldle_d *a) ++{ ++ ASRTLE; ++ DECL_ARG(ldx_d) ++ trans_ldx_d(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stgt_b(DisasContext *ctx, arg_stgt_b *a) ++{ ++ ASRTGT; ++ DECL_ARG(stx_b) ++ trans_stx_b(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stgt_h(DisasContext *ctx, arg_stgt_h *a) ++{ ++ ASRTGT; ++ DECL_ARG(stx_h) ++ trans_stx_h(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stgt_w(DisasContext *ctx, arg_stgt_w *a) ++{ ++ ASRTGT; ++ DECL_ARG(stx_w) ++ trans_stx_w(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stgt_d(DisasContext *ctx, arg_stgt_d *a) ++{ ++ ASRTGT; ++ DECL_ARG(stx_d) ++ trans_stx_d(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stle_b(DisasContext *ctx, arg_stle_b *a) ++{ ++ ASRTLE; ++ DECL_ARG(stx_b) ++ trans_stx_b(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stle_h(DisasContext *ctx, arg_stle_h *a) ++{ ++ ASRTLE; ++ DECL_ARG(stx_h) ++ trans_stx_h(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stle_w(DisasContext *ctx, arg_stle_w *a) ++{ ++ ASRTLE; ++ DECL_ARG(stx_w) ++ trans_stx_w(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stle_d(DisasContext *ctx, arg_stle_d *a) ++{ ++ ASRTLE; ++ DECL_ARG(stx_d) ++ trans_stx_d(ctx, &arg); ++ return true; ++} ++ ++#undef ASRTGT ++#undef ASRTLE ++#undef DECL_ARG ++ ++static bool trans_beqz(DisasContext *ctx, arg_beqz *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BEQZ, 4, a->rj, 0, a->offs21 << 2); ++ return true; ++} ++ ++static bool trans_bnez(DisasContext *ctx, arg_bnez *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BNEZ, 4, a->rj, 0, a->offs21 << 2); ++ return true; ++} ++ ++static bool trans_bceqz(DisasContext *ctx, arg_bceqz *a) ++{ ++ TCGv_i32 cj = tcg_const_i32(a->cj); ++ TCGv v0 = tcg_temp_new(); ++ TCGv v1 = tcg_const_i64(0); ++ ++ gen_helper_movcf2reg(v0, cpu_env, cj); ++ tcg_gen_setcond_tl(TCG_COND_EQ, bcond, v0, v1); ++ ctx->hflags |= LARCH_HFLAG_BC; ++ ctx->btarget = ctx->base.pc_next + (a->offs21 << 2); ++ ++ tcg_temp_free_i32(cj); ++ tcg_temp_free(v0); ++ tcg_temp_free(v1); ++ return true; ++} ++ ++static bool trans_bcnez(DisasContext *ctx, arg_bcnez *a) ++{ ++ TCGv_i32 cj = tcg_const_i32(a->cj); ++ TCGv v0 = tcg_temp_new(); ++ TCGv v1 = tcg_const_i64(0); ++ ++ gen_helper_movcf2reg(v0, cpu_env, cj); ++ tcg_gen_setcond_tl(TCG_COND_NE, bcond, v0, v1); ++ ctx->hflags |= LARCH_HFLAG_BC; ++ ctx->btarget = ctx->base.pc_next + (a->offs21 << 2); ++ ++ tcg_temp_free_i32(cj); ++ tcg_temp_free(v0); ++ tcg_temp_free(v1); ++ return true; ++} ++ ++static bool trans_b(DisasContext *ctx, arg_b *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_B, 4, 0, 0, a->offs << 2); ++ return true; ++} ++ ++static bool trans_bl(DisasContext *ctx, arg_bl *a) ++{ ++ ctx->btarget = ctx->base.pc_next + (a->offs << 2); ++ tcg_gen_movi_tl(cpu_gpr[1], ctx->base.pc_next + 4); ++ ctx->hflags |= LARCH_HFLAG_B; ++ gen_branch(ctx, 4); ++ return true; ++} ++ ++static bool trans_blt(DisasContext *ctx, arg_blt *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BLT, 4, a->rj, a->rd, a->offs16 << 2); ++ return true; ++} ++ ++static bool trans_bge(DisasContext *ctx, arg_bge *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BGE, 4, a->rj, a->rd, a->offs16 << 2); ++ return true; ++} ++ ++static bool trans_bltu(DisasContext *ctx, arg_bltu *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BLTU, 4, a->rj, a->rd, a->offs16 << 2); ++ return true; ++} ++ ++static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BGEU, 4, a->rj, a->rd, a->offs16 << 2); ++ return true; ++} ++ ++static bool trans_beq(DisasContext *ctx, arg_beq *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BEQ, 4, a->rj, a->rd, a->offs16 << 2); ++ return true; ++} ++ ++static bool trans_bne(DisasContext *ctx, arg_bne *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BNE, 4, a->rj, a->rd, a->offs16 << 2); ++ return true; ++} ++ ++static bool trans_jirl(DisasContext *ctx, arg_jirl *a) ++{ ++ gen_base_offset_addr(ctx, btarget, a->rj, a->offs16 << 2); ++ if (a->rd != 0) { ++ tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->base.pc_next + 4); ++ } ++ ctx->hflags |= LARCH_HFLAG_BR; ++ gen_branch(ctx, 4); ++ ++ return true; ++} ++ ++#define TRANS_F4FR(name, fmt, op, bits) \ ++static bool trans_ ## name ## _ ## fmt(DisasContext *ctx, \ ++ arg_##name##_##fmt * a) \ ++{ \ ++ check_cp1_enabled(ctx); \ ++ TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ ++ TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ ++ TCGv_i ## bits fp2 = tcg_temp_new_i ## bits(); \ ++ TCGv_i ## bits fp3 = tcg_temp_new_i ## bits(); \ ++ check_cp1_enabled(ctx); \ ++ gen_load_fpr ## bits(ctx, fp0, a->fj); \ ++ gen_load_fpr ## bits(ctx, fp1, a->fk); \ ++ gen_load_fpr ## bits(ctx, fp2, a->fa); \ ++ gen_helper_float_ ## op ## _ ## fmt(fp3, \ ++ cpu_env, fp0, fp1, fp2); \ ++ gen_store_fpr ## bits(ctx, fp3, a->fd); \ ++ tcg_temp_free_i ## bits(fp3); \ ++ tcg_temp_free_i ## bits(fp2); \ ++ tcg_temp_free_i ## bits(fp1); \ ++ tcg_temp_free_i ## bits(fp0); \ ++ return true; \ ++} ++ ++TRANS_F4FR(fmadd , s, maddf , 32) /* trans_fmadd_s */ ++TRANS_F4FR(fmadd , d, maddf , 64) /* trans_fmadd_d */ ++TRANS_F4FR(fmsub , s, msubf , 32) /* trans_fmsub_s */ ++TRANS_F4FR(fmsub , d, msubf , 64) /* trans_fmsub_d */ ++TRANS_F4FR(fnmadd, s, nmaddf, 32) /* trans_fnmadd_s */ ++TRANS_F4FR(fnmadd, d, nmaddf, 64) /* trans_fnmadd_d */ ++TRANS_F4FR(fnmsub, s, nmsubf, 32) /* trans_fnmsub_s */ ++TRANS_F4FR(fnmsub, d, nmsubf, 64) /* trans_fnmsub_d */ ++#undef TRANS_F4FR ++ ++static bool trans_fadd_s(DisasContext *ctx, arg_fadd_s * a) ++{ ++ gen_farith(ctx, OPC_LARCH_FADD_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fadd_d(DisasContext *ctx, arg_fadd_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FADD_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fsub_s(DisasContext *ctx, arg_fsub_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FSUB_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fsub_d(DisasContext *ctx, arg_fsub_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FSUB_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmul_s(DisasContext *ctx, arg_fmul_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMUL_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmul_d(DisasContext *ctx, arg_fmul_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMUL_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fdiv_s(DisasContext *ctx, arg_fdiv_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FDIV_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fdiv_d(DisasContext *ctx, arg_fdiv_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FDIV_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmax_s(DisasContext *ctx, arg_fmax_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMAX_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmax_d(DisasContext *ctx, arg_fmax_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMAX_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmin_s(DisasContext *ctx, arg_fmin_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMIN_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmin_d(DisasContext *ctx, arg_fmin_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMIN_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmaxa_s(DisasContext *ctx, arg_fmaxa_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMAXA_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmaxa_d(DisasContext *ctx, arg_fmaxa_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMAXA_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmina_s(DisasContext *ctx, arg_fmina_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMINA_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmina_d(DisasContext *ctx, arg_fmina_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMINA_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fscaleb_s(DisasContext *ctx, arg_fscaleb_s *a) ++{ ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr32(ctx, fp0, a->fj); ++ gen_load_fpr32(ctx, fp1, a->fk); ++ gen_helper_float_exp2_s(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i32(fp1); ++ gen_store_fpr32(ctx, fp0, a->fd); ++ tcg_temp_free_i32(fp0); ++ return true; ++} ++ ++static bool trans_fscaleb_d(DisasContext *ctx, arg_fscaleb_d *a) ++{ ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr64(ctx, fp0, a->fj); ++ gen_load_fpr64(ctx, fp1, a->fk); ++ gen_helper_float_exp2_d(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i64(fp1); ++ gen_store_fpr64(ctx, fp0, a->fd); ++ tcg_temp_free_i64(fp0); ++ return true; ++} ++ ++static bool trans_fcopysign_s(DisasContext *ctx, arg_fcopysign_s *a) ++{ ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ TCGv_i32 fp2 = tcg_temp_new_i32(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr32(ctx, fp0, a->fj); ++ gen_load_fpr32(ctx, fp1, a->fk); ++ tcg_gen_deposit_i32(fp2, fp1, fp0, 0, 31); ++ gen_store_fpr32(ctx, fp2, a->fd); ++ ++ tcg_temp_free_i32(fp2); ++ tcg_temp_free_i32(fp1); ++ tcg_temp_free_i32(fp0); ++ return true; ++} ++ ++static bool trans_fcopysign_d(DisasContext *ctx, arg_fcopysign_d *a) ++{ ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ TCGv_i64 fp2 = tcg_temp_new_i64(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr64(ctx, fp0, a->fj); ++ gen_load_fpr64(ctx, fp1, a->fk); ++ tcg_gen_deposit_i64(fp2, fp1, fp0, 0, 63); ++ gen_store_fpr64(ctx, fp2, a->fd); ++ ++ tcg_temp_free_i64(fp2); ++ tcg_temp_free_i64(fp1); ++ tcg_temp_free_i64(fp0); ++ return true; ++} ++ ++static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FABS_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FABS_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FNEG_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FNEG_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_flogb_s(DisasContext *ctx, arg_flogb_s *a) ++{ ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr32(ctx, fp0, a->fj); ++ gen_helper_float_logb_s(fp1, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp1, a->fd); ++ ++ tcg_temp_free_i32(fp0); ++ tcg_temp_free_i32(fp1); ++ return true; ++} ++ ++static bool trans_flogb_d(DisasContext *ctx, arg_flogb_d *a) ++{ ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr64(ctx, fp0, a->fj); ++ gen_helper_float_logb_d(fp1, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp1, a->fd); ++ ++ tcg_temp_free_i64(fp0); ++ tcg_temp_free_i64(fp1); ++ return true; ++} ++ ++static bool trans_fclass_s(DisasContext *ctx, arg_fclass_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FCLASS_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FCLASS_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fsqrt_s(DisasContext *ctx, arg_fsqrt_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FSQRT_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fsqrt_d(DisasContext *ctx, arg_fsqrt_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FSQRT_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_frecip_s(DisasContext *ctx, arg_frecip_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FRECIP_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_frecip_d(DisasContext *ctx, arg_frecip_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FRECIP_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_frsqrt_s(DisasContext *ctx, arg_frsqrt_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FRSQRT_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_frsqrt_d(DisasContext *ctx, arg_frsqrt_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FRSQRT_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmov_s(DisasContext *ctx, arg_fmov_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMOV_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmov_d(DisasContext *ctx, arg_fmov_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMOV_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_movgr2fr_w(DisasContext *ctx, arg_movgr2fr_w *a) ++{ ++ gen_cp1(ctx, OPC_LARCH_GR2FR_W, a->rj, a->fd); ++ return true; ++} ++ ++static bool trans_movgr2fr_d(DisasContext *ctx, arg_movgr2fr_d *a) ++{ ++ gen_cp1(ctx, OPC_LARCH_GR2FR_D, a->rj, a->fd); ++ return true; ++} ++ ++static bool trans_movgr2frh_w(DisasContext *ctx, arg_movgr2frh_w *a) ++{ ++ gen_cp1(ctx, OPC_LARCH_GR2FRH_W, a->rj, a->fd); ++ return true; ++} ++ ++static bool trans_movfr2gr_s(DisasContext *ctx, arg_movfr2gr_s *a) ++{ ++ gen_cp1(ctx, OPC_LARCH_FR2GR_S, a->rd, a->fj); ++ return true; ++} ++ ++static bool trans_movfr2gr_d(DisasContext *ctx, arg_movfr2gr_d *a) ++{ ++ gen_cp1(ctx, OPC_LARCH_FR2GR_D, a->rd, a->fj); ++ return true; ++} ++ ++static bool trans_movfrh2gr_s(DisasContext *ctx, arg_movfrh2gr_s *a) ++{ ++ gen_cp1(ctx, OPC_LARCH_FRH2GR_S, a->rd, a->fj); ++ return true; ++} ++ ++static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_gpr(t0, a->rj); ++ save_cpu_state(ctx, 0); ++ { ++ TCGv_i32 fs_tmp = tcg_const_i32(a->fcsrd); ++ gen_helper_0e2i(movgr2fcsr, t0, fs_tmp, a->rj); ++ tcg_temp_free_i32(fs_tmp); ++ } ++ /* Stop translation as we may have changed hflags */ ++ ctx->base.is_jmp = DISAS_STOP; ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ gen_helper_1e0i(movfcsr2gr, t0, a->fcsrs); ++ gen_store_gpr(t0, a->rd); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a) ++{ ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i32 cd = tcg_const_i32(a->cd); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr64(ctx, fp0, a->fj); ++ gen_helper_movreg2cf(cpu_env, cd, fp0); ++ ++ tcg_temp_free_i64(fp0); ++ tcg_temp_free_i32(cd); ++ return true; ++} ++ ++static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv_i32 cj = tcg_const_i32(a->cj); ++ ++ check_cp1_enabled(ctx); ++ gen_helper_movcf2reg(t0, cpu_env, cj); ++ gen_store_fpr64(ctx, t0, a->fd); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv_i32 cd = tcg_const_i32(a->cd); ++ ++ check_cp1_enabled(ctx); ++ gen_load_gpr(t0, a->rj); ++ gen_helper_movreg2cf(cpu_env, cd, t0); ++ ++ tcg_temp_free(t0); ++ tcg_temp_free_i32(cd); ++ return true; ++} ++ ++static bool trans_movcf2gr(DisasContext *ctx, arg_movcf2gr *a) ++{ ++ TCGv_i32 cj = tcg_const_i32(a->cj); ++ ++ check_cp1_enabled(ctx); ++ gen_helper_movcf2reg(cpu_gpr[a->rd], cpu_env, cj); ++ ++ tcg_temp_free_i32(cj); ++ return true; ++} ++ ++static bool trans_fcvt_s_d(DisasContext *ctx, arg_fcvt_s_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FCVT_S_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fcvt_d_s(DisasContext *ctx, arg_fcvt_d_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FCVT_D_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrm_w_s(DisasContext *ctx, arg_ftintrm_l_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRM_W_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrm_w_d(DisasContext *ctx, arg_ftintrm_l_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRM_W_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrm_l_s(DisasContext *ctx, arg_ftintrm_l_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRM_L_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrm_l_d(DisasContext *ctx, arg_ftintrm_l_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRM_L_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrp_w_s(DisasContext *ctx, arg_ftintrp_w_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRP_W_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrp_w_d(DisasContext *ctx, arg_ftintrp_w_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRP_W_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrp_l_s(DisasContext *ctx, arg_ftintrp_l_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRP_L_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrp_l_d(DisasContext *ctx, arg_ftintrp_l_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRP_L_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrz_w_s(DisasContext *ctx, arg_ftintrz_w_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRZ_W_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrz_w_d(DisasContext *ctx, arg_ftintrz_w_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRZ_W_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrz_l_s(DisasContext *ctx, arg_ftintrz_l_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRZ_L_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrz_l_d(DisasContext *ctx, arg_ftintrz_l_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRZ_L_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrne_w_s(DisasContext *ctx, arg_ftintrne_w_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRNE_W_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrne_w_d(DisasContext *ctx, arg_ftintrne_w_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRNE_W_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrne_l_s(DisasContext *ctx, arg_ftintrne_l_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRNE_L_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrne_l_d(DisasContext *ctx, arg_ftintrne_l_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRNE_L_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftint_w_s(DisasContext *ctx, arg_ftint_w_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINT_W_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftint_w_d(DisasContext *ctx, arg_ftint_w_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINT_W_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftint_l_s(DisasContext *ctx, arg_ftint_l_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINT_L_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftint_l_d(DisasContext *ctx, arg_ftint_l_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINT_L_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ffint_s_w(DisasContext *ctx, arg_ffint_s_w *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FFINT_S_W, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ffint_s_l(DisasContext *ctx, arg_ffint_s_l *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FFINT_S_L, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ffint_d_w(DisasContext *ctx, arg_ffint_d_w *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FFINT_D_W, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ffint_d_l(DisasContext *ctx, arg_ffint_d_l *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FFINT_D_L, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_frint_s(DisasContext *ctx, arg_frint_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FRINT_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_frint_d(DisasContext *ctx, arg_frint_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FRINT_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_alsl_w(DisasContext *ctx, arg_alsl_w *a) ++{ ++ gen_lsa(ctx, OPC_LARCH_ALSL_W, a->rd, a->rj, a->rk, a->sa2); ++ return true; ++} ++ ++static bool trans_alsl_wu(DisasContext *ctx, arg_alsl_wu *a) ++{ ++ TCGv t0, t1; ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rj); ++ gen_load_gpr(t1, a->rk); ++ tcg_gen_shli_tl(t0, t0, a->sa2 + 1); ++ tcg_gen_add_tl(t0, t0, t1); ++ tcg_gen_ext32u_tl(cpu_gpr[a->rd], t0); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ ++ return true; ++} ++ ++static bool trans_alsl_d(DisasContext *ctx, arg_alsl_d *a) ++{ ++ check_larch_64(ctx); ++ gen_lsa(ctx, OPC_LARCH_ALSL_D, a->rd, a->rj, a->rk, a->sa2); ++ return true; ++} ++ ++static bool trans_bytepick_w(DisasContext *ctx, arg_bytepick_w *a) ++{ ++ gen_align(ctx, 32, a->rd, a->rj, a->rk, a->sa2); ++ return true; ++} ++ ++static bool trans_bytepick_d(DisasContext *ctx, arg_bytepick_d *a) ++{ ++ check_larch_64(ctx); ++ gen_align(ctx, 64, a->rd, a->rj, a->rk, a->sa3); ++ return true; ++} ++ ++static bool trans_add_w(DisasContext *ctx, arg_add_w *a) ++{ ++ gen_arith(ctx, OPC_LARCH_ADD_W, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_sub_w(DisasContext *ctx, arg_sub_w *a) ++{ ++ gen_arith(ctx, OPC_LARCH_SUB_W, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_add_d(DisasContext *ctx, arg_add_d *a) ++{ ++ gen_arith(ctx, OPC_LARCH_ADD_D, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_sub_d(DisasContext *ctx, arg_sub_d *a) ++{ ++ check_larch_64(ctx); ++ gen_arith(ctx, OPC_LARCH_SUB_D, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_slt(DisasContext *ctx, arg_slt *a) ++{ ++ gen_slt(ctx, OPC_LARCH_SLT, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_sltu(DisasContext *ctx, arg_sltu *a) ++{ ++ gen_slt(ctx, OPC_LARCH_SLTU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_maskeqz(DisasContext *ctx, arg_maskeqz *a) ++{ ++ gen_cond_move(ctx, OPC_LARCH_MASKEQZ, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_masknez(DisasContext *ctx, arg_masknez *a) ++{ ++ gen_cond_move(ctx, OPC_LARCH_MASKNEZ, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_nor(DisasContext *ctx, arg_nor *a) ++{ ++ gen_logic(ctx, OPC_LARCH_NOR, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_and(DisasContext *ctx, arg_and *a) ++{ ++ gen_logic(ctx, OPC_LARCH_AND, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_or(DisasContext *ctx, arg_or *a) ++{ ++ gen_logic(ctx, OPC_LARCH_OR, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_xor(DisasContext *ctx, arg_xor *a) ++{ ++ gen_logic(ctx, OPC_LARCH_XOR, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_orn(DisasContext *ctx, arg_orn *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rk); ++ tcg_gen_not_tl(t0, t0); ++ tcg_gen_or_tl(cpu_gpr[a->rd], cpu_gpr[a->rj], t0); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_andn(DisasContext *ctx, arg_andn *a) ++{ ++ TCGv t0, t1; ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rk); ++ gen_load_gpr(t1, a->rj); ++ tcg_gen_not_tl(t0, t0); ++ tcg_gen_and_tl(cpu_gpr[a->rd], t1, t0); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_sll_w(DisasContext *ctx, arg_sll_w *a) ++{ ++ gen_shift(ctx, OPC_LARCH_SLL_W, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_srl_w(DisasContext *ctx, arg_srl_w *a) ++{ ++ gen_shift(ctx, OPC_LARCH_SRL_W, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_sra_w(DisasContext *ctx, arg_sra_w *a) ++{ ++ gen_shift(ctx, OPC_LARCH_SRA_W, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_sll_d(DisasContext *ctx, arg_sll_d *a) ++{ ++ check_larch_64(ctx); ++ gen_shift(ctx, OPC_LARCH_SLL_D, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_srl_d(DisasContext *ctx, arg_srl_d *a) ++{ ++ check_larch_64(ctx); ++ gen_shift(ctx, OPC_LARCH_SRL_D, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_sra_d(DisasContext *ctx, arg_sra_d *a) ++{ ++ check_larch_64(ctx); ++ gen_shift(ctx, OPC_LARCH_SRA_D, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_rotr_w(DisasContext *ctx, arg_rotr_w *a) ++{ ++ gen_shift(ctx, OPC_LARCH_ROTR_W, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_rotr_d(DisasContext *ctx, arg_rotr_d *a) ++{ ++ check_larch_64(ctx); ++ gen_shift(ctx, OPC_LARCH_ROTR_D, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_crc_w_b_w(DisasContext *ctx, arg_crc_w_b_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 1, 0); ++ return true; ++} ++ ++static bool trans_crc_w_h_w(DisasContext *ctx, arg_crc_w_h_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 2, 0); ++ return true; ++} ++ ++static bool trans_crc_w_w_w(DisasContext *ctx, arg_crc_w_w_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 4, 0); ++ return true; ++} ++ ++static bool trans_crc_w_d_w(DisasContext *ctx, arg_crc_w_d_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 8, 0); ++ return true; ++} ++ ++static bool trans_crcc_w_b_w(DisasContext *ctx, arg_crcc_w_b_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 1, 1); ++ return true; ++} ++ ++static bool trans_crcc_w_h_w(DisasContext *ctx, arg_crcc_w_h_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 2, 1); ++ return true; ++} ++ ++static bool trans_crcc_w_w_w(DisasContext *ctx, arg_crcc_w_w_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 4, 1); ++ return true; ++} ++ ++static bool trans_crcc_w_d_w(DisasContext *ctx, arg_crcc_w_d_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 8, 1); ++ return true; ++} ++ ++static bool trans_mul_w(DisasContext *ctx, arg_mul_w *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_MUL_W, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mulh_w(DisasContext *ctx, arg_mulh_w *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_MULH_W, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mulh_wu(DisasContext *ctx, arg_mulh_wu *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_MULH_WU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mul_d(DisasContext *ctx, arg_mul_d *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_MUL_D, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mulh_d(DisasContext *ctx, arg_mulh_d *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_MULH_D, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mulh_du(DisasContext *ctx, arg_mulh_du *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_MULH_DU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mulw_d_w(DisasContext *ctx, arg_mulw_d_w *a) ++{ ++ TCGv_i64 t0 = tcg_temp_new_i64(); ++ TCGv_i64 t1 = tcg_temp_new_i64(); ++ TCGv_i64 t2 = tcg_temp_new_i64(); ++ gen_load_gpr(t0, a->rj); ++ gen_load_gpr(t1, a->rk); ++ tcg_gen_ext32s_i64(t0, t0); ++ tcg_gen_ext32s_i64(t1, t1); ++ tcg_gen_mul_i64(t2, t0, t1); ++ gen_store_gpr(t2, a->rd); ++ tcg_temp_free_i64(t0); ++ tcg_temp_free_i64(t1); ++ tcg_temp_free_i64(t2); ++ return true; ++} ++ ++static bool trans_mulw_d_wu(DisasContext *ctx, arg_mulw_d_wu *a) ++{ ++ TCGv_i64 t0 = tcg_temp_new_i64(); ++ TCGv_i64 t1 = tcg_temp_new_i64(); ++ TCGv_i64 t2 = tcg_temp_new_i64(); ++ gen_load_gpr(t0, a->rj); ++ gen_load_gpr(t1, a->rk); ++ tcg_gen_ext32u_i64(t0, t0); ++ tcg_gen_ext32u_i64(t1, t1); ++ tcg_gen_mul_i64(t2, t0, t1); ++ gen_store_gpr(t2, a->rd); ++ tcg_temp_free_i64(t0); ++ tcg_temp_free_i64(t1); ++ tcg_temp_free_i64(t2); ++ return true; ++} ++ ++static bool trans_div_w(DisasContext *ctx, arg_div_w *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_DIV_W, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mod_w(DisasContext *ctx, arg_mod_w *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_MOD_W, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_div_wu(DisasContext *ctx, arg_div_wu *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_DIV_WU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mod_wu(DisasContext *ctx, arg_mod_wu *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_MOD_WU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_div_d(DisasContext *ctx, arg_div_d *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_DIV_D, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mod_d(DisasContext *ctx, arg_mod_d *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_MOD_D, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_div_du(DisasContext *ctx, arg_div_du *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_DIV_DU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mod_du(DisasContext *ctx, arg_mod_du *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_MOD_DU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++/* do not update CP0.BadVaddr */ ++static bool trans_asrtle_d(DisasContext *ctx, arg_asrtle_d * a) ++{ ++ TCGv t1 = tcg_temp_new(); ++ TCGv t2 = tcg_temp_new(); ++ gen_load_gpr(t1, a->rj); ++ gen_load_gpr(t2, a->rk); ++ gen_helper_asrtle_d(cpu_env, t1, t2); ++ tcg_temp_free(t1); ++ tcg_temp_free(t2); ++ return true; ++} ++ ++/* do not update CP0.BadVaddr */ ++static bool trans_asrtgt_d(DisasContext *ctx, arg_asrtgt_d * a) ++{ ++ TCGv t1 = tcg_temp_new(); ++ TCGv t2 = tcg_temp_new(); ++ gen_load_gpr(t1, a->rj); ++ gen_load_gpr(t2, a->rk); ++ gen_helper_asrtgt_d(cpu_env, t1, t2); ++ tcg_temp_free(t1); ++ tcg_temp_free(t2); ++ return true; ++} ++ ++#ifdef CONFIG_USER_ONLY ++static bool trans_gr2scr(DisasContext *ctx, arg_gr2scr *a) ++{ ++ return false; ++} ++ ++static bool trans_scr2gr(DisasContext *ctx, arg_scr2gr *a) ++{ ++ return false; ++} ++#else ++static bool trans_gr2scr(DisasContext *ctx, arg_gr2scr *a) ++{ ++ TCGv_i32 sd = tcg_const_i32(a->sd); ++ TCGv val = tcg_temp_new(); ++ check_lbt_enabled(ctx); ++ gen_load_gpr(val, a->rj); ++ gen_helper_store_scr(cpu_env, sd, val); ++ tcg_temp_free_i32(sd); ++ tcg_temp_free(val); ++ return true; ++} ++ ++static bool trans_scr2gr(DisasContext *ctx, arg_scr2gr *a) ++{ ++ if (a->rd == 0) { ++ /* Nop */ ++ return true; ++ } ++ ++ TCGv_i32 tsj = tcg_const_i32(a->sj); ++ check_lbt_enabled(ctx); ++ gen_helper_load_scr(cpu_gpr[a->rd], cpu_env, tsj); ++ tcg_temp_free_i32(tsj); ++ return true; ++} ++#endif ++ ++static bool trans_clo_w(DisasContext *ctx, arg_clo_w *a) ++{ ++ gen_cl(ctx, OPC_LARCH_CLO_W, a->rd, a->rj); ++ return true; ++} ++ ++static bool trans_clz_w(DisasContext *ctx, arg_clz_w *a) ++{ ++ gen_cl(ctx, OPC_LARCH_CLZ_W, a->rd, a->rj); ++ return true; ++} ++ ++static bool trans_cto_w(DisasContext *ctx, arg_cto_w *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ gen_helper_cto_w(cpu_gpr[a->rd], cpu_env, t0); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_ctz_w(DisasContext *ctx, arg_ctz_w *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ gen_helper_ctz_w(cpu_gpr[a->rd], cpu_env, t0); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_clo_d(DisasContext *ctx, arg_clo_d *a) ++{ ++ check_larch_64(ctx); ++ gen_cl(ctx, OPC_LARCH_CLO_D, a->rd, a->rj); ++ return true; ++} ++ ++static bool trans_clz_d(DisasContext *ctx, arg_clz_d *a) ++{ ++ check_larch_64(ctx); ++ gen_cl(ctx, OPC_LARCH_CLZ_D, a->rd, a->rj); ++ return true; ++} ++ ++static bool trans_cto_d(DisasContext *ctx, arg_cto_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ gen_helper_cto_d(cpu_gpr[a->rd], cpu_env, t0); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_ctz_d(DisasContext *ctx, arg_ctz_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ gen_helper_ctz_d(cpu_gpr[a->rd], cpu_env, t0); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_revb_2h(DisasContext *ctx, arg_revb_2h *a) ++{ ++ gen_bshfl(ctx, OPC_LARCH_REVB_2H, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_revb_4h(DisasContext *ctx, arg_revb_4h *a) ++{ ++ check_larch_64(ctx); ++ gen_bshfl(ctx, OPC_LARCH_REVB_4H, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_revb_2w(DisasContext *ctx, arg_revb_2w *a) ++{ ++ handle_rev32(ctx, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_revb_d(DisasContext *ctx, arg_revb_d *a) ++{ ++ handle_rev64(ctx, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_revh_2w(DisasContext *ctx, arg_revh_2w *a) ++{ ++ handle_rev16(ctx, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_revh_d(DisasContext *ctx, arg_revh_d *a) ++{ ++ check_larch_64(ctx); ++ gen_bshfl(ctx, OPC_LARCH_REVH_D, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_bitrev_4b(DisasContext *ctx, arg_bitrev_4b *a) ++{ ++ gen_bitswap(ctx, OPC_LARCH_BREV_4B, a->rd, a->rj); ++ return true; ++} ++ ++static bool trans_bitrev_8b(DisasContext *ctx, arg_bitrev_8b *a) ++{ ++ check_larch_64(ctx); ++ gen_bitswap(ctx, OPC_LARCH_BREV_8B, a->rd, a->rj); ++ return true; ++} ++ ++static bool trans_bitrev_w(DisasContext *ctx, arg_bitrev_w *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rj); ++ gen_helper_bitrev_w(cpu_gpr[a->rd], cpu_env, t0); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_bitrev_d(DisasContext *ctx, arg_bitrev_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rj); ++ gen_helper_bitrev_d(cpu_gpr[a->rd], cpu_env, t0); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_ext_w_h(DisasContext *ctx, arg_ext_w_h *a) ++{ ++ gen_bshfl(ctx, OPC_LARCH_EXT_WH, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_ext_w_b(DisasContext *ctx, arg_ext_w_b *a) ++{ ++ gen_bshfl(ctx, OPC_LARCH_EXT_WB, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_srli_w(DisasContext *ctx, arg_srli_w *a) ++{ ++ gen_shift_imm(ctx, OPC_LARCH_SRLI_W, a->rd, a->rj, a->ui5); ++ return true; ++} ++ ++static bool trans_srai_w(DisasContext *ctx, arg_srai_w *a) ++{ ++ gen_shift_imm(ctx, OPC_LARCH_SRAI_W, a->rd, a->rj, a->ui5); ++ return true; ++} ++ ++static bool trans_srai_d(DisasContext *ctx, arg_srai_d *a) ++{ ++ TCGv t0; ++ check_larch_64(ctx); ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rj); ++ tcg_gen_sari_tl(cpu_gpr[a->rd], t0, a->ui6); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_rotri_w(DisasContext *ctx, arg_rotri_w *a) ++{ ++ gen_shift_imm(ctx, OPC_LARCH_ROTRI_W, a->rd, a->rj, a->ui5); ++ return true; ++} ++ ++static bool trans_rotri_d(DisasContext *ctx, arg_rotri_d *a) ++{ ++ TCGv t0; ++ check_larch_64(ctx); ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rj); ++ tcg_gen_rotri_tl(cpu_gpr[a->rd], t0, a->ui6); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a) ++{ ++ check_cp1_enabled(ctx); ++ gen_fcmp_s(ctx, a->fcond, a->fk, a->fj, a->cd); ++ return true; ++} ++ ++static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a) ++{ ++ check_cp1_enabled(ctx); ++ gen_fcmp_d(ctx, a->fcond, a->fk, a->fj, a->cd); ++ return true; ++} ++ ++static bool trans_fsel(DisasContext *ctx, arg_fsel *a) ++{ ++ TCGv_i64 fj = tcg_temp_new_i64(); ++ TCGv_i64 fk = tcg_temp_new_i64(); ++ TCGv_i64 fd = tcg_temp_new_i64(); ++ TCGv_i32 ca = tcg_const_i32(a->ca); ++ check_cp1_enabled(ctx); ++ gen_load_fpr64(ctx, fj, a->fj); ++ gen_load_fpr64(ctx, fk, a->fk); ++ gen_helper_fsel(fd, cpu_env, fj, fk, ca); ++ gen_store_fpr64(ctx, fd, a->fd); ++ tcg_temp_free_i64(fj); ++ tcg_temp_free_i64(fk); ++ tcg_temp_free_i64(fd); ++ tcg_temp_free_i32(ca); ++ return true; ++} ++ ++#include "cpu-csr.h" ++ ++#ifdef CONFIG_USER_ONLY ++ ++static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) ++{ ++ return false; ++} ++ ++#else ++ ++ ++#define GEN_CSRRQ_CASE(name) \ ++ do { \ ++ case LOONGARCH_CSR_ ## name: \ ++ gen_csr_rdq(ctx, cpu_gpr[rd], LOONGARCH_CSR_ ## name);\ ++ } while (0) ++ ++static bool trans_csrrd(DisasContext *ctx, unsigned rd, unsigned csr) ++{ ++ switch (csr) { ++ GEN_CSRRQ_CASE(CRMD); ++ break; ++ GEN_CSRRQ_CASE(PRMD); ++ break; ++ GEN_CSRRQ_CASE(EUEN); ++ break; ++ GEN_CSRRQ_CASE(MISC); ++ break; ++ GEN_CSRRQ_CASE(ECFG); ++ break; ++ GEN_CSRRQ_CASE(ESTAT); ++ break; ++ GEN_CSRRQ_CASE(ERA); ++ break; ++ GEN_CSRRQ_CASE(BADV); ++ break; ++ GEN_CSRRQ_CASE(BADI); ++ break; ++ GEN_CSRRQ_CASE(EEPN); ++ break; ++ GEN_CSRRQ_CASE(TLBIDX); ++ break; ++ GEN_CSRRQ_CASE(TLBEHI); ++ break; ++ GEN_CSRRQ_CASE(TLBELO0); ++ break; ++ GEN_CSRRQ_CASE(TLBELO1); ++ break; ++ GEN_CSRRQ_CASE(TLBWIRED); ++ break; ++ GEN_CSRRQ_CASE(GTLBC); ++ break; ++ GEN_CSRRQ_CASE(TRGP); ++ break; ++ GEN_CSRRQ_CASE(ASID); ++ break; ++ GEN_CSRRQ_CASE(PGDL); ++ break; ++ GEN_CSRRQ_CASE(PGDH); ++ break; ++ case LOONGARCH_CSR_PGD: ++ gen_helper_read_pgd(cpu_gpr[rd], cpu_env); ++ break; ++ GEN_CSRRQ_CASE(PWCTL0); ++ break; ++ GEN_CSRRQ_CASE(PWCTL1); ++ break; ++ GEN_CSRRQ_CASE(STLBPGSIZE); ++ break; ++ GEN_CSRRQ_CASE(RVACFG); ++ break; ++ GEN_CSRRQ_CASE(CPUID); ++ break; ++ GEN_CSRRQ_CASE(PRCFG1); ++ break; ++ GEN_CSRRQ_CASE(PRCFG2); ++ break; ++ GEN_CSRRQ_CASE(PRCFG3); ++ break; ++ GEN_CSRRQ_CASE(KS0); ++ break; ++ GEN_CSRRQ_CASE(KS1); ++ break; ++ GEN_CSRRQ_CASE(KS2); ++ break; ++ GEN_CSRRQ_CASE(KS3); ++ break; ++ GEN_CSRRQ_CASE(KS4); ++ break; ++ GEN_CSRRQ_CASE(KS5); ++ break; ++ GEN_CSRRQ_CASE(KS6); ++ break; ++ GEN_CSRRQ_CASE(KS7); ++ break; ++ GEN_CSRRQ_CASE(KS8); ++ break; ++ GEN_CSRRQ_CASE(TMID); ++ break; ++ GEN_CSRRQ_CASE(TCFG); ++ break; ++ GEN_CSRRQ_CASE(TVAL); ++ break; ++ GEN_CSRRQ_CASE(CNTC); ++ break; ++ GEN_CSRRQ_CASE(TINTCLR); ++ break; ++ GEN_CSRRQ_CASE(GSTAT); ++ break; ++ GEN_CSRRQ_CASE(GCFG); ++ break; ++ GEN_CSRRQ_CASE(GINTC); ++ break; ++ GEN_CSRRQ_CASE(GCNTC); ++ break; ++ GEN_CSRRQ_CASE(LLBCTL); ++ break; ++ GEN_CSRRQ_CASE(IMPCTL1); ++ break; ++ GEN_CSRRQ_CASE(IMPCTL2); ++ break; ++ GEN_CSRRQ_CASE(GNMI); ++ break; ++ GEN_CSRRQ_CASE(TLBRENT); ++ break; ++ GEN_CSRRQ_CASE(TLBRBADV); ++ break; ++ GEN_CSRRQ_CASE(TLBRERA); ++ break; ++ GEN_CSRRQ_CASE(TLBRSAVE); ++ break; ++ GEN_CSRRQ_CASE(TLBRELO0); ++ break; ++ GEN_CSRRQ_CASE(TLBRELO1); ++ break; ++ GEN_CSRRQ_CASE(TLBREHI); ++ break; ++ GEN_CSRRQ_CASE(TLBRPRMD); ++ break; ++ GEN_CSRRQ_CASE(ERRCTL); ++ break; ++ GEN_CSRRQ_CASE(ERRINFO); ++ break; ++ GEN_CSRRQ_CASE(ERRINFO1); ++ break; ++ GEN_CSRRQ_CASE(ERRENT); ++ break; ++ GEN_CSRRQ_CASE(ERRERA); ++ break; ++ GEN_CSRRQ_CASE(ERRSAVE); ++ break; ++ GEN_CSRRQ_CASE(CTAG); ++ break; ++ GEN_CSRRQ_CASE(DMWIN0); ++ break; ++ GEN_CSRRQ_CASE(DMWIN1); ++ break; ++ GEN_CSRRQ_CASE(DMWIN2); ++ break; ++ GEN_CSRRQ_CASE(DMWIN3); ++ break; ++ GEN_CSRRQ_CASE(PERFCTRL0); ++ break; ++ GEN_CSRRQ_CASE(PERFCNTR0); ++ break; ++ GEN_CSRRQ_CASE(PERFCTRL1); ++ break; ++ GEN_CSRRQ_CASE(PERFCNTR1); ++ break; ++ GEN_CSRRQ_CASE(PERFCTRL2); ++ break; ++ GEN_CSRRQ_CASE(PERFCNTR2); ++ break; ++ GEN_CSRRQ_CASE(PERFCTRL3); ++ break; ++ GEN_CSRRQ_CASE(PERFCNTR3); ++ break; ++ /* debug */ ++ GEN_CSRRQ_CASE(MWPC); ++ break; ++ GEN_CSRRQ_CASE(MWPS); ++ break; ++ GEN_CSRRQ_CASE(DB0ADDR); ++ break; ++ GEN_CSRRQ_CASE(DB0MASK); ++ break; ++ GEN_CSRRQ_CASE(DB0CTL); ++ break; ++ GEN_CSRRQ_CASE(DB0ASID); ++ break; ++ GEN_CSRRQ_CASE(DB1ADDR); ++ break; ++ GEN_CSRRQ_CASE(DB1MASK); ++ break; ++ GEN_CSRRQ_CASE(DB1CTL); ++ break; ++ GEN_CSRRQ_CASE(DB1ASID); ++ break; ++ GEN_CSRRQ_CASE(DB2ADDR); ++ break; ++ GEN_CSRRQ_CASE(DB2MASK); ++ break; ++ GEN_CSRRQ_CASE(DB2CTL); ++ break; ++ GEN_CSRRQ_CASE(DB2ASID); ++ break; ++ GEN_CSRRQ_CASE(DB3ADDR); ++ break; ++ GEN_CSRRQ_CASE(DB3MASK); ++ break; ++ GEN_CSRRQ_CASE(DB3CTL); ++ break; ++ GEN_CSRRQ_CASE(DB3ASID); ++ break; ++ GEN_CSRRQ_CASE(FWPC); ++ break; ++ GEN_CSRRQ_CASE(FWPS); ++ break; ++ GEN_CSRRQ_CASE(IB0ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB0MASK); ++ break; ++ GEN_CSRRQ_CASE(IB0CTL); ++ break; ++ GEN_CSRRQ_CASE(IB0ASID); ++ break; ++ GEN_CSRRQ_CASE(IB1ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB1MASK); ++ break; ++ GEN_CSRRQ_CASE(IB1CTL); ++ break; ++ GEN_CSRRQ_CASE(IB1ASID); ++ break; ++ GEN_CSRRQ_CASE(IB2ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB2MASK); ++ break; ++ GEN_CSRRQ_CASE(IB2CTL); ++ break; ++ GEN_CSRRQ_CASE(IB2ASID); ++ break; ++ GEN_CSRRQ_CASE(IB3ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB3MASK); ++ break; ++ GEN_CSRRQ_CASE(IB3CTL); ++ break; ++ GEN_CSRRQ_CASE(IB3ASID); ++ break; ++ GEN_CSRRQ_CASE(IB4ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB4MASK); ++ break; ++ GEN_CSRRQ_CASE(IB4CTL); ++ break; ++ GEN_CSRRQ_CASE(IB4ASID); ++ break; ++ GEN_CSRRQ_CASE(IB5ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB5MASK); ++ break; ++ GEN_CSRRQ_CASE(IB5CTL); ++ break; ++ GEN_CSRRQ_CASE(IB5ASID); ++ break; ++ GEN_CSRRQ_CASE(IB6ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB6MASK); ++ break; ++ GEN_CSRRQ_CASE(IB6CTL); ++ break; ++ GEN_CSRRQ_CASE(IB6ASID); ++ break; ++ GEN_CSRRQ_CASE(IB7ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB7MASK); ++ break; ++ GEN_CSRRQ_CASE(IB7CTL); ++ break; ++ GEN_CSRRQ_CASE(IB7ASID); ++ break; ++ GEN_CSRRQ_CASE(DEBUG); ++ break; ++ GEN_CSRRQ_CASE(DERA); ++ break; ++ GEN_CSRRQ_CASE(DESAVE); ++ break; ++ default: ++ return false; ++ } ++ ++ #undef GEN_CSRRQ_CASE ++ ++ return true; ++} ++ ++#define GEN_CSRWQ_CASE(name) \ ++do { \ ++ case LOONGARCH_CSR_ ## name: \ ++ gen_csr_wrq(ctx, cpu_gpr[rd], LOONGARCH_CSR_ ## name); \ ++} while (0) ++ ++static bool trans_csrwr(DisasContext *ctx, unsigned rd, unsigned csr) ++{ ++ ++ switch (csr) { ++ case LOONGARCH_CSR_CRMD: ++ save_cpu_state(ctx, 1); ++ gen_csr_wrq(ctx, cpu_gpr[rd], LOONGARCH_CSR_CRMD); ++ gen_save_pc(ctx->base.pc_next + 4); ++ ctx->base.is_jmp = DISAS_EXIT; ++ break; ++ GEN_CSRWQ_CASE(PRMD); ++ break; ++ case LOONGARCH_CSR_EUEN: ++ gen_csr_wrq(ctx, cpu_gpr[rd], LOONGARCH_CSR_EUEN); ++ /* Stop translation */ ++ gen_save_pc(ctx->base.pc_next + 4); ++ ctx->base.is_jmp = DISAS_EXIT; ++ break; ++ GEN_CSRWQ_CASE(MISC); ++ break; ++ GEN_CSRWQ_CASE(ECFG); ++ break; ++ GEN_CSRWQ_CASE(ESTAT); ++ break; ++ GEN_CSRWQ_CASE(ERA); ++ break; ++ GEN_CSRWQ_CASE(BADV); ++ break; ++ GEN_CSRWQ_CASE(BADI); ++ break; ++ GEN_CSRWQ_CASE(EEPN); ++ break; ++ GEN_CSRWQ_CASE(TLBIDX); ++ break; ++ GEN_CSRWQ_CASE(TLBEHI); ++ break; ++ GEN_CSRWQ_CASE(TLBELO0); ++ break; ++ GEN_CSRWQ_CASE(TLBELO1); ++ break; ++ GEN_CSRWQ_CASE(TLBWIRED); ++ break; ++ GEN_CSRWQ_CASE(GTLBC); ++ break; ++ GEN_CSRWQ_CASE(TRGP); ++ break; ++ GEN_CSRWQ_CASE(ASID); ++ break; ++ GEN_CSRWQ_CASE(PGDL); ++ break; ++ GEN_CSRWQ_CASE(PGDH); ++ break; ++ GEN_CSRWQ_CASE(PGD); ++ break; ++ GEN_CSRWQ_CASE(PWCTL0); ++ break; ++ GEN_CSRWQ_CASE(PWCTL1); ++ break; ++ GEN_CSRWQ_CASE(STLBPGSIZE); ++ break; ++ GEN_CSRWQ_CASE(RVACFG); ++ break; ++ GEN_CSRWQ_CASE(CPUID); ++ break; ++ GEN_CSRWQ_CASE(PRCFG1); ++ break; ++ GEN_CSRWQ_CASE(PRCFG2); ++ break; ++ GEN_CSRWQ_CASE(PRCFG3); ++ break; ++ GEN_CSRWQ_CASE(KS0); ++ break; ++ GEN_CSRWQ_CASE(KS1); ++ break; ++ GEN_CSRWQ_CASE(KS2); ++ break; ++ GEN_CSRWQ_CASE(KS3); ++ break; ++ GEN_CSRWQ_CASE(KS4); ++ break; ++ GEN_CSRWQ_CASE(KS5); ++ break; ++ GEN_CSRWQ_CASE(KS6); ++ break; ++ GEN_CSRWQ_CASE(KS7); ++ break; ++ GEN_CSRWQ_CASE(KS8); ++ break; ++ GEN_CSRWQ_CASE(TMID); ++ break; ++ GEN_CSRWQ_CASE(TCFG); ++ break; ++ GEN_CSRWQ_CASE(TVAL); ++ break; ++ GEN_CSRWQ_CASE(CNTC); ++ break; ++ GEN_CSRWQ_CASE(TINTCLR); ++ break; ++ GEN_CSRWQ_CASE(GSTAT); ++ break; ++ GEN_CSRWQ_CASE(GCFG); ++ break; ++ GEN_CSRWQ_CASE(GINTC); ++ break; ++ GEN_CSRWQ_CASE(GCNTC); ++ break; ++ GEN_CSRWQ_CASE(LLBCTL); ++ break; ++ GEN_CSRWQ_CASE(IMPCTL1); ++ break; ++ GEN_CSRWQ_CASE(IMPCTL2); ++ break; ++ GEN_CSRWQ_CASE(GNMI); ++ break; ++ GEN_CSRWQ_CASE(TLBRENT); ++ break; ++ GEN_CSRWQ_CASE(TLBRBADV); ++ break; ++ GEN_CSRWQ_CASE(TLBRERA); ++ break; ++ GEN_CSRWQ_CASE(TLBRSAVE); ++ break; ++ GEN_CSRWQ_CASE(TLBRELO0); ++ break; ++ GEN_CSRWQ_CASE(TLBRELO1); ++ break; ++ GEN_CSRWQ_CASE(TLBREHI); ++ break; ++ GEN_CSRWQ_CASE(TLBRPRMD); ++ break; ++ GEN_CSRWQ_CASE(ERRCTL); ++ break; ++ GEN_CSRWQ_CASE(ERRINFO); ++ break; ++ GEN_CSRWQ_CASE(ERRINFO1); ++ break; ++ GEN_CSRWQ_CASE(ERRENT); ++ break; ++ GEN_CSRWQ_CASE(ERRERA); ++ break; ++ GEN_CSRWQ_CASE(ERRSAVE); ++ break; ++ GEN_CSRWQ_CASE(CTAG); ++ break; ++ GEN_CSRWQ_CASE(DMWIN0); ++ break; ++ GEN_CSRWQ_CASE(DMWIN1); ++ break; ++ GEN_CSRWQ_CASE(DMWIN2); ++ break; ++ GEN_CSRWQ_CASE(DMWIN3); ++ break; ++ GEN_CSRWQ_CASE(PERFCTRL0); ++ break; ++ GEN_CSRWQ_CASE(PERFCNTR0); ++ break; ++ GEN_CSRWQ_CASE(PERFCTRL1); ++ break; ++ GEN_CSRWQ_CASE(PERFCNTR1); ++ break; ++ GEN_CSRWQ_CASE(PERFCTRL2); ++ break; ++ GEN_CSRWQ_CASE(PERFCNTR2); ++ break; ++ GEN_CSRWQ_CASE(PERFCTRL3); ++ break; ++ GEN_CSRWQ_CASE(PERFCNTR3); ++ break; ++ /* debug */ ++ GEN_CSRWQ_CASE(MWPC); ++ break; ++ GEN_CSRWQ_CASE(MWPS); ++ break; ++ GEN_CSRWQ_CASE(DB0ADDR); ++ break; ++ GEN_CSRWQ_CASE(DB0MASK); ++ break; ++ GEN_CSRWQ_CASE(DB0CTL); ++ break; ++ GEN_CSRWQ_CASE(DB0ASID); ++ break; ++ GEN_CSRWQ_CASE(DB1ADDR); ++ break; ++ GEN_CSRWQ_CASE(DB1MASK); ++ break; ++ GEN_CSRWQ_CASE(DB1CTL); ++ break; ++ GEN_CSRWQ_CASE(DB1ASID); ++ break; ++ GEN_CSRWQ_CASE(DB2ADDR); ++ break; ++ GEN_CSRWQ_CASE(DB2MASK); ++ break; ++ GEN_CSRWQ_CASE(DB2CTL); ++ break; ++ GEN_CSRWQ_CASE(DB2ASID); ++ break; ++ GEN_CSRWQ_CASE(DB3ADDR); ++ break; ++ GEN_CSRWQ_CASE(DB3MASK); ++ break; ++ GEN_CSRWQ_CASE(DB3CTL); ++ break; ++ GEN_CSRWQ_CASE(DB3ASID); ++ break; ++ GEN_CSRWQ_CASE(FWPC); ++ break; ++ GEN_CSRWQ_CASE(FWPS); ++ break; ++ GEN_CSRWQ_CASE(IB0ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB0MASK); ++ break; ++ GEN_CSRWQ_CASE(IB0CTL); ++ break; ++ GEN_CSRWQ_CASE(IB0ASID); ++ break; ++ GEN_CSRWQ_CASE(IB1ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB1MASK); ++ break; ++ GEN_CSRWQ_CASE(IB1CTL); ++ break; ++ GEN_CSRWQ_CASE(IB1ASID); ++ break; ++ GEN_CSRWQ_CASE(IB2ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB2MASK); ++ break; ++ GEN_CSRWQ_CASE(IB2CTL); ++ break; ++ GEN_CSRWQ_CASE(IB2ASID); ++ break; ++ GEN_CSRWQ_CASE(IB3ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB3MASK); ++ break; ++ GEN_CSRWQ_CASE(IB3CTL); ++ break; ++ GEN_CSRWQ_CASE(IB3ASID); ++ break; ++ GEN_CSRWQ_CASE(IB4ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB4MASK); ++ break; ++ GEN_CSRWQ_CASE(IB4CTL); ++ break; ++ GEN_CSRWQ_CASE(IB4ASID); ++ break; ++ GEN_CSRWQ_CASE(IB5ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB5MASK); ++ break; ++ GEN_CSRWQ_CASE(IB5CTL); ++ break; ++ GEN_CSRWQ_CASE(IB5ASID); ++ break; ++ GEN_CSRWQ_CASE(IB6ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB6MASK); ++ break; ++ GEN_CSRWQ_CASE(IB6CTL); ++ break; ++ GEN_CSRWQ_CASE(IB6ASID); ++ break; ++ GEN_CSRWQ_CASE(IB7ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB7MASK); ++ break; ++ GEN_CSRWQ_CASE(IB7CTL); ++ break; ++ GEN_CSRWQ_CASE(IB7ASID); ++ break; ++ GEN_CSRWQ_CASE(DEBUG); ++ break; ++ GEN_CSRWQ_CASE(DERA); ++ break; ++ GEN_CSRWQ_CASE(DESAVE); ++ break; ++ default: ++ return false; ++ } ++ ++ #undef GEN_CSRWQ_CASE ++ ++ return true; ++} ++ ++#define GEN_CSRXQ_CASE(name) \ ++do { \ ++ case LOONGARCH_CSR_ ## name: \ ++ if (rd == 0) { \ ++ gen_csr_xchgq(ctx, zero, cpu_gpr[rj], \ ++ LOONGARCH_CSR_ ## name); \ ++ } else { \ ++ gen_csr_xchgq(ctx, cpu_gpr[rd], cpu_gpr[rj], \ ++ LOONGARCH_CSR_ ## name); \ ++ } \ ++} while (0) ++ ++static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) ++{ ++ unsigned rd, rj, csr; ++ TCGv zero = tcg_const_tl(0); ++ rd = a->rd; ++ rj = a->rj; ++ csr = a->csr; ++ ++ if (rj == 0) { ++ return trans_csrrd(ctx, rd, csr); ++ } else if (rj == 1) { ++ return trans_csrwr(ctx, rd, csr); ++ } ++ ++ switch (csr) { ++ case LOONGARCH_CSR_CRMD: ++ save_cpu_state(ctx, 1); ++ if (rd == 0) { ++ gen_csr_xchgq(ctx, zero, cpu_gpr[rj], LOONGARCH_CSR_CRMD); ++ } else { ++ gen_csr_xchgq(ctx, cpu_gpr[rd], cpu_gpr[rj], LOONGARCH_CSR_CRMD); ++ } ++ gen_save_pc(ctx->base.pc_next + 4); ++ ctx->base.is_jmp = DISAS_EXIT; ++ break; ++ ++ GEN_CSRXQ_CASE(PRMD); ++ break; ++ case LOONGARCH_CSR_EUEN: ++ if (rd == 0) { ++ gen_csr_xchgq(ctx, zero, cpu_gpr[rj], LOONGARCH_CSR_EUEN); ++ } else { ++ gen_csr_xchgq(ctx, cpu_gpr[rd], cpu_gpr[rj], LOONGARCH_CSR_EUEN); ++ } ++ /* Stop translation */ ++ gen_save_pc(ctx->base.pc_next + 4); ++ ctx->base.is_jmp = DISAS_EXIT; ++ break; ++ GEN_CSRXQ_CASE(MISC); ++ break; ++ GEN_CSRXQ_CASE(ECFG); ++ break; ++ GEN_CSRXQ_CASE(ESTAT); ++ break; ++ GEN_CSRXQ_CASE(ERA); ++ break; ++ GEN_CSRXQ_CASE(BADV); ++ break; ++ GEN_CSRXQ_CASE(BADI); ++ break; ++ GEN_CSRXQ_CASE(EEPN); ++ break; ++ GEN_CSRXQ_CASE(TLBIDX); ++ break; ++ GEN_CSRXQ_CASE(TLBEHI); ++ break; ++ GEN_CSRXQ_CASE(TLBELO0); ++ break; ++ GEN_CSRXQ_CASE(TLBELO1); ++ break; ++ GEN_CSRXQ_CASE(TLBWIRED); ++ break; ++ GEN_CSRXQ_CASE(GTLBC); ++ break; ++ GEN_CSRXQ_CASE(TRGP); ++ break; ++ GEN_CSRXQ_CASE(ASID); ++ break; ++ GEN_CSRXQ_CASE(PGDL); ++ break; ++ GEN_CSRXQ_CASE(PGDH); ++ break; ++ GEN_CSRXQ_CASE(PGD); ++ break; ++ GEN_CSRXQ_CASE(PWCTL0); ++ break; ++ GEN_CSRXQ_CASE(PWCTL1); ++ break; ++ GEN_CSRXQ_CASE(STLBPGSIZE); ++ break; ++ GEN_CSRXQ_CASE(RVACFG); ++ break; ++ GEN_CSRXQ_CASE(CPUID); ++ break; ++ GEN_CSRXQ_CASE(PRCFG1); ++ break; ++ GEN_CSRXQ_CASE(PRCFG2); ++ break; ++ GEN_CSRXQ_CASE(PRCFG3); ++ break; ++ GEN_CSRXQ_CASE(KS0); ++ break; ++ GEN_CSRXQ_CASE(KS1); ++ break; ++ GEN_CSRXQ_CASE(KS2); ++ break; ++ GEN_CSRXQ_CASE(KS3); ++ break; ++ GEN_CSRXQ_CASE(KS4); ++ break; ++ GEN_CSRXQ_CASE(KS5); ++ break; ++ GEN_CSRXQ_CASE(KS6); ++ break; ++ GEN_CSRXQ_CASE(KS7); ++ break; ++ GEN_CSRXQ_CASE(KS8); ++ break; ++ GEN_CSRXQ_CASE(TMID); ++ break; ++ GEN_CSRXQ_CASE(TCFG); ++ break; ++ GEN_CSRXQ_CASE(TVAL); ++ break; ++ GEN_CSRXQ_CASE(CNTC); ++ break; ++ GEN_CSRXQ_CASE(TINTCLR); ++ break; ++ GEN_CSRXQ_CASE(GSTAT); ++ break; ++ GEN_CSRXQ_CASE(GCFG); ++ break; ++ GEN_CSRXQ_CASE(GINTC); ++ break; ++ GEN_CSRXQ_CASE(GCNTC); ++ break; ++ GEN_CSRXQ_CASE(LLBCTL); ++ break; ++ GEN_CSRXQ_CASE(IMPCTL1); ++ break; ++ GEN_CSRXQ_CASE(IMPCTL2); ++ break; ++ GEN_CSRXQ_CASE(GNMI); ++ break; ++ GEN_CSRXQ_CASE(TLBRENT); ++ break; ++ GEN_CSRXQ_CASE(TLBRBADV); ++ break; ++ GEN_CSRXQ_CASE(TLBRERA); ++ break; ++ GEN_CSRXQ_CASE(TLBRSAVE); ++ break; ++ GEN_CSRXQ_CASE(TLBRELO0); ++ break; ++ GEN_CSRXQ_CASE(TLBRELO1); ++ break; ++ GEN_CSRXQ_CASE(TLBREHI); ++ break; ++ GEN_CSRXQ_CASE(TLBRPRMD); ++ break; ++ GEN_CSRXQ_CASE(ERRCTL); ++ break; ++ GEN_CSRXQ_CASE(ERRINFO); ++ break; ++ GEN_CSRXQ_CASE(ERRINFO1); ++ break; ++ GEN_CSRXQ_CASE(ERRENT); ++ break; ++ GEN_CSRXQ_CASE(ERRERA); ++ break; ++ GEN_CSRXQ_CASE(ERRSAVE); ++ break; ++ GEN_CSRXQ_CASE(CTAG); ++ break; ++ GEN_CSRXQ_CASE(DMWIN0); ++ break; ++ GEN_CSRXQ_CASE(DMWIN1); ++ break; ++ GEN_CSRXQ_CASE(DMWIN2); ++ break; ++ GEN_CSRXQ_CASE(DMWIN3); ++ break; ++ GEN_CSRXQ_CASE(PERFCTRL0); ++ break; ++ GEN_CSRXQ_CASE(PERFCNTR0); ++ break; ++ GEN_CSRXQ_CASE(PERFCTRL1); ++ break; ++ GEN_CSRXQ_CASE(PERFCNTR1); ++ break; ++ GEN_CSRXQ_CASE(PERFCTRL2); ++ break; ++ GEN_CSRXQ_CASE(PERFCNTR2); ++ break; ++ GEN_CSRXQ_CASE(PERFCTRL3); ++ break; ++ GEN_CSRXQ_CASE(PERFCNTR3); ++ break; ++ /* debug */ ++ GEN_CSRXQ_CASE(MWPC); ++ break; ++ GEN_CSRXQ_CASE(MWPS); ++ break; ++ GEN_CSRXQ_CASE(DB0ADDR); ++ break; ++ GEN_CSRXQ_CASE(DB0MASK); ++ break; ++ GEN_CSRXQ_CASE(DB0CTL); ++ break; ++ GEN_CSRXQ_CASE(DB0ASID); ++ break; ++ GEN_CSRXQ_CASE(DB1ADDR); ++ break; ++ GEN_CSRXQ_CASE(DB1MASK); ++ break; ++ GEN_CSRXQ_CASE(DB1CTL); ++ break; ++ GEN_CSRXQ_CASE(DB1ASID); ++ break; ++ GEN_CSRXQ_CASE(DB2ADDR); ++ break; ++ GEN_CSRXQ_CASE(DB2MASK); ++ break; ++ GEN_CSRXQ_CASE(DB2CTL); ++ break; ++ GEN_CSRXQ_CASE(DB2ASID); ++ break; ++ GEN_CSRXQ_CASE(DB3ADDR); ++ break; ++ GEN_CSRXQ_CASE(DB3MASK); ++ break; ++ GEN_CSRXQ_CASE(DB3CTL); ++ break; ++ GEN_CSRXQ_CASE(DB3ASID); ++ break; ++ GEN_CSRXQ_CASE(FWPC); ++ break; ++ GEN_CSRXQ_CASE(FWPS); ++ break; ++ GEN_CSRXQ_CASE(IB0ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB0MASK); ++ break; ++ GEN_CSRXQ_CASE(IB0CTL); ++ break; ++ GEN_CSRXQ_CASE(IB0ASID); ++ break; ++ GEN_CSRXQ_CASE(IB1ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB1MASK); ++ break; ++ GEN_CSRXQ_CASE(IB1CTL); ++ break; ++ GEN_CSRXQ_CASE(IB1ASID); ++ break; ++ GEN_CSRXQ_CASE(IB2ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB2MASK); ++ break; ++ GEN_CSRXQ_CASE(IB2CTL); ++ break; ++ GEN_CSRXQ_CASE(IB2ASID); ++ break; ++ GEN_CSRXQ_CASE(IB3ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB3MASK); ++ break; ++ GEN_CSRXQ_CASE(IB3CTL); ++ break; ++ GEN_CSRXQ_CASE(IB3ASID); ++ break; ++ GEN_CSRXQ_CASE(IB4ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB4MASK); ++ break; ++ GEN_CSRXQ_CASE(IB4CTL); ++ break; ++ GEN_CSRXQ_CASE(IB4ASID); ++ break; ++ GEN_CSRXQ_CASE(IB5ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB5MASK); ++ break; ++ GEN_CSRXQ_CASE(IB5CTL); ++ break; ++ GEN_CSRXQ_CASE(IB5ASID); ++ break; ++ GEN_CSRXQ_CASE(IB6ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB6MASK); ++ break; ++ GEN_CSRXQ_CASE(IB6CTL); ++ break; ++ GEN_CSRXQ_CASE(IB6ASID); ++ break; ++ GEN_CSRXQ_CASE(IB7ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB7MASK); ++ break; ++ GEN_CSRXQ_CASE(IB7CTL); ++ break; ++ GEN_CSRXQ_CASE(IB7ASID); ++ break; ++ GEN_CSRXQ_CASE(DEBUG); ++ break; ++ GEN_CSRXQ_CASE(DERA); ++ break; ++ GEN_CSRXQ_CASE(DESAVE); ++ break; ++ default: ++ return false; ++ } ++ ++ #undef GEN_CSRXQ_CASE ++ tcg_temp_free(zero); ++ return true; ++} ++ ++#endif ++ ++static bool trans_cacop(DisasContext *ctx, arg_cacop *a) ++{ ++ /* Treat as NOP. */ ++ return true; ++} ++ ++#ifdef CONFIG_USER_ONLY ++ ++static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a) ++{ ++ return false; ++} ++ ++static bool trans_lddir(DisasContext *ctx, arg_lddir *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrrd_b(DisasContext *ctx, arg_iocsrrd_b *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrrd_h(DisasContext *ctx, arg_iocsrrd_h *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrrd_w(DisasContext *ctx, arg_iocsrrd_w *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrrd_d(DisasContext *ctx, arg_iocsrrd_d *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrwr_b(DisasContext *ctx, arg_iocsrwr_b *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrwr_h(DisasContext *ctx, arg_iocsrwr_h *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrwr_w(DisasContext *ctx, arg_iocsrwr_w *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrwr_d(DisasContext *ctx, arg_iocsrwr_d *a) ++{ ++ return false; ++} ++#else ++ ++static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a) ++{ ++ TCGv t0, t1; ++ TCGv_i32 t2; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->seq); ++ t2 = tcg_const_i32(ctx->mem_idx); ++ gen_helper_ldpte(cpu_env, t0, t1, t2); ++ ++ return true; ++} ++ ++static bool trans_lddir(DisasContext *ctx, arg_lddir *a) ++{ ++ TCGv t0, t1, t2; ++ TCGv_i32 t3; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->rd); ++ t2 = tcg_const_tl(a->level); ++ t3 = tcg_const_i32(ctx->mem_idx); ++ gen_helper_lddir(cpu_env, t0, t1, t2, t3); ++ ++ return true; ++} ++ ++static bool trans_iocsrrd_b(DisasContext *ctx, arg_iocsrrd_b *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrrd_h(DisasContext *ctx, arg_iocsrrd_h *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrrd_w(DisasContext *ctx, arg_iocsrrd_w *a) ++{ ++ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_LD_W); ++ TCGv t0, t1; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->rd); ++ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); ++ return true; ++} ++ ++static bool trans_iocsrrd_d(DisasContext *ctx, arg_iocsrrd_d *a) ++{ ++ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_LD_D); ++ TCGv t0, t1; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->rd); ++ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); ++ return true; ++} ++ ++static bool trans_iocsrwr_b(DisasContext *ctx, arg_iocsrwr_b *a) ++{ ++ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_ST_B); ++ TCGv t0, t1; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->rd); ++ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); ++ return true; ++} ++ ++static bool trans_iocsrwr_h(DisasContext *ctx, arg_iocsrwr_h *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrwr_w(DisasContext *ctx, arg_iocsrwr_w *a) ++{ ++ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_ST_W); ++ TCGv t0, t1; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->rd); ++ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); ++ return true; ++} ++ ++static bool trans_iocsrwr_d(DisasContext *ctx, arg_iocsrwr_d *a) ++{ ++ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_ST_D); ++ TCGv t0, t1; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->rd); ++ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); ++ return true; ++} ++#endif /* !CONFIG_USER_ONLY */ ++ ++ ++#ifdef CONFIG_USER_ONLY ++ ++#define GEN_FALSE_TRANS(name) \ ++static bool trans_##name(DisasContext *ctx, arg_##name * a) \ ++{ \ ++ return false; \ ++} ++ ++GEN_FALSE_TRANS(tlbclr) ++GEN_FALSE_TRANS(invtlb) ++GEN_FALSE_TRANS(tlbflush) ++GEN_FALSE_TRANS(tlbsrch) ++GEN_FALSE_TRANS(tlbrd) ++GEN_FALSE_TRANS(tlbwr) ++GEN_FALSE_TRANS(tlbfill) ++GEN_FALSE_TRANS(ertn) ++ ++#else ++ ++static bool trans_tlbclr(DisasContext *ctx, arg_tlbclr *a) ++{ ++ gen_helper_tlbclr(cpu_env); ++ return true; ++} ++ ++static bool trans_tlbflush(DisasContext *ctx, arg_tlbflush *a) ++{ ++ gen_helper_tlbflush(cpu_env); ++ return true; ++} ++ ++static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a) ++{ ++ TCGv addr = tcg_temp_new(); ++ TCGv info = tcg_temp_new(); ++ TCGv op = tcg_const_tl(a->invop); ++ ++ gen_load_gpr(addr, a->addr); ++ gen_load_gpr(info, a->info); ++ gen_helper_invtlb(cpu_env, addr, info, op); ++ ++ tcg_temp_free(addr); ++ tcg_temp_free(info); ++ tcg_temp_free(op); ++ return true; ++} ++ ++static bool trans_tlbsrch(DisasContext *ctx, arg_tlbsrch *a) ++{ ++ gen_helper_tlbsrch(cpu_env); ++ return true; ++} ++ ++static bool trans_tlbrd(DisasContext *ctx, arg_tlbrd *a) ++{ ++ gen_helper_tlbrd(cpu_env); ++ return true; ++} ++ ++static bool trans_tlbwr(DisasContext *ctx, arg_tlbwr *a) ++{ ++ gen_helper_tlbwr(cpu_env); ++ return true; ++} ++ ++static bool trans_tlbfill(DisasContext *ctx, arg_tlbfill *a) ++{ ++ gen_helper_tlbfill(cpu_env); ++ return true; ++} ++ ++static bool trans_ertn(DisasContext *ctx, arg_ertn *a) ++{ ++ gen_helper_ertn(cpu_env); ++ ctx->base.is_jmp = DISAS_EXIT; ++ return true; ++} ++ ++#endif /* CONFIG_USER_ONLY */ ++ ++static bool trans_idle(DisasContext *ctx, arg_idle *a) ++{ ++ ctx->base.pc_next += 4; ++ save_cpu_state(ctx, 1); ++ ctx->base.pc_next -= 4; ++ gen_helper_idle(cpu_env); ++ ctx->base.is_jmp = DISAS_NORETURN; ++ return true; ++} ++ ++#ifdef CONFIG_USER_ONLY ++ ++static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a) ++{ ++ /* Nop */ ++ return true; ++} ++ ++#else ++ ++static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a) ++{ ++ TCGv t0, t1; ++ t0 = tcg_const_tl(a->rd); ++ t1 = tcg_const_tl(a->rj); ++ gen_helper_drdtime(cpu_env, t0, t1); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++#endif ++ ++static bool trans_cpucfg(DisasContext *ctx, arg_cpucfg *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rj); ++ gen_helper_cpucfg(cpu_gpr[a->rd], cpu_env, t0); ++ tcg_temp_free(t0); ++ return true; ++} +diff --git a/target/loongarch64/translate.c b/target/loongarch64/translate.c +new file mode 100644 +index 0000000000..fe122e4c31 +--- /dev/null ++++ b/target/loongarch64/translate.c +@@ -0,0 +1,2892 @@ ++/* ++ * LOONGARCH emulation for QEMU - main translation routines ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++ ++#include "qemu/osdep.h" ++#include "cpu.h" ++#include "internal.h" ++#include "disas/disas.h" ++#include "exec/exec-all.h" ++#include "tcg/tcg-op.h" ++#include "exec/cpu_ldst.h" ++#include "hw/loongarch/cpudevs.h" ++ ++#include "exec/helper-proto.h" ++#include "exec/helper-gen.h" ++#include "semihosting/semihost.h" ++ ++#include "trace-tcg.h" ++#include "exec/translator.h" ++#include "exec/log.h" ++ ++#include "instmap.h" ++ ++#define LARCH_DEBUG_DISAS 0 ++ ++/* Values for the fmt field in FP instructions */ ++enum { ++ /* 0 - 15 are reserved */ ++ FMT_S = 16, /* single fp */ ++ FMT_D = 17, /* double fp */ ++}; ++ ++/* global register indices */ ++static TCGv cpu_gpr[32], cpu_PC; ++static TCGv btarget, bcond; ++static TCGv cpu_lladdr, cpu_llval; ++static TCGv_i32 hflags; ++static TCGv_i32 fpu_fcsr0; ++static TCGv_i64 fpu_f64[32]; ++ ++#include "exec/gen-icount.h" ++ ++#define gen_helper_0e0i(name, arg) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg); \ ++ gen_helper_##name(cpu_env, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++#define gen_helper_0e1i(name, arg1, arg2) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ ++ gen_helper_##name(cpu_env, arg1, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++#define gen_helper_1e0i(name, ret, arg1) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg1); \ ++ gen_helper_##name(ret, cpu_env, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++#define gen_helper_1e1i(name, ret, arg1, arg2) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ ++ gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ ++ gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ ++ gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg4); \ ++ gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++typedef struct DisasContext { ++ DisasContextBase base; ++ target_ulong saved_pc; ++ target_ulong page_start; ++ uint32_t opcode; ++ uint64_t insn_flags; ++ /* Routine used to access memory */ ++ int mem_idx; ++ MemOp default_tcg_memop_mask; ++ uint32_t hflags, saved_hflags; ++ target_ulong btarget; ++} DisasContext; ++ ++#define DISAS_STOP DISAS_TARGET_0 ++#define DISAS_EXIT DISAS_TARGET_1 ++ ++#define LOG_DISAS(...) \ ++ do { \ ++ if (LARCH_DEBUG_DISAS) { \ ++ qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \ ++ } \ ++ } while (0) ++ ++#define LARCH_INVAL(op) \ ++ do { \ ++ if (LARCH_DEBUG_DISAS) { \ ++ qemu_log_mask(CPU_LOG_TB_IN_ASM, \ ++ TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \ ++ ctx->base.pc_next, ctx->opcode, op, \ ++ ctx->opcode >> 26, ctx->opcode & 0x3F, \ ++ ((ctx->opcode >> 16) & 0x1F)); \ ++ } \ ++ } while (0) ++ ++/* General purpose registers moves. */ ++static inline void gen_load_gpr(TCGv t, int reg) ++{ ++ if (reg == 0) { ++ tcg_gen_movi_tl(t, 0); ++ } else { ++ tcg_gen_mov_tl(t, cpu_gpr[reg]); ++ } ++} ++ ++static inline void gen_store_gpr(TCGv t, int reg) ++{ ++ if (reg != 0) { ++ tcg_gen_mov_tl(cpu_gpr[reg], t); ++ } ++} ++ ++/* Moves to/from shadow registers. */ ++/* Tests */ ++static inline void gen_save_pc(target_ulong pc) ++{ ++ tcg_gen_movi_tl(cpu_PC, pc); ++} ++ ++static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) ++{ ++ LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); ++ if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { ++ gen_save_pc(ctx->base.pc_next); ++ ctx->saved_pc = ctx->base.pc_next; ++ } ++ if (ctx->hflags != ctx->saved_hflags) { ++ tcg_gen_movi_i32(hflags, ctx->hflags); ++ ctx->saved_hflags = ctx->hflags; ++ switch (ctx->hflags & LARCH_HFLAG_BMASK) { ++ case LARCH_HFLAG_BR: ++ break; ++ case LARCH_HFLAG_BC: ++ case LARCH_HFLAG_B: ++ tcg_gen_movi_tl(btarget, ctx->btarget); ++ break; ++ } ++ } ++} ++ ++static inline void restore_cpu_state(CPULOONGARCHState *env, DisasContext *ctx) ++{ ++ ctx->saved_hflags = ctx->hflags; ++ switch (ctx->hflags & LARCH_HFLAG_BMASK) { ++ case LARCH_HFLAG_BR: ++ break; ++ case LARCH_HFLAG_BC: ++ case LARCH_HFLAG_B: ++ ctx->btarget = env->btarget; ++ break; ++ } ++} ++ ++static inline void generate_exception_err(DisasContext *ctx, int excp, int err) ++{ ++ TCGv_i32 texcp = tcg_const_i32(excp); ++ TCGv_i32 terr = tcg_const_i32(err); ++ save_cpu_state(ctx, 1); ++ gen_helper_raise_exception_err(cpu_env, texcp, terr); ++ tcg_temp_free_i32(terr); ++ tcg_temp_free_i32(texcp); ++ ctx->base.is_jmp = DISAS_NORETURN; ++} ++ ++static inline void generate_exception_end(DisasContext *ctx, int excp) ++{ ++ generate_exception_err(ctx, excp, 0); ++} ++ ++/* Floating point register moves. */ ++static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) ++{ ++ tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); ++} ++ ++static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) ++{ ++ TCGv_i64 t64; ++ t64 = tcg_temp_new_i64(); ++ tcg_gen_extu_i32_i64(t64, t); ++ tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); ++ tcg_temp_free_i64(t64); ++} ++ ++static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) ++{ ++ tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); ++} ++ ++static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) ++{ ++ TCGv_i64 t64 = tcg_temp_new_i64(); ++ tcg_gen_extu_i32_i64(t64, t); ++ tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); ++ tcg_temp_free_i64(t64); ++} ++ ++static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) ++{ ++ tcg_gen_mov_i64(t, fpu_f64[reg]); ++} ++ ++static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) ++{ ++ tcg_gen_mov_i64(fpu_f64[reg], t); ++} ++ ++static inline int get_fp_bit(int cc) ++{ ++ if (cc) { ++ return 24 + cc; ++ } else { ++ return 23; ++ } ++} ++ ++/* Addresses computation */ ++static inline void gen_op_addr_add(DisasContext *ctx, ++ TCGv ret, TCGv arg0, TCGv arg1) ++{ ++ tcg_gen_add_tl(ret, arg0, arg1); ++ ++ if (ctx->hflags & LARCH_HFLAG_AWRAP) { ++ tcg_gen_ext32s_i64(ret, ret); ++ } ++} ++ ++static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, ++ target_long ofs) ++{ ++ tcg_gen_addi_tl(ret, base, ofs); ++ ++ if (ctx->hflags & LARCH_HFLAG_AWRAP) { ++ tcg_gen_ext32s_i64(ret, ret); ++ } ++} ++ ++/* Sign-extract the low 32-bits to a target_long. */ ++static inline void gen_move_low32(TCGv ret, TCGv_i64 arg) ++{ ++ tcg_gen_ext32s_i64(ret, arg); ++} ++ ++/* Sign-extract the high 32-bits to a target_long. */ ++static inline void gen_move_high32(TCGv ret, TCGv_i64 arg) ++{ ++ tcg_gen_sari_i64(ret, arg, 32); ++} ++ ++static inline void check_cp1_enabled(DisasContext *ctx) ++{ ++#ifndef CONFIG_USER_ONLY ++ if (unlikely(!(ctx->hflags & LARCH_HFLAG_FPU))) { ++ generate_exception_err(ctx, EXCP_FPDIS, 1); ++ } ++#endif ++} ++ ++static inline void check_lsx_enabled(DisasContext *ctx) ++{ ++#ifndef CONFIG_USER_ONLY ++ if (unlikely(!(ctx->hflags & LARCH_HFLAG_LSX))) { ++ generate_exception_err(ctx, EXCP_LSXDIS, 1); ++ } ++#endif ++} ++ ++static inline void check_lasx_enabled(DisasContext *ctx) ++{ ++#ifndef CONFIG_USER_ONLY ++ if (unlikely(!(ctx->hflags & LARCH_HFLAG_LASX))) { ++ generate_exception_err(ctx, EXCP_LASXDIS, 1); ++ } ++#endif ++} ++ ++static inline void check_lbt_enabled(DisasContext *ctx) ++{ ++#ifndef CONFIG_USER_ONLY ++ if (unlikely(!(ctx->hflags & LARCH_HFLAG_LBT))) { ++ generate_exception_err(ctx, EXCP_BTDIS, 1); ++ } ++#endif ++} ++ ++/* This code generates a "reserved instruction" exception if the ++ CPU does not support the instruction set corresponding to flags. */ ++static inline void check_insn(DisasContext *ctx, uint64_t flags) ++{ ++ if (unlikely(!(ctx->insn_flags & flags))) { ++ generate_exception_end(ctx, EXCP_RI); ++ } ++} ++ ++/* This code generates a "reserved instruction" exception if the ++ CPU has corresponding flag set which indicates that the instruction ++ has been removed. */ ++static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) ++{ ++ if (unlikely(ctx->insn_flags & flags)) { ++ generate_exception_end(ctx, EXCP_RI); ++ } ++} ++ ++/* ++ * The Linux kernel traps certain reserved instruction exceptions to ++ * emulate the corresponding instructions. QEMU is the kernel in user ++ * mode, so those traps are emulated by accepting the instructions. ++ * ++ * A reserved instruction exception is generated for flagged CPUs if ++ * QEMU runs in system mode. ++ */ ++static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) ++{ ++#ifndef CONFIG_USER_ONLY ++ check_insn_opc_removed(ctx, flags); ++#endif ++} ++ ++/* This code generates a "reserved instruction" exception if 64-bit ++ instructions are not enabled. */ ++static inline void check_larch_64(DisasContext *ctx) ++{ ++ if (unlikely(!(ctx->hflags & LARCH_HFLAG_64))) { ++ generate_exception_end(ctx, EXCP_RI); ++ } ++} ++ ++/* Define small wrappers for gen_load_fpr* so that we have a uniform ++ calling interface for 32 and 64-bit FPRs. No sense in changing ++ all callers for gen_load_fpr32 when we need the CTX parameter for ++ this one use. */ ++#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) ++#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) ++#define FCOP_CONDNS(fmt, ifmt, bits, STORE) \ ++static inline void gen_fcmp_ ## fmt(DisasContext *ctx, int n, \ ++ int ft, int fs, int cd) \ ++{ \ ++ TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ ++ TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ ++ TCGv_i32 fcc = tcg_const_i32(cd); \ ++ check_cp1_enabled(ctx); \ ++ gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ ++ gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ ++ switch (n) { \ ++ case 0: \ ++ gen_helper_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 1: \ ++ gen_helper_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 2: \ ++ gen_helper_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 3: \ ++ gen_helper_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 4: \ ++ gen_helper_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 5: \ ++ gen_helper_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 6: \ ++ gen_helper_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 7: \ ++ gen_helper_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 8: \ ++ gen_helper_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 9: \ ++ gen_helper_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 10: \ ++ gen_helper_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 11: \ ++ gen_helper_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 12: \ ++ gen_helper_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 13: \ ++ gen_helper_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 14: \ ++ gen_helper_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 15: \ ++ gen_helper_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 16: \ ++ gen_helper_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 17: \ ++ gen_helper_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 20: \ ++ gen_helper_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 21: \ ++ gen_helper_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 24: \ ++ gen_helper_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 25: \ ++ gen_helper_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ default: \ ++ abort(); \ ++ } \ ++ STORE; \ ++ tcg_temp_free_i ## bits(fp0); \ ++ tcg_temp_free_i ## bits(fp1); \ ++ tcg_temp_free_i32(fcc); \ ++} ++ ++FCOP_CONDNS(d, FMT_D, 64, gen_helper_movreg2cf_i64(cpu_env, fcc, fp0)) ++FCOP_CONDNS(s, FMT_S, 32, gen_helper_movreg2cf_i32(cpu_env, fcc, fp0)) ++#undef FCOP_CONDNS ++#undef gen_ldcmp_fpr32 ++#undef gen_ldcmp_fpr64 ++ ++/* load/store instructions. */ ++#ifdef CONFIG_USER_ONLY ++#define OP_LD_ATOMIC(insn, fname) \ ++static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ ++ DisasContext *ctx) \ ++{ \ ++ TCGv t0 = tcg_temp_new(); \ ++ tcg_gen_mov_tl(t0, arg1); \ ++ tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ ++ tcg_gen_st_tl(t0, cpu_env, \ ++ offsetof(CPULOONGARCHState, lladdr)); \ ++ tcg_gen_st_tl(ret, cpu_env, \ ++ offsetof(CPULOONGARCHState, llval)); \ ++ tcg_temp_free(t0); \ ++} ++#else ++#define OP_LD_ATOMIC(insn, fname) \ ++static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ ++ DisasContext *ctx) \ ++{ \ ++ gen_helper_1e1i(insn, ret, arg1, mem_idx); \ ++} ++#endif ++#if 0 ++OP_LD_ATOMIC(ll, ld32s); ++OP_LD_ATOMIC(lld, ld64); ++#endif ++#undef OP_LD_ATOMIC ++ ++static void gen_base_offset_addr(DisasContext *ctx, TCGv addr, ++ int base, int offset) ++{ ++ if (base == 0) { ++ tcg_gen_movi_tl(addr, offset); ++ } else if (offset == 0) { ++ gen_load_gpr(addr, base); ++ } else { ++ tcg_gen_movi_tl(addr, offset); ++ gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); ++ } ++} ++ ++/* Load */ ++static void gen_ld(DisasContext *ctx, uint32_t opc, ++ int rt, int base, int offset) ++{ ++ TCGv t0; ++ int mem_idx = ctx->mem_idx; ++ ++ t0 = tcg_temp_new(); ++ gen_base_offset_addr(ctx, t0, base, offset); ++ ++ switch (opc) { ++ case OPC_LARCH_LD_WU: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LDPTR_D: ++ case OPC_LARCH_LD_D: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LL_D: ++#if 0 ++ op_ld_lld(t0, t0, mem_idx, ctx); ++#endif ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LDPTR_W: ++ case OPC_LARCH_LD_W: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LD_H: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LD_HU: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LD_B: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LD_BU: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LL_W: ++#if 0 ++ op_ld_ll(t0, t0, mem_idx, ctx); ++#endif ++ gen_store_gpr(t0, rt); ++ break; ++ } ++ ++ tcg_temp_free(t0); ++} ++ ++/* Store */ ++static void gen_st(DisasContext *ctx, uint32_t opc, int rt, ++ int base, int offset) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_base_offset_addr(ctx, t0, base, offset); ++ gen_load_gpr(t1, rt); ++ ++ switch (opc) { ++ case OPC_LARCH_STPTR_D: ++ case OPC_LARCH_ST_D: ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ | ++ ctx->default_tcg_memop_mask); ++ break; ++ case OPC_LARCH_STPTR_W: ++ case OPC_LARCH_ST_W: ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | ++ ctx->default_tcg_memop_mask); ++ break; ++ case OPC_LARCH_ST_H: ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | ++ ctx->default_tcg_memop_mask); ++ break; ++ case OPC_LARCH_ST_B: ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); ++ break; ++ } ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++} ++ ++/* Store conditional */ ++static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, ++ MemOp tcg_mo, bool eva) ++{ ++ TCGv addr, t0, val; ++ TCGLabel *l1 = gen_new_label(); ++ TCGLabel *done = gen_new_label(); ++ ++ t0 = tcg_temp_new(); ++ addr = tcg_temp_new(); ++ /* compare the address against that of the preceeding LL */ ++ gen_base_offset_addr(ctx, addr, base, offset); ++ tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); ++ tcg_temp_free(addr); ++ tcg_gen_movi_tl(t0, 0); ++ gen_store_gpr(t0, rt); ++ tcg_gen_br(done); ++ ++ gen_set_label(l1); ++ /* generate cmpxchg */ ++ val = tcg_temp_new(); ++ gen_load_gpr(val, rt); ++ tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, ++ eva ? LARCH_HFLAG_UM : ctx->mem_idx, tcg_mo); ++ tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); ++ gen_store_gpr(t0, rt); ++ tcg_temp_free(val); ++ ++ gen_set_label(done); ++ tcg_temp_free(t0); ++} ++ ++/* Load and store */ ++static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, ++ TCGv t0) ++{ ++ /* Don't do NOP if destination is zero: we must perform the actual ++ memory access. */ ++ switch (opc) { ++ case OPC_LARCH_FLD_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | ++ ctx->default_tcg_memop_mask); ++ gen_store_fpr32(ctx, fp0, ft); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FST_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, ft); ++ tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | ++ ctx->default_tcg_memop_mask); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FLD_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ | ++ ctx->default_tcg_memop_mask); ++ gen_store_fpr64(ctx, fp0, ft); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FST_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, ft); ++ tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ | ++ ctx->default_tcg_memop_mask); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ default: ++ LARCH_INVAL("flt_ldst"); ++ generate_exception_end(ctx, EXCP_RI); ++ break; ++ } ++} ++ ++static void gen_fp_ldst(DisasContext *ctx, uint32_t op, int rt, ++ int rs, int16_t imm) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ check_cp1_enabled(ctx); ++ gen_base_offset_addr(ctx, t0, rs, imm); ++ gen_flt_ldst(ctx, op, rt, t0); ++ tcg_temp_free(t0); ++} ++ ++/* Arithmetic with immediate operand */ ++static void gen_arith_imm(DisasContext *ctx, uint32_t opc, ++ int rt, int rs, int imm) ++{ ++ target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ ++ ++ if (rt == 0) { ++ /* If no destination, treat it as a NOP. ++ For addi, we must generate the overflow exception when needed. */ ++ return; ++ } ++ switch (opc) { ++ case OPC_LARCH_ADDI_W: ++ if (rs != 0) { ++ tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); ++ tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rt], uimm); ++ } ++ break; ++ case OPC_LARCH_ADDI_D: ++ if (rs != 0) { ++ tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rt], uimm); ++ } ++ break; ++ } ++} ++ ++/* Logic with immediate operand */ ++static void gen_logic_imm(DisasContext *ctx, uint32_t opc, ++ int rt, int rs, int16_t imm) ++{ ++ target_ulong uimm; ++ ++ if (rt == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ uimm = (uint16_t)imm; ++ switch (opc) { ++ case OPC_LARCH_ANDI: ++ if (likely(rs != 0)) { ++ tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rt], 0); ++ } ++ break; ++ case OPC_LARCH_ORI: ++ if (rs != 0) { ++ tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rt], uimm); ++ } ++ break; ++ case OPC_LARCH_XORI: ++ if (likely(rs != 0)) { ++ tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rt], uimm); ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++/* Set on less than with immediate operand */ ++static void gen_slt_imm(DisasContext *ctx, uint32_t opc, ++ int rt, int rs, int16_t imm) ++{ ++ target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ ++ TCGv t0; ++ ++ if (rt == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, rs); ++ switch (opc) { ++ case OPC_LARCH_SLTI: ++ tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); ++ break; ++ case OPC_LARCH_SLTIU: ++ tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); ++ break; ++ } ++ tcg_temp_free(t0); ++} ++ ++/* Shifts with immediate operand */ ++static void gen_shift_imm(DisasContext *ctx, uint32_t opc, ++ int rt, int rs, int16_t imm) ++{ ++ target_ulong uimm = ((uint16_t)imm) & 0x1f; ++ TCGv t0; ++ ++ if (rt == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, rs); ++ switch (opc) { ++ case OPC_LARCH_SRAI_W: ++ tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); ++ break; ++ case OPC_LARCH_SRLI_W: ++ if (uimm != 0) { ++ tcg_gen_ext32u_tl(t0, t0); ++ tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); ++ } else { ++ tcg_gen_ext32s_tl(cpu_gpr[rt], t0); ++ } ++ break; ++ case OPC_LARCH_ROTRI_W: ++ if (uimm != 0) { ++ TCGv_i32 t1 = tcg_temp_new_i32(); ++ ++ tcg_gen_trunc_tl_i32(t1, t0); ++ tcg_gen_rotri_i32(t1, t1, uimm); ++ tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); ++ tcg_temp_free_i32(t1); ++ } else { ++ tcg_gen_ext32s_tl(cpu_gpr[rt], t0); ++ } ++ break; ++ } ++ tcg_temp_free(t0); ++} ++ ++/* Arithmetic */ ++static void gen_arith(DisasContext *ctx, uint32_t opc, ++ int rd, int rs, int rt) ++{ ++ if (rd == 0) { ++ /* If no destination, treat it as a NOP. ++ For add & sub, we must generate the ++ overflow exception when needed. */ ++ return; ++ } ++ ++ switch (opc) { ++ case OPC_LARCH_ADD_W: ++ if (rs != 0 && rt != 0) { ++ tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ case OPC_LARCH_SUB_W: ++ if (rs != 0 && rt != 0) { ++ tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ case OPC_LARCH_ADD_D: ++ if (rs != 0 && rt != 0) { ++ tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ case OPC_LARCH_SUB_D: ++ if (rs != 0 && rt != 0) { ++ tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ } ++} ++ ++/* Conditional move */ ++static void gen_cond_move(DisasContext *ctx, uint32_t opc, ++ int rd, int rs, int rt) ++{ ++ TCGv t0, t1, t2; ++ ++ if (rd == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, rt); ++ t1 = tcg_const_tl(0); ++ t2 = tcg_temp_new(); ++ gen_load_gpr(t2, rs); ++ switch (opc) { ++ case OPC_LARCH_MASKEQZ: ++ tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); ++ break; ++ case OPC_LARCH_MASKNEZ: ++ tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); ++ break; ++ } ++ tcg_temp_free(t2); ++ tcg_temp_free(t1); ++ tcg_temp_free(t0); ++} ++ ++/* Logic */ ++static void gen_logic(DisasContext *ctx, uint32_t opc, ++ int rd, int rs, int rt) ++{ ++ if (rd == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ ++ switch (opc) { ++ case OPC_LARCH_AND: ++ if (likely(rs != 0 && rt != 0)) { ++ tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ case OPC_LARCH_NOR: ++ if (rs != 0 && rt != 0) { ++ tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); ++ } ++ break; ++ case OPC_LARCH_OR: ++ if (likely(rs != 0 && rt != 0)) { ++ tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ case OPC_LARCH_XOR: ++ if (likely(rs != 0 && rt != 0)) { ++ tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ } ++} ++ ++/* Set on lower than */ ++static void gen_slt(DisasContext *ctx, uint32_t opc, ++ int rd, int rs, int rt) ++{ ++ TCGv t0, t1; ++ ++ if (rd == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ gen_load_gpr(t0, rs); ++ gen_load_gpr(t1, rt); ++ switch (opc) { ++ case OPC_LARCH_SLT: ++ tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); ++ break; ++ case OPC_LARCH_SLTU: ++ tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); ++ break; ++ } ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++} ++ ++/* Shifts */ ++static void gen_shift(DisasContext *ctx, uint32_t opc, ++ int rd, int rs, int rt) ++{ ++ TCGv t0, t1; ++ ++ if (rd == 0) { ++ /* If no destination, treat it as a NOP. ++ For add & sub, we must generate the ++ overflow exception when needed. */ ++ return; ++ } ++ ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ gen_load_gpr(t0, rs); ++ gen_load_gpr(t1, rt); ++ switch (opc) { ++ case OPC_LARCH_SLL_W: ++ tcg_gen_andi_tl(t0, t0, 0x1f); ++ tcg_gen_shl_tl(t0, t1, t0); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); ++ break; ++ case OPC_LARCH_SRA_W: ++ tcg_gen_andi_tl(t0, t0, 0x1f); ++ tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); ++ break; ++ case OPC_LARCH_SRL_W: ++ tcg_gen_ext32u_tl(t1, t1); ++ tcg_gen_andi_tl(t0, t0, 0x1f); ++ tcg_gen_shr_tl(t0, t1, t0); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); ++ break; ++ case OPC_LARCH_ROTR_W: ++ { ++ TCGv_i32 t2 = tcg_temp_new_i32(); ++ TCGv_i32 t3 = tcg_temp_new_i32(); ++ ++ tcg_gen_trunc_tl_i32(t2, t0); ++ tcg_gen_trunc_tl_i32(t3, t1); ++ tcg_gen_andi_i32(t2, t2, 0x1f); ++ tcg_gen_rotr_i32(t2, t3, t2); ++ tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); ++ tcg_temp_free_i32(t2); ++ tcg_temp_free_i32(t3); ++ } ++ break; ++ case OPC_LARCH_SLL_D: ++ tcg_gen_andi_tl(t0, t0, 0x3f); ++ tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); ++ break; ++ case OPC_LARCH_SRA_D: ++ tcg_gen_andi_tl(t0, t0, 0x3f); ++ tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); ++ break; ++ case OPC_LARCH_SRL_D: ++ tcg_gen_andi_tl(t0, t0, 0x3f); ++ tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); ++ break; ++ case OPC_LARCH_ROTR_D: ++ tcg_gen_andi_tl(t0, t0, 0x3f); ++ tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); ++ break; ++ } ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++} ++ ++static inline void gen_r6_ld(target_long addr, int reg, int memidx, ++ MemOp memop) ++{ ++ TCGv t0 = tcg_const_tl(addr); ++ tcg_gen_qemu_ld_tl(t0, t0, memidx, memop); ++ gen_store_gpr(t0, reg); ++ tcg_temp_free(t0); ++} ++ ++static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) ++{ ++ TCGv t0, t1; ++ ++ if (rd == 0) { ++ /* Treat as NOP. */ ++ return; ++ } ++ ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, rs); ++ gen_load_gpr(t1, rt); ++ ++ switch (opc) { ++ case OPC_LARCH_DIV_W: ++ { ++ TCGv t2 = tcg_temp_new(); ++ TCGv t3 = tcg_temp_new(); ++ tcg_gen_ext32s_tl(t0, t0); ++ tcg_gen_ext32s_tl(t1, t1); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); ++ tcg_gen_and_tl(t2, t2, t3); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); ++ tcg_gen_or_tl(t2, t2, t3); ++ tcg_gen_movi_tl(t3, 0); ++ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); ++ tcg_gen_div_tl(cpu_gpr[rd], t0, t1); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MOD_W: ++ { ++ TCGv t2 = tcg_temp_new(); ++ TCGv t3 = tcg_temp_new(); ++ tcg_gen_ext32s_tl(t0, t0); ++ tcg_gen_ext32s_tl(t1, t1); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); ++ tcg_gen_and_tl(t2, t2, t3); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); ++ tcg_gen_or_tl(t2, t2, t3); ++ tcg_gen_movi_tl(t3, 0); ++ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); ++ tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_DIV_WU: ++ { ++ TCGv t2 = tcg_const_tl(0); ++ TCGv t3 = tcg_const_tl(1); ++ tcg_gen_ext32u_tl(t0, t0); ++ tcg_gen_ext32u_tl(t1, t1); ++ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); ++ tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MOD_WU: ++ { ++ TCGv t2 = tcg_const_tl(0); ++ TCGv t3 = tcg_const_tl(1); ++ tcg_gen_ext32u_tl(t0, t0); ++ tcg_gen_ext32u_tl(t1, t1); ++ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); ++ tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MUL_W: ++ { ++ TCGv_i32 t2 = tcg_temp_new_i32(); ++ TCGv_i32 t3 = tcg_temp_new_i32(); ++ tcg_gen_trunc_tl_i32(t2, t0); ++ tcg_gen_trunc_tl_i32(t3, t1); ++ tcg_gen_mul_i32(t2, t2, t3); ++ tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); ++ tcg_temp_free_i32(t2); ++ tcg_temp_free_i32(t3); ++ } ++ break; ++ case OPC_LARCH_MULH_W: ++ { ++ TCGv_i32 t2 = tcg_temp_new_i32(); ++ TCGv_i32 t3 = tcg_temp_new_i32(); ++ tcg_gen_trunc_tl_i32(t2, t0); ++ tcg_gen_trunc_tl_i32(t3, t1); ++ tcg_gen_muls2_i32(t2, t3, t2, t3); ++ tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); ++ tcg_temp_free_i32(t2); ++ tcg_temp_free_i32(t3); ++ } ++ break; ++ case OPC_LARCH_MULH_WU: ++ { ++ TCGv_i32 t2 = tcg_temp_new_i32(); ++ TCGv_i32 t3 = tcg_temp_new_i32(); ++ tcg_gen_trunc_tl_i32(t2, t0); ++ tcg_gen_trunc_tl_i32(t3, t1); ++ tcg_gen_mulu2_i32(t2, t3, t2, t3); ++ tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); ++ tcg_temp_free_i32(t2); ++ tcg_temp_free_i32(t3); ++ } ++ break; ++ case OPC_LARCH_DIV_D: ++ { ++ TCGv t2 = tcg_temp_new(); ++ TCGv t3 = tcg_temp_new(); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); ++ tcg_gen_and_tl(t2, t2, t3); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); ++ tcg_gen_or_tl(t2, t2, t3); ++ tcg_gen_movi_tl(t3, 0); ++ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); ++ tcg_gen_div_tl(cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MOD_D: ++ { ++ TCGv t2 = tcg_temp_new(); ++ TCGv t3 = tcg_temp_new(); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); ++ tcg_gen_and_tl(t2, t2, t3); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); ++ tcg_gen_or_tl(t2, t2, t3); ++ tcg_gen_movi_tl(t3, 0); ++ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); ++ tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_DIV_DU: ++ { ++ TCGv t2 = tcg_const_tl(0); ++ TCGv t3 = tcg_const_tl(1); ++ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); ++ tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MOD_DU: ++ { ++ TCGv t2 = tcg_const_tl(0); ++ TCGv t3 = tcg_const_tl(1); ++ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); ++ tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MUL_D: ++ tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); ++ break; ++ case OPC_LARCH_MULH_D: ++ { ++ TCGv t2 = tcg_temp_new(); ++ tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MULH_DU: ++ { ++ TCGv t2 = tcg_temp_new(); ++ tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t2); ++ } ++ break; ++ default: ++ LARCH_INVAL("r6 mul/div"); ++ generate_exception_end(ctx, EXCP_RI); ++ goto out; ++ } ++ out: ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++} ++ ++static void gen_cl(DisasContext *ctx, uint32_t opc, ++ int rd, int rs) ++{ ++ TCGv t0; ++ ++ if (rd == 0) { ++ /* Treat as NOP. */ ++ return; ++ } ++ t0 = cpu_gpr[rd]; ++ gen_load_gpr(t0, rs); ++ ++ switch (opc) { ++ case OPC_LARCH_CLO_W: ++ case OPC_LARCH_CLO_D: ++ tcg_gen_not_tl(t0, t0); ++ break; ++ } ++ ++ switch (opc) { ++ case OPC_LARCH_CLO_W: ++ case OPC_LARCH_CLZ_W: ++ tcg_gen_ext32u_tl(t0, t0); ++ tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); ++ tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); ++ break; ++ case OPC_LARCH_CLO_D: ++ case OPC_LARCH_CLZ_D: ++ tcg_gen_clzi_i64(t0, t0, 64); ++ break; ++ } ++} ++ ++static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) ++{ ++ if (unlikely(ctx->base.singlestep_enabled)) { ++ return false; ++ } ++ ++#ifndef CONFIG_USER_ONLY ++ return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); ++#else ++ return true; ++#endif ++} ++ ++static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) ++{ ++ if (use_goto_tb(ctx, dest)) { ++ tcg_gen_goto_tb(n); ++ gen_save_pc(dest); ++ tcg_gen_exit_tb(ctx->base.tb, n); ++ } else { ++ gen_save_pc(dest); ++ if (ctx->base.singlestep_enabled) { ++ save_cpu_state(ctx, 0); ++ gen_helper_raise_exception_debug(cpu_env); ++ } ++ tcg_gen_lookup_and_goto_ptr(); ++ } ++} ++ ++/* Branches */ ++static void gen_compute_branch(DisasContext *ctx, uint32_t opc, ++ int insn_bytes, ++ int rs, int rt, int32_t offset) ++{ ++ target_ulong btgt = -1; ++ int bcond_compute = 0; ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ ++ if (ctx->hflags & LARCH_HFLAG_BMASK) { ++#ifdef LARCH_DEBUG_DISAS ++ LOG_DISAS("Branch at PC 0x" ++ TARGET_FMT_lx "\n", ctx->base.pc_next); ++#endif ++ generate_exception_end(ctx, EXCP_RI); ++ goto out; ++ } ++ ++ /* Load needed operands */ ++ switch (opc) { ++ case OPC_LARCH_BLT: ++ case OPC_LARCH_BGE: ++ case OPC_LARCH_BLTU: ++ case OPC_LARCH_BGEU: ++ gen_load_gpr(t0, rs); ++ gen_load_gpr(t1, rt); ++ bcond_compute = 1; ++ btgt = ctx->base.pc_next + offset; ++ break; ++ case OPC_LARCH_BEQZ: ++ case OPC_LARCH_B: ++ case OPC_LARCH_BEQ: ++ case OPC_LARCH_BNEZ: ++ case OPC_LARCH_BNE: ++ /* Compare two registers */ ++ if (rs != rt) { ++ gen_load_gpr(t0, rs); ++ gen_load_gpr(t1, rt); ++ bcond_compute = 1; ++ } ++ btgt = ctx->base.pc_next + offset; ++ break; ++ default: ++ LARCH_INVAL("branch/jump"); ++ generate_exception_end(ctx, EXCP_RI); ++ goto out; ++ } ++ if (bcond_compute == 0) { ++ /* No condition to be computed */ ++ switch (opc) { ++ case OPC_LARCH_BEQZ: /* rx == rx */ ++ case OPC_LARCH_B: ++ case OPC_LARCH_BEQ: ++ /* Always take */ ++ ctx->hflags |= LARCH_HFLAG_B; ++ break; ++ case OPC_LARCH_BNEZ: ++ case OPC_LARCH_BNE: ++ /* Treat as NOP. */ ++ goto out; ++ default: ++ LARCH_INVAL("branch/jump"); ++ generate_exception_end(ctx, EXCP_RI); ++ goto out; ++ } ++ } else { ++ switch (opc) { ++ case OPC_LARCH_BLT: ++ tcg_gen_setcond_tl(TCG_COND_LT, bcond, t0, t1); ++ goto not_likely; ++ case OPC_LARCH_BGE: ++ tcg_gen_setcond_tl(TCG_COND_GE, bcond, t0, t1); ++ goto not_likely; ++ case OPC_LARCH_BLTU: ++ tcg_gen_setcond_tl(TCG_COND_LTU, bcond, t0, t1); ++ goto not_likely; ++ case OPC_LARCH_BGEU: ++ tcg_gen_setcond_tl(TCG_COND_GEU, bcond, t0, t1); ++ goto not_likely; ++ case OPC_LARCH_BEQZ: ++ case OPC_LARCH_B: ++ case OPC_LARCH_BEQ: ++ tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); ++ goto not_likely; ++ case OPC_LARCH_BNEZ: ++ case OPC_LARCH_BNE: ++ tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); ++ goto not_likely; ++ not_likely: ++ ctx->hflags |= LARCH_HFLAG_BC; ++ break; ++ default: ++ LARCH_INVAL("conditional branch/jump"); ++ generate_exception_end(ctx, EXCP_RI); ++ goto out; ++ } ++ } ++ ++ ctx->btarget = btgt; ++ ++ out: ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++} ++ ++/* special3 bitfield operations */ ++static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, ++ int rs, int lsb, int msb) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ ++ gen_load_gpr(t1, rs); ++ switch (opc) { ++ case OPC_LARCH_TRPICK_W: ++ if (lsb + msb > 31) { ++ goto fail; ++ } ++ if (msb != 31) { ++ tcg_gen_extract_tl(t0, t1, lsb, msb + 1); ++ } else { ++ /* ++ * The two checks together imply that lsb == 0, ++ * so this is a simple sign-extension. ++ */ ++ tcg_gen_ext32s_tl(t0, t1); ++ } ++ break; ++ case OPC_LARCH_TRINS_W: ++ if (lsb > msb) { ++ goto fail; ++ } ++ gen_load_gpr(t0, rt); ++ tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); ++ tcg_gen_ext32s_tl(t0, t0); ++ break; ++ default: ++fail: ++ LARCH_INVAL("bitops"); ++ generate_exception_end(ctx, EXCP_RI); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return; ++ } ++ gen_store_gpr(t0, rt); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++} ++ ++static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) ++{ ++ TCGv t0; ++ ++ if (rd == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, rt); ++ switch (op2) { ++ case OPC_LARCH_REVB_2H: ++ { ++ TCGv t1 = tcg_temp_new(); ++ TCGv t2 = tcg_const_tl(0x00FF00FF); ++ ++ tcg_gen_shri_tl(t1, t0, 8); ++ tcg_gen_and_tl(t1, t1, t2); ++ tcg_gen_and_tl(t0, t0, t2); ++ tcg_gen_shli_tl(t0, t0, 8); ++ tcg_gen_or_tl(t0, t0, t1); ++ tcg_temp_free(t2); ++ tcg_temp_free(t1); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); ++ } ++ break; ++ case OPC_LARCH_EXT_WB: ++ tcg_gen_ext8s_tl(cpu_gpr[rd], t0); ++ break; ++ case OPC_LARCH_EXT_WH: ++ tcg_gen_ext16s_tl(cpu_gpr[rd], t0); ++ break; ++ case OPC_LARCH_REVB_4H: ++ { ++ TCGv t1 = tcg_temp_new(); ++ TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL); ++ ++ tcg_gen_shri_tl(t1, t0, 8); ++ tcg_gen_and_tl(t1, t1, t2); ++ tcg_gen_and_tl(t0, t0, t2); ++ tcg_gen_shli_tl(t0, t0, 8); ++ tcg_gen_or_tl(cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t2); ++ tcg_temp_free(t1); ++ } ++ break; ++ case OPC_LARCH_REVH_D: ++ { ++ TCGv t1 = tcg_temp_new(); ++ TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL); ++ ++ tcg_gen_shri_tl(t1, t0, 16); ++ tcg_gen_and_tl(t1, t1, t2); ++ tcg_gen_and_tl(t0, t0, t2); ++ tcg_gen_shli_tl(t0, t0, 16); ++ tcg_gen_or_tl(t0, t0, t1); ++ tcg_gen_shri_tl(t1, t0, 32); ++ tcg_gen_shli_tl(t0, t0, 32); ++ tcg_gen_or_tl(cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t2); ++ tcg_temp_free(t1); ++ } ++ break; ++ default: ++ LARCH_INVAL("bsfhl"); ++ generate_exception_end(ctx, EXCP_RI); ++ tcg_temp_free(t0); ++ return; ++ } ++ tcg_temp_free(t0); ++} ++ ++/* REV with sf==1, opcode==3 ("REV64") */ ++static void handle_rev64(DisasContext *ctx, ++ unsigned int rn, unsigned int rd) ++{ ++ tcg_gen_bswap64_i64(cpu_gpr[rd], cpu_gpr[rn]); ++} ++ ++/* REV with sf==0, opcode==2 ++ * REV32 (sf==1, opcode==2) ++ */ ++static void handle_rev32(DisasContext *ctx, ++ unsigned int rn, unsigned int rd) ++{ ++ TCGv_i64 tcg_rd = tcg_temp_new_i64(); ++ gen_load_gpr(tcg_rd, rd); ++ ++ TCGv_i64 tcg_tmp = tcg_temp_new_i64(); ++ TCGv_i64 tcg_rn = tcg_temp_new_i64(); ++ gen_load_gpr(tcg_rn, rn); ++ ++ /* bswap32_i64 requires zero high word */ ++ tcg_gen_ext32u_i64(tcg_tmp, tcg_rn); ++ tcg_gen_bswap32_i64(tcg_rd, tcg_tmp, TCG_BSWAP_OZ); ++ tcg_gen_shri_i64(tcg_tmp, tcg_rn, 32); ++ tcg_gen_bswap32_i64(tcg_tmp, tcg_tmp, TCG_BSWAP_OZ); ++ tcg_gen_concat32_i64(cpu_gpr[rd], tcg_rd, tcg_tmp); ++ ++ tcg_temp_free_i64(tcg_tmp); ++ tcg_temp_free_i64(tcg_rd); ++ tcg_temp_free_i64(tcg_rn); ++} ++ ++/* REV16 */ ++static void handle_rev16(DisasContext *ctx, unsigned int rn, unsigned int rd) ++{ ++ TCGv_i64 tcg_rd = tcg_temp_new_i64(); ++ TCGv_i64 tcg_rn = tcg_temp_new_i64(); ++ gen_load_gpr(tcg_rd, rd); ++ gen_load_gpr(tcg_rn, rn); ++ TCGv_i64 tcg_tmp = tcg_temp_new_i64(); ++ TCGv_i64 mask = tcg_const_i64(0x0000ffff0000ffffull); ++ ++ tcg_gen_shri_i64(tcg_tmp, tcg_rn, 16); ++ tcg_gen_and_i64(tcg_rd, tcg_rn, mask); ++ tcg_gen_and_i64(tcg_tmp, tcg_tmp, mask); ++ tcg_gen_shli_i64(tcg_rd, tcg_rd, 16); ++ tcg_gen_or_i64(cpu_gpr[rd], tcg_rd, tcg_tmp); ++ ++ tcg_temp_free_i64(mask); ++ tcg_temp_free_i64(tcg_tmp); ++ tcg_temp_free_i64(tcg_rd); ++ tcg_temp_free_i64(tcg_rn); ++} ++ ++static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt, ++ int imm2) ++{ ++ TCGv t0; ++ TCGv t1; ++ if (rd == 0) { ++ /* Treat as NOP. */ ++ return; ++ } ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ gen_load_gpr(t0, rs); ++ gen_load_gpr(t1, rt); ++ tcg_gen_shli_tl(t0, t0, imm2 + 1); ++ tcg_gen_add_tl(cpu_gpr[rd], t0, t1); ++ if (opc == OPC_LARCH_ALSL_W) { ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ } ++ ++ tcg_temp_free(t1); ++ tcg_temp_free(t0); ++ ++ return; ++} ++ ++static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, ++ int rt, int bits) ++{ ++ TCGv t0; ++ if (rd == 0) { ++ /* Treat as NOP. */ ++ return; ++ } ++ t0 = tcg_temp_new(); ++ if (bits == 0 || bits == wordsz) { ++ if (bits == 0) { ++ gen_load_gpr(t0, rt); ++ } else { ++ gen_load_gpr(t0, rs); ++ } ++ switch (wordsz) { ++ case 32: ++ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); ++ break; ++ case 64: ++ tcg_gen_mov_tl(cpu_gpr[rd], t0); ++ break; ++ } ++ } else { ++ TCGv t1 = tcg_temp_new(); ++ gen_load_gpr(t0, rt); ++ gen_load_gpr(t1, rs); ++ switch (wordsz) { ++ case 32: ++ { ++ TCGv_i64 t2 = tcg_temp_new_i64(); ++ tcg_gen_concat_tl_i64(t2, t1, t0); ++ tcg_gen_shri_i64(t2, t2, 32 - bits); ++ gen_move_low32(cpu_gpr[rd], t2); ++ tcg_temp_free_i64(t2); ++ } ++ break; ++ case 64: ++ tcg_gen_shli_tl(t0, t0, bits); ++ tcg_gen_shri_tl(t1, t1, 64 - bits); ++ tcg_gen_or_tl(cpu_gpr[rd], t1, t0); ++ break; ++ } ++ tcg_temp_free(t1); ++ } ++ ++ tcg_temp_free(t0); ++} ++ ++static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, ++ int bp) ++{ ++ gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); ++} ++ ++static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) ++{ ++ TCGv t0; ++ if (rd == 0) { ++ /* Treat as NOP. */ ++ return; ++ } ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, rt); ++ switch (opc) { ++ case OPC_LARCH_BREV_4B: ++ gen_helper_bitswap(cpu_gpr[rd], t0); ++ break; ++ case OPC_LARCH_BREV_8B: ++ gen_helper_dbitswap(cpu_gpr[rd], t0); ++ break; ++ } ++ tcg_temp_free(t0); ++} ++ ++static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) ++{ ++ TCGv t0 = tcg_temp_new(); ++ check_cp1_enabled(ctx); ++ ++ switch (opc) { ++ case OPC_LARCH_FR2GR_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ tcg_gen_ext_i32_tl(t0, fp0); ++ tcg_temp_free_i32(fp0); ++ } ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_GR2FR_W: ++ gen_load_gpr(t0, rt); ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ tcg_gen_trunc_tl_i32(fp0, t0); ++ gen_store_fpr32(ctx, fp0, fs); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FR2GR_D: ++ gen_load_fpr64(ctx, t0, fs); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_GR2FR_D: ++ gen_load_gpr(t0, rt); ++ gen_store_fpr64(ctx, t0, fs); ++ break; ++ case OPC_LARCH_FRH2GR_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32h(ctx, fp0, fs); ++ tcg_gen_ext_i32_tl(t0, fp0); ++ tcg_temp_free_i32(fp0); ++ } ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_GR2FRH_W: ++ gen_load_gpr(t0, rt); ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ tcg_gen_trunc_tl_i32(fp0, t0); ++ gen_store_fpr32h(ctx, fp0, fs); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ default: ++ LARCH_INVAL("cp1 move"); ++ generate_exception_end(ctx, EXCP_RI); ++ goto out; ++ } ++ ++ out: ++ tcg_temp_free(t0); ++} ++ ++static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, ++ int cc, int tf) ++{ ++ int cond; ++ TCGv_i32 t0 = tcg_temp_new_i32(); ++ TCGLabel *l1 = gen_new_label(); ++ TCGLabel *l2 = gen_new_label(); ++ ++ if (tf) { ++ cond = TCG_COND_EQ; ++ } else { ++ cond = TCG_COND_NE; ++ } ++ ++ tcg_gen_andi_i32(t0, fpu_fcsr0, 1 << get_fp_bit(cc)); ++ tcg_gen_brcondi_i32(cond, t0, 0, l1); ++ gen_load_fpr32(ctx, t0, fs); ++ gen_store_fpr32(ctx, t0, fd); ++ gen_set_label(l1); ++ ++ tcg_gen_andi_i32(t0, fpu_fcsr0, 1 << get_fp_bit(cc + 1)); ++ tcg_gen_brcondi_i32(cond, t0, 0, l2); ++ gen_load_fpr32h(ctx, t0, fs); ++ gen_store_fpr32h(ctx, t0, fd); ++ tcg_temp_free_i32(t0); ++ gen_set_label(l2); ++} ++ ++static void gen_farith(DisasContext *ctx, uint32_t opc, ++ int ft, int fs, int fd, int cc) ++{ ++ check_cp1_enabled(ctx); ++ switch (opc) { ++ case OPC_LARCH_FADD_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i32(fp1); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FSUB_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i32(fp1); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FMUL_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i32(fp1); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FDIV_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i32(fp1); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FSQRT_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_sqrt_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FABS_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_abs_s(fp0, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FMOV_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FNEG_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_chs_s(fp0, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRNE_L_S: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_round_l_s(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FTINTRZ_L_S: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_trunc_l_s(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FTINTRP_L_S: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_ceil_l_s(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FTINTRM_L_S: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_floor_l_s(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FTINTRNE_W_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_round_w_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRZ_W_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_trunc_w_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRP_W_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_ceil_w_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRM_W_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_floor_w_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FRECIP_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_recip_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FRSQRT_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FRINT_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_rint_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FCLASS_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_class_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FMIN_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ TCGv_i32 fp2 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_min_s(fp2, cpu_env, fp0, fp1); ++ gen_store_fpr32(ctx, fp2, fd); ++ tcg_temp_free_i32(fp2); ++ tcg_temp_free_i32(fp1); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FMINA_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ TCGv_i32 fp2 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1); ++ gen_store_fpr32(ctx, fp2, fd); ++ tcg_temp_free_i32(fp2); ++ tcg_temp_free_i32(fp1); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FMAX_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_max_s(fp1, cpu_env, fp0, fp1); ++ gen_store_fpr32(ctx, fp1, fd); ++ tcg_temp_free_i32(fp1); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FMAXA_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1); ++ gen_store_fpr32(ctx, fp1, fd); ++ tcg_temp_free_i32(fp1); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FCVT_D_S: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_cvtd_s(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FTINT_W_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_cvt_w_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINT_L_S: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_cvt_l_s(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FADD_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i64(fp1); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FSUB_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i64(fp1); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FMUL_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i64(fp1); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FDIV_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i64(fp1); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FSQRT_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_sqrt_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FABS_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_abs_d(fp0, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FMOV_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FNEG_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_chs_d(fp0, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRNE_L_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_round_l_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRZ_L_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_trunc_l_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRP_L_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_ceil_l_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRM_L_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_floor_l_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRNE_W_D: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_round_w_d(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FTINTRZ_W_D: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_trunc_w_d(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FTINTRP_W_D: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_ceil_w_d(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FTINTRM_W_D: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_floor_w_d(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FRECIP_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_recip_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FRSQRT_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FRINT_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_rint_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FCLASS_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_class_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FMIN_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_min_d(fp1, cpu_env, fp0, fp1); ++ gen_store_fpr64(ctx, fp1, fd); ++ tcg_temp_free_i64(fp1); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FMINA_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1); ++ gen_store_fpr64(ctx, fp1, fd); ++ tcg_temp_free_i64(fp1); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FMAX_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_max_d(fp1, cpu_env, fp0, fp1); ++ gen_store_fpr64(ctx, fp1, fd); ++ tcg_temp_free_i64(fp1); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FMAXA_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1); ++ gen_store_fpr64(ctx, fp1, fd); ++ tcg_temp_free_i64(fp1); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FCVT_S_D: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_cvts_d(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FTINT_W_D: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_cvt_w_d(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FTINT_L_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_cvt_l_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FFINT_S_W: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_cvts_w(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FFINT_D_W: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_cvtd_w(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FFINT_S_L: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_cvts_l(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FFINT_D_L: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_cvtd_l(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ default: ++ LARCH_INVAL("farith"); ++ generate_exception_end(ctx, EXCP_RI); ++ return; ++ } ++} ++ ++/* Coprocessor 3 (FPU) */ ++static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, ++ int fd, int fs, int base, int index) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ check_cp1_enabled(ctx); ++ if (base == 0) { ++ gen_load_gpr(t0, index); ++ } else if (index == 0) { ++ gen_load_gpr(t0, base); ++ } else { ++ gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); ++ } ++ ++ /* ++ * Don't do NOP if destination is zero: we must perform the actual ++ * memory access. ++ */ ++ switch (opc) { ++ case OPC_LARCH_FLDX_S: ++ case OPC_LARCH_FLDGT_S: ++ case OPC_LARCH_FLDLE_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); ++ tcg_gen_trunc_tl_i32(fp0, t0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FLDX_D: ++ case OPC_LARCH_FLDGT_D: ++ case OPC_LARCH_FLDLE_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FSTX_S: ++ case OPC_LARCH_FSTGT_S: ++ case OPC_LARCH_FSTLE_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FSTX_D: ++ case OPC_LARCH_FSTGT_D: ++ case OPC_LARCH_FSTLE_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ } ++ tcg_temp_free(t0); ++} ++ ++static inline void clear_branch_hflags(DisasContext *ctx) ++{ ++ ctx->hflags &= ~LARCH_HFLAG_BMASK; ++ if (ctx->base.is_jmp == DISAS_NEXT) { ++ save_cpu_state(ctx, 0); ++ } else { ++ /* ++ * It is not safe to save ctx->hflags as hflags may be changed ++ * in execution time. ++ */ ++ tcg_gen_andi_i32(hflags, hflags, ~LARCH_HFLAG_BMASK); ++ } ++} ++ ++static void gen_branch(DisasContext *ctx, int insn_bytes) ++{ ++ if (ctx->hflags & LARCH_HFLAG_BMASK) { ++ int proc_hflags = ctx->hflags & LARCH_HFLAG_BMASK; ++ /* Branches completion */ ++ clear_branch_hflags(ctx); ++ ctx->base.is_jmp = DISAS_NORETURN; ++ /* FIXME: Need to clear can_do_io. */ ++ switch (proc_hflags & LARCH_HFLAG_BMASK) { ++ case LARCH_HFLAG_B: ++ /* unconditional branch */ ++ gen_goto_tb(ctx, 0, ctx->btarget); ++ break; ++ case LARCH_HFLAG_BC: ++ /* Conditional branch */ ++ { ++ TCGLabel *l1 = gen_new_label(); ++ ++ tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); ++ gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); ++ gen_set_label(l1); ++ gen_goto_tb(ctx, 0, ctx->btarget); ++ } ++ break; ++ case LARCH_HFLAG_BR: ++ /* unconditional branch to register */ ++ tcg_gen_mov_tl(cpu_PC, btarget); ++ if (ctx->base.singlestep_enabled) { ++ save_cpu_state(ctx, 0); ++ gen_helper_raise_exception_debug(cpu_env); ++ } ++ tcg_gen_lookup_and_goto_ptr(); ++ break; ++ default: ++ fprintf(stderr, "unknown branch 0x%x\n", proc_hflags); ++ abort(); ++ } ++ } ++} ++ ++/* Signed immediate */ ++#define SIMM(op, start, width) \ ++ ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \ ++ << (32 - width)) \ ++ >> (32 - width)) ++/* Zero-extended immediate */ ++#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width))) ++ ++static void gen_sync(int stype) ++{ ++ TCGBar tcg_mo = TCG_BAR_SC; ++ ++ switch (stype) { ++ case 0x4: /* SYNC_WMB */ ++ tcg_mo |= TCG_MO_ST_ST; ++ break; ++ case 0x10: /* SYNC_MB */ ++ tcg_mo |= TCG_MO_ALL; ++ break; ++ case 0x11: /* SYNC_ACQUIRE */ ++ tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; ++ break; ++ case 0x12: /* SYNC_RELEASE */ ++ tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; ++ break; ++ case 0x13: /* SYNC_RMB */ ++ tcg_mo |= TCG_MO_LD_LD; ++ break; ++ default: ++ tcg_mo |= TCG_MO_ALL; ++ break; ++ } ++ ++ tcg_gen_mb(tcg_mo); ++} ++ ++static void gen_crc32(DisasContext *ctx, int rd, int rs, int rt, int sz, ++ int crc32c) ++{ ++ TCGv t0; ++ TCGv t1; ++ TCGv_i32 tsz = tcg_const_i32(1 << sz); ++ if (rd == 0) { ++ /* Treat as NOP. */ ++ return; ++ } ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, rt); ++ gen_load_gpr(t1, rs); ++ ++ if (crc32c) { ++ gen_helper_crc32c(cpu_gpr[rd], t0, t1, tsz); ++ } else { ++ gen_helper_crc32(cpu_gpr[rd], t0, t1, tsz); ++ } ++ ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ tcg_temp_free_i32(tsz); ++} ++ ++#include "cpu-csr.h" ++ ++#ifndef CONFIG_USER_ONLY ++ ++/* ++ * 64-bit CSR read ++ * ++ * @arg : GPR to store the value of CSR register ++ * @csr : CSR register number ++ */ ++static void gen_csr_rdq(DisasContext *ctx, TCGv rd, int64_t a1) ++{ ++ TCGv_i64 csr = tcg_const_i64(a1); ++ gen_helper_csr_rdq(rd, cpu_env, csr); ++} ++ ++/* ++ * 64-bit CSR write ++ * ++ * @arg : GPR that stores the new value of CSR register ++ * @csr : CSR register number ++ */ ++static void gen_csr_wrq(DisasContext *ctx, TCGv val, int64_t a1) ++{ ++ TCGv_i64 csr = tcg_const_i64(a1); ++ gen_helper_csr_wrq(val, cpu_env, val, csr); ++} ++ ++/* ++ * 64-bit CSR exchange ++ * ++ * @arg : GPR that stores the new value of CSR register ++ * @csr : CSR register number ++ */ ++static void gen_csr_xchgq(DisasContext *ctx, TCGv val, TCGv mask, int64_t a1) ++{ ++ TCGv_i64 csr = tcg_const_i64(a1); ++ gen_helper_csr_xchgq(val, cpu_env, val, mask, csr); ++} ++#endif /* !CONFIG_USER_ONLY */ ++ ++static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, ++ CPUState *cs) ++{ ++ DisasContext *ctx = container_of(dcbase, DisasContext, base); ++ CPULOONGARCHState *env = cs->env_ptr; ++ ++ ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; ++ ctx->saved_pc = -1; ++ ctx->insn_flags = env->insn_flags; ++ ctx->btarget = 0; ++ /* Restore state from the tb context. */ ++ ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ ++ restore_cpu_state(env, ctx); ++#ifdef CONFIG_USER_ONLY ++ ctx->mem_idx = LARCH_HFLAG_UM; ++#else ++ ctx->mem_idx = hflags_mmu_index(ctx->hflags); ++#endif ++ ctx->default_tcg_memop_mask = MO_ALIGN; ++ ++ LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, ++ ctx->hflags); ++} ++ ++static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) ++{ ++} ++ ++static void loongarch_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) ++{ ++ DisasContext *ctx = container_of(dcbase, DisasContext, base); ++ ++ tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & LARCH_HFLAG_BMASK, ++ ctx->btarget); ++} ++#if 0 ++static bool loongarch_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, ++ const CPUBreakpoint *bp) ++{ ++ DisasContext *ctx = container_of(dcbase, DisasContext, base); ++ ++ save_cpu_state(ctx, 1); ++ ctx->base.is_jmp = DISAS_NORETURN; ++ gen_helper_raise_exception_debug(cpu_env); ++ /* 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->base.pc_next += 4; ++ return true; ++} ++#endif ++/* 128 and 256 lsx vector instructions are not supported yet */ ++static bool decode_vector_lsx(uint32_t opcode) ++{ ++ uint32_t value = (opcode & 0xff000000); ++ ++ if ((opcode & 0xf0000000) == 0x70000000) { ++ return true; ++ } else if ((opcode & 0xfff00000) == 0x38400000) { ++ return true; ++ } else { ++ switch (value) { ++ case 0x09000000: ++ case 0x0a000000: ++ case 0x0e000000: ++ case 0x0f000000: ++ case 0x2c000000: ++ case 0x30000000: ++ case 0x31000000: ++ case 0x32000000: ++ case 0x33000000: ++ return true; ++ } ++ } ++ return false; ++} ++ ++static bool decode_insn(DisasContext *ctx, uint32_t insn); ++#include "decode-insn.c.inc" ++#include "trans.inc.c" ++ ++static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) ++{ ++ CPULOONGARCHState *env = cs->env_ptr; ++ DisasContext *ctx = container_of(dcbase, DisasContext, base); ++ int insn_bytes = 4; ++ ++ ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next); ++ ++ if (!decode_insn(ctx, ctx->opcode)) { ++ if (decode_vector_lsx(ctx->opcode)) { ++ generate_exception_end(ctx, EXCP_RI); ++ } else { ++ fprintf(stderr, "Error: unkown opcode. 0x%lx: 0x%x\n", ++ ctx->base.pc_next, ctx->opcode); ++ generate_exception_end(ctx, EXCP_RI); ++ } ++ } ++ ++ if (ctx->hflags & LARCH_HFLAG_BMASK) { ++ gen_branch(ctx, insn_bytes); ++ } ++ ctx->base.pc_next += insn_bytes; ++} ++ ++static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) ++{ ++ DisasContext *ctx = container_of(dcbase, DisasContext, base); ++ ++ if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) { ++ save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT); ++ gen_helper_raise_exception_debug(cpu_env); ++ } else { ++ switch (ctx->base.is_jmp) { ++ case DISAS_STOP: ++ gen_save_pc(ctx->base.pc_next); ++ tcg_gen_lookup_and_goto_ptr(); ++ break; ++ case DISAS_NEXT: ++ case DISAS_TOO_MANY: ++ save_cpu_state(ctx, 0); ++ gen_goto_tb(ctx, 0, ctx->base.pc_next); ++ break; ++ case DISAS_EXIT: ++ tcg_gen_exit_tb(NULL, 0); ++ break; ++ case DISAS_NORETURN: ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++ } ++} ++ ++static void loongarch_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) ++{ ++ qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); ++ log_target_disas(cs, dcbase->pc_first, dcbase->tb->size); ++} ++ ++static const TranslatorOps loongarch_tr_ops = { ++ .init_disas_context = loongarch_tr_init_disas_context, ++ .tb_start = loongarch_tr_tb_start, ++ .insn_start = loongarch_tr_insn_start, ++#if 0 ++ .breakpoint_check = loongarch_tr_breakpoint_check, ++#endif ++ .translate_insn = loongarch_tr_translate_insn, ++ .tb_stop = loongarch_tr_tb_stop, ++ .disas_log = loongarch_tr_disas_log, ++}; ++ ++void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb, int max_insns) ++{ ++ DisasContext ctx; ++ ++ translator_loop(&loongarch_tr_ops, &ctx.base, cs, tb, max_insns); ++} ++ ++void loongarch_tcg_init(void) ++{ ++ int i; ++ ++ for (i = 0; i < 32; i++) ++ cpu_gpr[i] = tcg_global_mem_new(cpu_env, ++ offsetof(CPULOONGARCHState, ++ active_tc.gpr[i]), ++ regnames[i]); ++ ++ for (i = 0; i < 32; i++) { ++ int off = offsetof(CPULOONGARCHState, active_fpu.fpr[i].d); ++ fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); ++ } ++ ++ cpu_PC = tcg_global_mem_new(cpu_env, ++ offsetof(CPULOONGARCHState, active_tc.PC), "PC"); ++ bcond = tcg_global_mem_new(cpu_env, ++ offsetof(CPULOONGARCHState, bcond), "bcond"); ++ btarget = tcg_global_mem_new(cpu_env, ++ offsetof(CPULOONGARCHState, btarget), "btarget"); ++ hflags = tcg_global_mem_new_i32(cpu_env, ++ offsetof(CPULOONGARCHState, hflags), "hflags"); ++ fpu_fcsr0 = tcg_global_mem_new_i32(cpu_env, ++ offsetof(CPULOONGARCHState, active_fpu.fcsr0), ++ "fcsr0"); ++ cpu_lladdr = tcg_global_mem_new(cpu_env, ++ offsetof(CPULOONGARCHState, lladdr), ++ "lladdr"); ++ cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPULOONGARCHState, llval), ++ "llval"); ++} ++ ++void restore_state_to_opc(CPULOONGARCHState *env, TranslationBlock *tb, ++ target_ulong *data) ++{ ++ env->active_tc.PC = data[0]; ++ env->hflags &= ~LARCH_HFLAG_BMASK; ++ env->hflags |= data[1]; ++ switch (env->hflags & LARCH_HFLAG_BMASK) { ++ case LARCH_HFLAG_BR: ++ break; ++ case LARCH_HFLAG_BC: ++ case LARCH_HFLAG_B: ++ env->btarget = data[2]; ++ break; ++ } ++} +diff --git a/target/meson.build b/target/meson.build +index 2f6940255e..ac0ce618b7 100644 +--- a/target/meson.build ++++ b/target/meson.build +@@ -5,6 +5,7 @@ subdir('cris') + subdir('hexagon') + subdir('hppa') + subdir('i386') ++subdir('loongarch64') + subdir('m68k') + subdir('microblaze') + subdir('mips') +-- +2.27.0 + diff --git a/0005-Add-linux-headers-and-linux-user.patch b/0005-Add-linux-headers-and-linux-user.patch new file mode 100644 index 0000000..93ba8ed --- /dev/null +++ b/0005-Add-linux-headers-and-linux-user.patch @@ -0,0 +1,1663 @@ +From 0d21e423fc15e8e2e2fdc910a7e94e051427f230 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Fri, 19 Aug 2022 23:47:06 -0400 +Subject: [PATCH 5/8] Add linux-headers and linux-user. + +Change-Id: If052442a981fed87c03ca431c010629dc8e872ca +Signed-off-by: lixianglai +--- + linux-headers/asm-loongarch64/bitsperlong.h | 9 + + linux-headers/asm-loongarch64/kvm.h | 346 ++++++++++++++++++++ + linux-headers/asm-loongarch64/sgidefs.h | 20 ++ + linux-headers/asm-loongarch64/unistd.h | 23 ++ + linux-user/loongarch64/cpu_loop.c | 193 +++++++++++ + linux-user/loongarch64/meson.build | 6 + + linux-user/loongarch64/signal.c | 212 ++++++++++++ + linux-user/loongarch64/sockbits.h | 1 + + linux-user/loongarch64/syscall_nr.h | 287 ++++++++++++++++ + linux-user/loongarch64/target_cpu.h | 45 +++ + linux-user/loongarch64/target_elf.h | 14 + + linux-user/loongarch64/target_fcntl.h | 13 + + linux-user/loongarch64/target_signal.h | 23 ++ + linux-user/loongarch64/target_structs.h | 62 ++++ + linux-user/loongarch64/target_syscall.h | 44 +++ + linux-user/loongarch64/termbits.h | 224 +++++++++++++ + 16 files changed, 1522 insertions(+) + create mode 100644 linux-headers/asm-loongarch64/bitsperlong.h + create mode 100644 linux-headers/asm-loongarch64/kvm.h + create mode 100644 linux-headers/asm-loongarch64/sgidefs.h + create mode 100644 linux-headers/asm-loongarch64/unistd.h + create mode 100644 linux-user/loongarch64/cpu_loop.c + create mode 100644 linux-user/loongarch64/meson.build + create mode 100644 linux-user/loongarch64/signal.c + create mode 100644 linux-user/loongarch64/sockbits.h + create mode 100644 linux-user/loongarch64/syscall_nr.h + create mode 100644 linux-user/loongarch64/target_cpu.h + create mode 100644 linux-user/loongarch64/target_elf.h + create mode 100644 linux-user/loongarch64/target_fcntl.h + create mode 100644 linux-user/loongarch64/target_signal.h + create mode 100644 linux-user/loongarch64/target_structs.h + create mode 100644 linux-user/loongarch64/target_syscall.h + create mode 100644 linux-user/loongarch64/termbits.h + +diff --git a/linux-headers/asm-loongarch64/bitsperlong.h b/linux-headers/asm-loongarch64/bitsperlong.h +new file mode 100644 +index 0000000000..5c2c8779a6 +--- /dev/null ++++ b/linux-headers/asm-loongarch64/bitsperlong.h +@@ -0,0 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++#ifndef __ASM_LOONGARCH_BITSPERLONG_H ++#define __ASM_LOONGARCH_BITSPERLONG_H ++ ++#define __BITS_PER_LONG _LOONGARCH_SZLONG ++ ++#include ++ ++#endif /* __ASM_LOONGARCH_BITSPERLONG_H */ +diff --git a/linux-headers/asm-loongarch64/kvm.h b/linux-headers/asm-loongarch64/kvm.h +new file mode 100644 +index 0000000000..a24375ee59 +--- /dev/null ++++ b/linux-headers/asm-loongarch64/kvm.h +@@ -0,0 +1,346 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2020 Loongson Technologies, Inc. All rights reserved. ++ * Authors: Sanjay Lal ++ * Authors: Xing Li ++ */ ++ ++#ifndef __LINUX_KVM_LOONGARCH_H ++#define __LINUX_KVM_LOONGARCH_H ++ ++#include ++ ++#define __KVM_HAVE_GUEST_DEBUG ++#define KVM_GUESTDBG_USE_SW_BP 0x00010000 ++#define KVM_GUESTDBG_USE_HW_BP 0x00020000 ++#define KVM_DATA_HW_BREAKPOINT_NUM 8 ++#define KVM_INST_HW_BREAKPOINT_NUM 8 ++ ++/* ++ * KVM Loongarch specific structures and definitions. ++ * ++ * Some parts derived from the x86 version of this file. ++ */ ++ ++#define __KVM_HAVE_READONLY_MEM ++ ++#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 ++ ++#define KVM_LARCH_VCPU_PVTIME_CTRL 2 ++#define KVM_LARCH_VCPU_PVTIME_IPA 0 ++ ++/* ++ * for KVM_GET_REGS and KVM_SET_REGS ++ */ ++struct kvm_regs { ++ /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */ ++ __u64 gpr[32]; ++ __u64 pc; ++}; ++ ++/* ++ * for KVM_GET_CPUCFG ++ */ ++struct kvm_cpucfg { ++ /* out (KVM_GET_CPUCFG) */ ++ __u32 cpucfg[64]; ++}; ++ ++/* ++ * for KVM_GET_FPU and KVM_SET_FPU ++ */ ++struct kvm_fpu { ++ __u32 fcsr; ++ __u32 vcsr; ++ __u64 fcc; /* 8x8 */ ++ struct kvm_fpureg { ++ __u64 val64[4]; //support max 256 bits ++ }fpr[32]; ++}; ++ ++/* ++ * For LOONGARCH, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various ++ * registers. The id field is broken down as follows: ++ * ++ * bits[63..52] - As per linux/kvm.h ++ * bits[51..32] - Must be zero. ++ * bits[31..16] - Register set. ++ * ++ * Register set = 0: GP registers from kvm_regs (see definitions below). ++ * ++ * Register set = 1: CP0 registers. ++ * bits[15..8] - COP0 register set. ++ * ++ * COP0 register set = 0: Main CP0 registers. ++ * bits[7..3] - Register 'rd' index. ++ * bits[2..0] - Register 'sel' index. ++ * ++ * COP0 register set = 1: MAARs. ++ * bits[7..0] - MAAR index. ++ * ++ * Register set = 2: KVM specific registers (see definitions below). ++ * ++ * Register set = 3: FPU / MSA registers (see definitions below). ++ * ++ * Other sets registers may be added in the future. Each set would ++ * have its own identifier in bits[31..16]. ++ */ ++ ++#define KVM_REG_LOONGARCH_GP (KVM_REG_LOONGARCH | 0x0000000000000000ULL) ++#define KVM_REG_LOONGARCH_CSR (KVM_REG_LOONGARCH | 0x0000000000010000ULL) ++#define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x0000000000020000ULL) ++#define KVM_REG_LOONGARCH_FPU (KVM_REG_LOONGARCH | 0x0000000000030000ULL) ++ ++ ++/* ++ * KVM_REG_LOONGARCH_GP - General purpose registers from kvm_regs. ++ */ ++ ++#define KVM_REG_LOONGARCH_R0 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 0) ++#define KVM_REG_LOONGARCH_R1 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 1) ++#define KVM_REG_LOONGARCH_R2 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 2) ++#define KVM_REG_LOONGARCH_R3 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 3) ++#define KVM_REG_LOONGARCH_R4 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 4) ++#define KVM_REG_LOONGARCH_R5 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 5) ++#define KVM_REG_LOONGARCH_R6 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 6) ++#define KVM_REG_LOONGARCH_R7 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 7) ++#define KVM_REG_LOONGARCH_R8 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 8) ++#define KVM_REG_LOONGARCH_R9 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 9) ++#define KVM_REG_LOONGARCH_R10 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 10) ++#define KVM_REG_LOONGARCH_R11 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 11) ++#define KVM_REG_LOONGARCH_R12 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 12) ++#define KVM_REG_LOONGARCH_R13 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 13) ++#define KVM_REG_LOONGARCH_R14 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 14) ++#define KVM_REG_LOONGARCH_R15 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 15) ++#define KVM_REG_LOONGARCH_R16 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 16) ++#define KVM_REG_LOONGARCH_R17 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 17) ++#define KVM_REG_LOONGARCH_R18 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 18) ++#define KVM_REG_LOONGARCH_R19 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 19) ++#define KVM_REG_LOONGARCH_R20 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 20) ++#define KVM_REG_LOONGARCH_R21 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 21) ++#define KVM_REG_LOONGARCH_R22 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 22) ++#define KVM_REG_LOONGARCH_R23 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 23) ++#define KVM_REG_LOONGARCH_R24 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 24) ++#define KVM_REG_LOONGARCH_R25 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 25) ++#define KVM_REG_LOONGARCH_R26 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 26) ++#define KVM_REG_LOONGARCH_R27 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 27) ++#define KVM_REG_LOONGARCH_R28 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 28) ++#define KVM_REG_LOONGARCH_R29 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 29) ++#define KVM_REG_LOONGARCH_R30 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 30) ++#define KVM_REG_LOONGARCH_R31 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 31) ++ ++#define KVM_REG_LOONGARCH_HI (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 32) ++#define KVM_REG_LOONGARCH_LO (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 33) ++#define KVM_REG_LOONGARCH_PC (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 34) ++ ++ ++/* ++ * KVM_REG_LOONGARCH_KVM - KVM specific control registers. ++ */ ++ ++/* ++ * CP0_Count control ++ * DC: Set 0: Master disable CP0_Count and set COUNT_RESUME to now ++ * Set 1: Master re-enable CP0_Count with unchanged bias, handling timer ++ * interrupts since COUNT_RESUME ++ * This can be used to freeze the timer to get a consistent snapshot of ++ * the CP0_Count and timer interrupt pending state, while also resuming ++ * safely without losing time or guest timer interrupts. ++ * Other: Reserved, do not change. ++ */ ++#define KVM_REG_LOONGARCH_COUNT_CTL (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 0) ++#define KVM_REG_LOONGARCH_COUNT_CTL_DC 0x00000001 ++ ++/* ++ * CP0_Count resume monotonic nanoseconds ++ * The monotonic nanosecond time of the last set of COUNT_CTL.DC (master ++ * disable). Any reads and writes of Count related registers while ++ * COUNT_CTL.DC=1 will appear to occur at this time. When COUNT_CTL.DC is ++ * cleared again (master enable) any timer interrupts since this time will be ++ * emulated. ++ * Modifications to times in the future are rejected. ++ */ ++#define KVM_REG_LOONGARCH_COUNT_RESUME (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 1) ++/* ++ * CP0_Count rate in Hz ++ * Specifies the rate of the CP0_Count timer in Hz. Modifications occur without ++ * discontinuities in CP0_Count. ++ */ ++#define KVM_REG_LOONGARCH_COUNT_HZ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 2) ++ ++#define KVM_REG_LOONGARCH_COUNTER (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3) ++ ++#define KVM_REG_LOONGARCH_VCPU_RESET (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 4) ++ ++struct kvm_iocsr_entry { ++ __u32 addr; ++ __u32 pad; ++ __u64 data; ++}; ++ ++struct kvm_csr_entry { ++ __u32 index; ++ __u32 reserved; ++ __u64 data; ++}; ++ ++/* for KVM_GET_MSRS and KVM_SET_MSRS */ ++struct kvm_msrs { ++ __u32 ncsrs; /* number of msrs in entries */ ++ __u32 pad; ++ struct kvm_csr_entry entries[0]; ++}; ++ ++#define __KVM_HAVE_IRQ_LINE ++ ++struct kvm_debug_exit_arch { ++ __u64 epc; ++ __u32 fwps; ++ __u32 mwps; ++ __u32 exception; ++}; ++ ++/* for KVM_SET_GUEST_DEBUG */ ++struct hw_breakpoint { ++ __u64 addr; ++ __u64 mask; ++ __u32 asid; ++ __u32 ctrl; ++}; ++ ++struct kvm_guest_debug_arch { ++ struct hw_breakpoint data_breakpoint[KVM_DATA_HW_BREAKPOINT_NUM]; ++ struct hw_breakpoint inst_breakpoint[KVM_INST_HW_BREAKPOINT_NUM]; ++ int inst_bp_nums, data_bp_nums; ++}; ++ ++/* definition of registers in kvm_run */ ++struct kvm_sync_regs { ++}; ++ ++/* dummy definition */ ++struct kvm_sregs { ++}; ++ ++struct kvm_loongarch_interrupt { ++ /* in */ ++ __u32 cpu; ++ __u32 irq; ++}; ++ ++#define KVM_IRQCHIP_LS7A_IOAPIC 0x0 ++#define KVM_IRQCHIP_LS3A_GIPI 0x1 ++#define KVM_IRQCHIP_LS3A_HT_IRQ 0x2 ++#define KVM_IRQCHIP_LS3A_ROUTE 0x3 ++#define KVM_IRQCHIP_LS3A_EXTIRQ 0x4 ++#define KVM_IRQCHIP_LS3A_IPMASK 0x5 ++#define KVM_NR_IRQCHIPS 1 ++#define KVM_IRQCHIP_NUM_PINS 64 ++ ++#define KVM_MAX_CORES 256 ++#define KVM_EXTIOI_IRQS (256) ++#define KVM_EXTIOI_IRQS_BITMAP_SIZE (KVM_EXTIOI_IRQS / 8) ++/* map to ipnum per 32 irqs */ ++#define KVM_EXTIOI_IRQS_IPMAP_SIZE (KVM_EXTIOI_IRQS / 32) ++#define KVM_EXTIOI_IRQS_PER_GROUP 32 ++#define KVM_EXTIOI_IRQS_COREMAP_SIZE (KVM_EXTIOI_IRQS) ++#define KVM_EXTIOI_IRQS_NODETYPE_SIZE 16 ++ ++struct ls7a_ioapic_state { ++ __u64 int_id; ++ /* 0x020 interrupt mask register */ ++ __u64 int_mask; ++ /* 0x040 1=msi */ ++ __u64 htmsi_en; ++ /* 0x060 edge=1 level =0 */ ++ __u64 intedge; ++ /* 0x080 for clean edge int,set 1 clean,set 0 is noused */ ++ __u64 intclr; ++ /* 0x0c0 */ ++ __u64 auto_crtl0; ++ /* 0x0e0 */ ++ __u64 auto_crtl1; ++ /* 0x100 - 0x140 */ ++ __u8 route_entry[64]; ++ /* 0x200 - 0x240 */ ++ __u8 htmsi_vector[64]; ++ /* 0x300 */ ++ __u64 intisr_chip0; ++ /* 0x320 */ ++ __u64 intisr_chip1; ++ /* edge detection */ ++ __u64 last_intirr; ++ /* 0x380 interrupt request register */ ++ __u64 intirr; ++ /* 0x3a0 interrupt service register */ ++ __u64 intisr; ++ /* 0x3e0 interrupt level polarity selection register, ++ * 0 for high level tirgger ++ */ ++ __u64 int_polarity; ++}; ++ ++struct loongarch_gipi_single { ++ __u32 status; ++ __u32 en; ++ __u32 set; ++ __u32 clear; ++ __u64 buf[4]; ++}; ++ ++struct loongarch_gipiState { ++ struct loongarch_gipi_single core[KVM_MAX_CORES]; ++}; ++ ++struct kvm_loongarch_ls3a_extirq_state { ++ union ext_en_r { ++ uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; ++ uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; ++ uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE]; ++ } ext_en_r; ++ union bounce_r { ++ uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; ++ uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; ++ uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE]; ++ } bounce_r; ++ union ext_isr_r { ++ uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; ++ uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; ++ uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE]; ++ } ext_isr_r; ++ union ext_core_isr_r { ++ uint64_t reg_u64[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; ++ uint32_t reg_u32[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; ++ uint8_t reg_u8[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE]; ++ } ext_core_isr_r; ++ union ip_map_r { ++ uint64_t reg_u64; ++ uint32_t reg_u32[KVM_EXTIOI_IRQS_IPMAP_SIZE / 4]; ++ uint8_t reg_u8[KVM_EXTIOI_IRQS_IPMAP_SIZE]; ++ } ip_map_r; ++ union core_map_r { ++ uint64_t reg_u64[KVM_EXTIOI_IRQS_COREMAP_SIZE / 8]; ++ uint32_t reg_u32[KVM_EXTIOI_IRQS_COREMAP_SIZE / 4]; ++ uint8_t reg_u8[KVM_EXTIOI_IRQS_COREMAP_SIZE]; ++ } core_map_r; ++ union node_type_r { ++ uint64_t reg_u64[KVM_EXTIOI_IRQS_NODETYPE_SIZE / 4]; ++ uint32_t reg_u32[KVM_EXTIOI_IRQS_NODETYPE_SIZE / 2]; ++ uint16_t reg_u16[KVM_EXTIOI_IRQS_NODETYPE_SIZE]; ++ uint8_t reg_u8[KVM_EXTIOI_IRQS_NODETYPE_SIZE * 2]; ++ } node_type_r; ++}; ++ ++struct loongarch_kvm_irqchip { ++ __u16 chip_id; ++ __u16 len; ++ __u16 vcpu_id; ++ __u16 reserved; ++ char data[0]; ++}; ++ ++#endif /* __LINUX_KVM_LOONGARCH_H */ +diff --git a/linux-headers/asm-loongarch64/sgidefs.h b/linux-headers/asm-loongarch64/sgidefs.h +new file mode 100644 +index 0000000000..b809608349 +--- /dev/null ++++ b/linux-headers/asm-loongarch64/sgidefs.h +@@ -0,0 +1,20 @@ ++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ ++/* ++* Copyright (C) 2020 Loongson Technology Corporation Limited ++* ++* Author: Hanlu Li ++*/ ++#ifndef __ASM_SGIDEFS_H ++#define __ASM_SGIDEFS_H ++ ++#define _LOONGARCH_ISA_LOONGARCH32 6 ++#define _LOONGARCH_ISA_LOONGARCH64 7 ++ ++/* ++ * Subprogram calling convention ++ */ ++#define _LOONGARCH_SIM_ABILP32 1 ++#define _LOONGARCH_SIM_ABILPX32 2 ++#define _LOONGARCH_SIM_ABILP64 3 ++ ++#endif /* __ASM_SGIDEFS_H */ +diff --git a/linux-headers/asm-loongarch64/unistd.h b/linux-headers/asm-loongarch64/unistd.h +new file mode 100644 +index 0000000000..2a6014562a +--- /dev/null ++++ b/linux-headers/asm-loongarch64/unistd.h +@@ -0,0 +1,23 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++/* ++ * 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. ++ * ++ * 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 . ++ * ++ * Copyright (C) 2020 Loongson Technologies, Inc. ++ * Authors: Jun Yi ++ */ ++ ++#ifdef __LP64__ ++#define __ARCH_WANT_NEW_STAT ++#endif /* __LP64__ */ ++ ++#include +diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c +new file mode 100644 +index 0000000000..6d4093e1d7 +--- /dev/null ++++ b/linux-user/loongarch64/cpu_loop.c +@@ -0,0 +1,193 @@ ++/* ++ * qemu user cpu loop ++ * ++ * Copyright (c) 2003-2008 Fabrice Bellard ++ * ++ * 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 . ++ */ ++ ++#include "qemu/osdep.h" ++#include "qemu.h" ++#include "cpu_loop-common.h" ++#include "elf.h" ++ ++/* Break codes */ ++enum { ++ BRK_OVERFLOW = 6, ++ BRK_DIVZERO = 7 ++}; ++ ++static int do_break(CPULOONGARCHState *env, target_siginfo_t *info, ++ unsigned int code) ++{ ++ int ret = -1; ++ ++ switch (code) { ++ case BRK_OVERFLOW: ++ case BRK_DIVZERO: ++ info->si_signo = TARGET_SIGFPE; ++ info->si_errno = 0; ++ info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV; ++ queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info); ++ ret = 0; ++ break; ++ default: ++ info->si_signo = TARGET_SIGTRAP; ++ info->si_errno = 0; ++ queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info); ++ ret = 0; ++ break; ++ } ++ ++ return ret; ++} ++ ++void cpu_loop(CPULOONGARCHState *env) ++{ ++ CPUState *cs = CPU(loongarch_env_get_cpu(env)); ++ target_siginfo_t info; ++ int trapnr; ++ abi_long ret; ++ ++ for (;;) { ++ cpu_exec_start(cs); ++ trapnr = cpu_exec(cs); ++ cpu_exec_end(cs); ++ process_queued_cpu_work(cs); ++ ++ switch (trapnr) { ++ case EXCP_SYSCALL: ++ env->active_tc.PC += 4; ++ ret = do_syscall(env, env->active_tc.gpr[11], ++ env->active_tc.gpr[4], env->active_tc.gpr[5], ++ env->active_tc.gpr[6], env->active_tc.gpr[7], ++ env->active_tc.gpr[8], env->active_tc.gpr[9], ++ -1, -1); ++ if (ret == -TARGET_ERESTARTSYS) { ++ env->active_tc.PC -= 4; ++ break; ++ } ++ if (ret == -TARGET_QEMU_ESIGRETURN) { ++ /* Returning from a successful sigreturn syscall. ++ Avoid clobbering register state. */ ++ break; ++ } ++ env->active_tc.gpr[4] = ret; ++ break; ++ case EXCP_TLBL: ++ case EXCP_TLBS: ++ case EXCP_AdEL: ++ case EXCP_AdES: ++ info.si_signo = TARGET_SIGSEGV; ++ info.si_errno = 0; ++ /* XXX: check env->error_code */ ++ info.si_code = TARGET_SEGV_MAPERR; ++ info._sifields._sigfault._addr = env->CSR_BADV; ++ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); ++ break; ++ case EXCP_FPDIS: ++ case EXCP_LSXDIS: ++ case EXCP_LASXDIS: ++ case EXCP_RI: ++ info.si_signo = TARGET_SIGILL; ++ info.si_errno = 0; ++ info.si_code = 0; ++ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); ++ break; ++ case EXCP_INTERRUPT: ++ /* just indicate that signals should be handled asap */ ++ break; ++ case EXCP_DEBUG: ++ info.si_signo = TARGET_SIGTRAP; ++ info.si_errno = 0; ++ info.si_code = TARGET_TRAP_BRKPT; ++ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); ++ break; ++ case EXCP_FPE: ++ info.si_signo = TARGET_SIGFPE; ++ info.si_errno = 0; ++ info.si_code = TARGET_FPE_FLTUNK; ++ if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_INVALID) { ++ info.si_code = TARGET_FPE_FLTINV; ++ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_DIV0) { ++ info.si_code = TARGET_FPE_FLTDIV; ++ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_OVERFLOW) { ++ info.si_code = TARGET_FPE_FLTOVF; ++ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_UNDERFLOW) { ++ info.si_code = TARGET_FPE_FLTUND; ++ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_INEXACT) { ++ info.si_code = TARGET_FPE_FLTRES; ++ } ++ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); ++ break; ++ case EXCP_BREAK: ++ { ++ abi_ulong trap_instr; ++ unsigned int code; ++ ++ ret = get_user_u32(trap_instr, env->active_tc.PC); ++ if (ret != 0) { ++ goto error; ++ } ++ ++ code = trap_instr & 0x7fff; ++ ++ if (do_break(env, &info, code) != 0) { ++ goto error; ++ } ++ } ++ break; ++ case EXCP_TRAP: ++ { ++ abi_ulong trap_instr; ++ unsigned int code = 0; ++ ++ ret = get_user_u32(trap_instr, env->active_tc.PC); ++ ++ if (ret != 0) { ++ goto error; ++ } ++ ++ /* The immediate versions don't provide a code. */ ++ if (!(trap_instr & 0xFC000000)) { ++ code = ((trap_instr >> 6) & ((1 << 10) - 1)); ++ } ++ ++ if (do_break(env, &info, code) != 0) { ++ goto error; ++ } ++ } ++ break; ++ case EXCP_ATOMIC: ++ cpu_exec_step_atomic(cs); ++ break; ++ default: ++error: ++ printf("111111\n"); ++ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr); ++ abort(); ++ } ++ process_pending_signals(env); ++ } ++} ++ ++void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) ++{ ++ int i; ++ ++ for (i = 0; i < 32; i++) { ++ env->active_tc.gpr[i] = regs->regs[i]; ++ } ++ env->active_tc.PC = regs->csr_era & ~(target_ulong)1; ++} +diff --git a/linux-user/loongarch64/meson.build b/linux-user/loongarch64/meson.build +new file mode 100644 +index 0000000000..c4c0b4d701 +--- /dev/null ++++ b/linux-user/loongarch64/meson.build +@@ -0,0 +1,6 @@ ++syscall_nr_generators += { ++ 'loongarch64': generator(sh, ++ arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@', ++ '', 'TARGET_SYSCALL_OFFSET' ], ++ output: '@BASENAME@_nr.h') ++} +diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c +new file mode 100644 +index 0000000000..6fe6852758 +--- /dev/null ++++ b/linux-user/loongarch64/signal.c +@@ -0,0 +1,212 @@ ++/* ++ * Emulation of Linux signals ++ * ++ * Copyright (c) 2003 Fabrice Bellard ++ * ++ * 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 . ++ */ ++#include "qemu/osdep.h" ++#include "qemu.h" ++#include "signal-common.h" ++#include "linux-user/trace.h" ++ ++#define FPU_REG_WIDTH 256 ++union fpureg { ++ uint32_t val32[FPU_REG_WIDTH / 32]; ++ uint64_t val64[FPU_REG_WIDTH / 64]; ++}; ++ ++struct target_sigcontext { ++ uint64_t sc_pc; ++ uint64_t sc_regs[32]; ++ uint32_t sc_flags; ++ ++ uint32_t sc_fcsr; ++ uint32_t sc_vcsr; ++ uint64_t sc_fcc; ++ union fpureg sc_fpregs[32] __attribute__((aligned(32))); ++ ++ uint32_t sc_reserved; ++ ++}; ++ ++struct sigframe { ++ uint32_t sf_ass[4]; /* argument save space for o32 */ ++ uint32_t sf_code[2]; /* signal trampoline */ ++ struct target_sigcontext sf_sc; ++ target_sigset_t sf_mask; ++}; ++ ++struct target_ucontext { ++ target_ulong tuc_flags; ++ target_ulong tuc_link; ++ target_stack_t tuc_stack; ++ target_ulong pad0; ++ struct target_sigcontext tuc_mcontext; ++ target_sigset_t tuc_sigmask; ++}; ++ ++struct target_rt_sigframe { ++ uint32_t rs_ass[4]; /* argument save space for o32 */ ++ uint32_t rs_code[2]; /* signal trampoline */ ++ struct target_siginfo rs_info; ++ struct target_ucontext rs_uc; ++}; ++ ++static inline void setup_sigcontext(CPULOONGARCHState *regs, ++ struct target_sigcontext *sc) ++{ ++ int i; ++ ++ __put_user(exception_resume_pc(regs), &sc->sc_pc); ++ regs->hflags &= ~LARCH_HFLAG_BMASK; ++ ++ __put_user(0, &sc->sc_regs[0]); ++ for (i = 1; i < 32; ++i) { ++ __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); ++ } ++ ++ for (i = 0; i < 32; ++i) { ++ __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i].val64[0]); ++ } ++} ++ ++static inline void ++restore_sigcontext(CPULOONGARCHState *regs, struct target_sigcontext *sc) ++{ ++ int i; ++ ++ __get_user(regs->CSR_ERA, &sc->sc_pc); ++ ++ for (i = 1; i < 32; ++i) { ++ __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); ++ } ++ ++ for (i = 0; i < 32; ++i) { ++ __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i].val64[0]); ++ } ++} ++ ++/* ++ * Determine which stack to use.. ++ */ ++static inline abi_ulong ++get_sigframe(struct target_sigaction *ka, CPULOONGARCHState *regs, ++ size_t frame_size) ++{ ++ unsigned long sp; ++ ++ /* ++ * FPU emulator may have its own trampoline active just ++ * above the user stack, 16-bytes before the next lowest ++ * 16 byte boundary. Try to avoid trashing it. ++ */ ++ sp = target_sigsp(get_sp_from_cpustate(regs) - 32, ka); ++ ++ return (sp - frame_size) & ~7; ++} ++ ++void setup_rt_frame(int sig, struct target_sigaction *ka, ++ target_siginfo_t *info, ++ target_sigset_t *set, CPULOONGARCHState *env) ++{ ++ struct target_rt_sigframe *frame; ++ abi_ulong frame_addr; ++ int i; ++ ++ frame_addr = get_sigframe(ka, env, sizeof(*frame)); ++ trace_user_setup_rt_frame(env, frame_addr); ++ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { ++ goto give_sigsegv; ++ } ++ ++ /* ori a7, $r0, TARGET_NR_rt_sigreturn */ ++ /* syscall 0 */ ++ __put_user(0x0380000b + (TARGET_NR_rt_sigreturn << 10), &frame->rs_code[0]); ++ __put_user(0x002b0000, &frame->rs_code[1]); ++ ++ tswap_siginfo(&frame->rs_info, info); ++ ++ __put_user(0, &frame->rs_uc.tuc_flags); ++ __put_user(0, &frame->rs_uc.tuc_link); ++ target_save_altstack(&frame->rs_uc.tuc_stack, env); ++ ++ setup_sigcontext(env, &frame->rs_uc.tuc_mcontext); ++ ++ for (i = 0; i < TARGET_NSIG_WORDS; i++) { ++ __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]); ++ } ++ ++ /* ++ * Arguments to signal handler: ++ * ++ * a0 = signal number ++ * a1 = pointer to siginfo_t ++ * a2 = pointer to ucontext_t ++ * ++ * $25 and PC point to the signal handler, $29 points to the ++ * struct sigframe. ++ */ ++ env->active_tc.gpr[4] = sig; ++ env->active_tc.gpr[5] = frame_addr ++ + offsetof(struct target_rt_sigframe, rs_info); ++ env->active_tc.gpr[6] = frame_addr ++ + offsetof(struct target_rt_sigframe, rs_uc); ++ env->active_tc.gpr[3] = frame_addr; ++ env->active_tc.gpr[1] = frame_addr ++ + offsetof(struct target_rt_sigframe, rs_code); ++ /* The original kernel code sets CP0_ERA to the handler ++ * since it returns to userland using ertn ++ * we cannot do this here, and we must set PC directly */ ++ env->active_tc.PC = env->active_tc.gpr[20] = ka->_sa_handler; ++ unlock_user_struct(frame, frame_addr, 1); ++ return; ++ ++give_sigsegv: ++ unlock_user_struct(frame, frame_addr, 1); ++ force_sigsegv(sig); ++} ++ ++long do_rt_sigreturn(CPULOONGARCHState *env) ++{ ++ struct target_rt_sigframe *frame; ++ abi_ulong frame_addr; ++ sigset_t blocked; ++ ++ frame_addr = env->active_tc.gpr[3]; ++ trace_user_do_rt_sigreturn(env, frame_addr); ++ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { ++ goto badframe; ++ } ++ ++ target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask); ++ set_sigmask(&blocked); ++ ++ restore_sigcontext(env, &frame->rs_uc.tuc_mcontext); ++ ++ if (do_sigaltstack(frame_addr + ++ offsetof(struct target_rt_sigframe, rs_uc.tuc_stack), ++ 0, get_sp_from_cpustate(env)) == -EFAULT) ++ goto badframe; ++ ++ env->active_tc.PC = env->CSR_ERA; ++ /* I am not sure this is right, but it seems to work ++ * maybe a problem with nested signals ? */ ++ env->CSR_ERA = 0; ++ return -TARGET_QEMU_ESIGRETURN; ++ ++badframe: ++ force_sig(TARGET_SIGSEGV); ++ return -TARGET_QEMU_ESIGRETURN; ++} +diff --git a/linux-user/loongarch64/sockbits.h b/linux-user/loongarch64/sockbits.h +new file mode 100644 +index 0000000000..0e4c8f012d +--- /dev/null ++++ b/linux-user/loongarch64/sockbits.h +@@ -0,0 +1 @@ ++#include "../generic/sockbits.h" +diff --git a/linux-user/loongarch64/syscall_nr.h b/linux-user/loongarch64/syscall_nr.h +new file mode 100644 +index 0000000000..a30aca8d8e +--- /dev/null ++++ b/linux-user/loongarch64/syscall_nr.h +@@ -0,0 +1,287 @@ ++#ifndef LINUX_USER_LOONGARCH_SYSCALL_NR_H ++#define LINUX_USER_LOONGARCH_SYSCALL_NR_H ++ ++#define TARGET_NR_io_setup 0 ++#define TARGET_NR_io_destroy 1 ++#define TARGET_NR_io_submit 2 ++#define TARGET_NR_io_cancel 3 ++#define TARGET_NR_io_getevents 4 ++#define TARGET_NR_setxattr 5 ++#define TARGET_NR_lsetxattr 6 ++#define TARGET_NR_fsetxattr 7 ++#define TARGET_NR_getxattr 8 ++#define TARGET_NR_lgetxattr 9 ++#define TARGET_NR_fgetxattr 10 ++#define TARGET_NR_listxattr 11 ++#define TARGET_NR_llistxattr 12 ++#define TARGET_NR_flistxattr 13 ++#define TARGET_NR_removexattr 14 ++#define TARGET_NR_lremovexattr 15 ++#define TARGET_NR_fremovexattr 16 ++#define TARGET_NR_getcwd 17 ++#define TARGET_NR_lookup_dcookie 18 ++#define TARGET_NR_eventfd2 19 ++#define TARGET_NR_epoll_create1 20 ++#define TARGET_NR_epoll_ctl 21 ++#define TARGET_NR_epoll_pwait 22 ++#define TARGET_NR_dup 23 ++#define TARGET_NR_dup3 24 ++#define TARGET_NR_fcntl 25 ++#define TARGET_NR_inotify_init1 26 ++#define TARGET_NR_inotify_add_watch 27 ++#define TARGET_NR_inotify_rm_watch 28 ++#define TARGET_NR_ioctl 29 ++#define TARGET_NR_ioprio_set 30 ++#define TARGET_NR_ioprio_get 31 ++#define TARGET_NR_flock 32 ++#define TARGET_NR_mknodat 33 ++#define TARGET_NR_mkdirat 34 ++#define TARGET_NR_unlinkat 35 ++#define TARGET_NR_symlinkat 36 ++#define TARGET_NR_linkat 37 ++#define TARGET_NR_renameat 38 ++#define TARGET_NR_umount2 39 ++#define TARGET_NR_mount 40 ++#define TARGET_NR_pivot_root 41 ++#define TARGET_NR_nfsservctl 42 ++#define TARGET_NR_statfs 43 ++#define TARGET_NR_fstatfs 44 ++#define TARGET_NR_truncate 45 ++#define TARGET_NR_ftruncate 46 ++#define TARGET_NR_fallocate 47 ++#define TARGET_NR_faccessat 48 ++#define TARGET_NR_chdir 49 ++#define TARGET_NR_fchdir 50 ++#define TARGET_NR_chroot 51 ++#define TARGET_NR_fchmod 52 ++#define TARGET_NR_fchmodat 53 ++#define TARGET_NR_fchownat 54 ++#define TARGET_NR_fchown 55 ++#define TARGET_NR_openat 56 ++#define TARGET_NR_close 57 ++#define TARGET_NR_vhangup 58 ++#define TARGET_NR_pipe2 59 ++#define TARGET_NR_quotactl 60 ++#define TARGET_NR_getdents64 61 ++#define TARGET_NR_lseek 62 ++#define TARGET_NR_read 63 ++#define TARGET_NR_write 64 ++#define TARGET_NR_readv 65 ++#define TARGET_NR_writev 66 ++#define TARGET_NR_pread64 67 ++#define TARGET_NR_pwrite64 68 ++#define TARGET_NR_preadv 69 ++#define TARGET_NR_pwritev 70 ++#define TARGET_NR_sendfile 71 ++#define TARGET_NR_pselect6 72 ++#define TARGET_NR_ppoll 73 ++#define TARGET_NR_signalfd4 74 ++#define TARGET_NR_vmsplice 75 ++#define TARGET_NR_splice 76 ++#define TARGET_NR_tee 77 ++#define TARGET_NR_readlinkat 78 ++#define TARGET_NR_newfstatat 79 ++#define TARGET_NR_fstat 80 ++#define TARGET_NR_sync 81 ++#define TARGET_NR_fsync 82 ++#define TARGET_NR_fdatasync 83 ++#define TARGET_NR_sync_file_range 84 ++#define TARGET_NR_timerfd_create 85 ++#define TARGET_NR_timerfd_settime 86 ++#define TARGET_NR_timerfd_gettime 87 ++#define TARGET_NR_utimensat 88 ++#define TARGET_NR_acct 89 ++#define TARGET_NR_capget 90 ++#define TARGET_NR_capset 91 ++#define TARGET_NR_personality 92 ++#define TARGET_NR_exit 93 ++#define TARGET_NR_exit_group 94 ++#define TARGET_NR_waitid 95 ++#define TARGET_NR_set_tid_address 96 ++#define TARGET_NR_unshare 97 ++#define TARGET_NR_futex 98 ++#define TARGET_NR_set_robust_list 99 ++#define TARGET_NR_get_robust_list 100 ++#define TARGET_NR_nanosleep 101 ++#define TARGET_NR_getitimer 102 ++#define TARGET_NR_setitimer 103 ++#define TARGET_NR_kexec_load 104 ++#define TARGET_NR_init_module 105 ++#define TARGET_NR_delete_module 106 ++#define TARGET_NR_timer_create 107 ++#define TARGET_NR_timer_gettime 108 ++#define TARGET_NR_timer_getoverrun 109 ++#define TARGET_NR_timer_settime 110 ++#define TARGET_NR_timer_delete 111 ++#define TARGET_NR_clock_settime 112 ++#define TARGET_NR_clock_gettime 113 ++#define TARGET_NR_clock_getres 114 ++#define TARGET_NR_clock_nanosleep 115 ++#define TARGET_NR_syslog 116 ++#define TARGET_NR_ptrace 117 ++#define TARGET_NR_sched_setparam 118 ++#define TARGET_NR_sched_setscheduler 119 ++#define TARGET_NR_sched_getscheduler 120 ++#define TARGET_NR_sched_getparam 121 ++#define TARGET_NR_sched_setaffinity 122 ++#define TARGET_NR_sched_getaffinity 123 ++#define TARGET_NR_sched_yield 124 ++#define TARGET_NR_sched_get_priority_max 125 ++#define TARGET_NR_sched_get_priority_min 126 ++#define TARGET_NR_sched_rr_get_interval 127 ++#define TARGET_NR_restart_syscall 128 ++#define TARGET_NR_kill 129 ++#define TARGET_NR_tkill 130 ++#define TARGET_NR_tgkill 131 ++#define TARGET_NR_sigaltstack 132 ++#define TARGET_NR_rt_sigsuspend 133 ++#define TARGET_NR_rt_sigaction 134 ++#define TARGET_NR_rt_sigprocmask 135 ++#define TARGET_NR_rt_sigpending 136 ++#define TARGET_NR_rt_sigtimedwait 137 ++#define TARGET_NR_rt_sigqueueinfo 138 ++#define TARGET_NR_rt_sigreturn 139 ++#define TARGET_NR_setpriority 140 ++#define TARGET_NR_getpriority 141 ++#define TARGET_NR_reboot 142 ++#define TARGET_NR_setregid 143 ++#define TARGET_NR_setgid 144 ++#define TARGET_NR_setreuid 145 ++#define TARGET_NR_setuid 146 ++#define TARGET_NR_setresuid 147 ++#define TARGET_NR_getresuid 148 ++#define TARGET_NR_setresgid 149 ++#define TARGET_NR_getresgid 150 ++#define TARGET_NR_setfsuid 151 ++#define TARGET_NR_setfsgid 152 ++#define TARGET_NR_times 153 ++#define TARGET_NR_setpgid 154 ++#define TARGET_NR_getpgid 155 ++#define TARGET_NR_getsid 156 ++#define TARGET_NR_setsid 157 ++#define TARGET_NR_getgroups 158 ++#define TARGET_NR_setgroups 159 ++#define TARGET_NR_uname 160 ++#define TARGET_NR_sethostname 161 ++#define TARGET_NR_setdomainname 162 ++#define TARGET_NR_getrlimit 163 ++#define TARGET_NR_setrlimit 164 ++#define TARGET_NR_getrusage 165 ++#define TARGET_NR_umask 166 ++#define TARGET_NR_prctl 167 ++#define TARGET_NR_getcpu 168 ++#define TARGET_NR_gettimeofday 169 ++#define TARGET_NR_settimeofday 170 ++#define TARGET_NR_adjtimex 171 ++#define TARGET_NR_getpid 172 ++#define TARGET_NR_getppid 173 ++#define TARGET_NR_getuid 174 ++#define TARGET_NR_geteuid 175 ++#define TARGET_NR_getgid 176 ++#define TARGET_NR_getegid 177 ++#define TARGET_NR_gettid 178 ++#define TARGET_NR_sysinfo 179 ++#define TARGET_NR_mq_open 180 ++#define TARGET_NR_mq_unlink 181 ++#define TARGET_NR_mq_timedsend 182 ++#define TARGET_NR_mq_timedreceive 183 ++#define TARGET_NR_mq_notify 184 ++#define TARGET_NR_mq_getsetattr 185 ++#define TARGET_NR_msgget 186 ++#define TARGET_NR_msgctl 187 ++#define TARGET_NR_msgrcv 188 ++#define TARGET_NR_msgsnd 189 ++#define TARGET_NR_semget 190 ++#define TARGET_NR_semctl 191 ++#define TARGET_NR_semtimedop 192 ++#define TARGET_NR_semop 193 ++#define TARGET_NR_shmget 194 ++#define TARGET_NR_shmctl 195 ++#define TARGET_NR_shmat 196 ++#define TARGET_NR_shmdt 197 ++#define TARGET_NR_socket 198 ++#define TARGET_NR_socketpair 199 ++#define TARGET_NR_bind 200 ++#define TARGET_NR_listen 201 ++#define TARGET_NR_accept 202 ++#define TARGET_NR_connect 203 ++#define TARGET_NR_getsockname 204 ++#define TARGET_NR_getpeername 205 ++#define TARGET_NR_sendto 206 ++#define TARGET_NR_recvfrom 207 ++#define TARGET_NR_setsockopt 208 ++#define TARGET_NR_getsockopt 209 ++#define TARGET_NR_shutdown 210 ++#define TARGET_NR_sendmsg 211 ++#define TARGET_NR_recvmsg 212 ++#define TARGET_NR_readahead 213 ++#define TARGET_NR_brk 214 ++#define TARGET_NR_munmap 215 ++#define TARGET_NR_mremap 216 ++#define TARGET_NR_add_key 217 ++#define TARGET_NR_request_key 218 ++#define TARGET_NR_keyctl 219 ++#define TARGET_NR_clone 220 ++#define TARGET_NR_execve 221 ++#define TARGET_NR_mmap 222 ++#define TARGET_NR_fadvise64 223 ++#define TARGET_NR_swapon 224 ++#define TARGET_NR_swapoff 225 ++#define TARGET_NR_mprotect 226 ++#define TARGET_NR_msync 227 ++#define TARGET_NR_mlock 228 ++#define TARGET_NR_munlock 229 ++#define TARGET_NR_mlockall 230 ++#define TARGET_NR_munlockall 231 ++#define TARGET_NR_mincore 232 ++#define TARGET_NR_madvise 233 ++#define TARGET_NR_remap_file_pages 234 ++#define TARGET_NR_mbind 235 ++#define TARGET_NR_get_mempolicy 236 ++#define TARGET_NR_set_mempolicy 237 ++#define TARGET_NR_migrate_pages 238 ++#define TARGET_NR_move_pages 239 ++#define TARGET_NR_rt_tgsigqueueinfo 240 ++#define TARGET_NR_perf_event_open 241 ++#define TARGET_NR_accept4 242 ++#define TARGET_NR_recvmmsg 243 ++#define TARGET_NR_arch_specific_syscall 244 ++#define TARGET_NR_wait4 260 ++#define TARGET_NR_prlimit64 261 ++#define TARGET_NR_fanotify_init 262 ++#define TARGET_NR_fanotify_mark 263 ++#define TARGET_NR_name_to_handle_at 264 ++#define TARGET_NR_open_by_handle_at 265 ++#define TARGET_NR_clock_adjtime 266 ++#define TARGET_NR_syncfs 267 ++#define TARGET_NR_setns 268 ++#define TARGET_NR_sendmmsg 269 ++#define TARGET_NR_process_vm_readv 270 ++#define TARGET_NR_process_vm_writev 271 ++#define TARGET_NR_kcmp 272 ++#define TARGET_NR_finit_module 273 ++#define TARGET_NR_sched_setattr 274 ++#define TARGET_NR_sched_getattr 275 ++#define TARGET_NR_renameat2 276 ++#define TARGET_NR_seccomp 277 ++#define TARGET_NR_getrandom 278 ++#define TARGET_NR_memfd_create 279 ++#define TARGET_NR_bpf 280 ++#define TARGET_NR_execveat 281 ++#define TARGET_NR_userfaultfd 282 ++#define TARGET_NR_membarrier 283 ++#define TARGET_NR_mlock2 284 ++#define TARGET_NR_copy_file_range 285 ++#define TARGET_NR_preadv2 286 ++#define TARGET_NR_pwritev2 287 ++#define TARGET_NR_pkey_mprotect 288 ++#define TARGET_NR_pkey_alloc 289 ++#define TARGET_NR_pkey_free 290 ++#define TARGET_NR_statx 291 ++#define TARGET_NR_io_pgetevents 292 ++#define TARGET_NR_rseq 293 ++#define TARGET_NR_kexec_file_load 294 ++ ++#define TARGET_NR_syscalls (TARGET_NR_kexec_file_load + 1) ++ ++#endif +diff --git a/linux-user/loongarch64/target_cpu.h b/linux-user/loongarch64/target_cpu.h +new file mode 100644 +index 0000000000..0f6845737f +--- /dev/null ++++ b/linux-user/loongarch64/target_cpu.h +@@ -0,0 +1,45 @@ ++/* ++ * MIPS specific CPU ABI and functions for linux-user ++ * ++ * Copyright (c) 2004-2005 Jocelyn Mayer ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#ifndef LOONGARCH_TARGET_CPU_H ++#define LOONGARCH_TARGET_CPU_H ++ ++static inline void cpu_clone_regs_child(CPULOONGARCHState *env, target_ulong newsp, ++ unsigned flags) ++{ ++ if (newsp) { ++ env->active_tc.gpr[3] = newsp; ++ } ++ env->active_tc.gpr[7] = 0; ++ env->active_tc.gpr[4] = 0; ++} ++ ++static inline void cpu_clone_regs_parent(CPULOONGARCHState *env, unsigned flags) ++{ ++} ++ ++static inline void cpu_set_tls(CPULOONGARCHState *env, target_ulong newtls) ++{ ++ env->active_tc.gpr[2] = newtls; ++} ++ ++static inline abi_ulong get_sp_from_cpustate(CPULOONGARCHState *state) ++{ ++ return state->active_tc.gpr[3]; ++} ++#endif +diff --git a/linux-user/loongarch64/target_elf.h b/linux-user/loongarch64/target_elf.h +new file mode 100644 +index 0000000000..6c153d12c4 +--- /dev/null ++++ b/linux-user/loongarch64/target_elf.h +@@ -0,0 +1,14 @@ ++/* ++ * 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 LOONGARCH_TARGET_ELF_H ++#define LOONGARCH_TARGET_ELF_H ++static inline const char *cpu_get_model(uint32_t eflags) ++{ ++ return "Loongson-3A5000"; ++} ++#endif +diff --git a/linux-user/loongarch64/target_fcntl.h b/linux-user/loongarch64/target_fcntl.h +new file mode 100644 +index 0000000000..a3d7b46062 +--- /dev/null ++++ b/linux-user/loongarch64/target_fcntl.h +@@ -0,0 +1,13 @@ ++/* ++ * 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 LOONGARCH_TARGET_FCNTL_H ++#define LOONGARCH_TARGET_FCNTL_H ++ ++#include "../generic/fcntl.h" ++ ++#endif /* LOONGARCH_TARGET_FCNTL_H */ +diff --git a/linux-user/loongarch64/target_signal.h b/linux-user/loongarch64/target_signal.h +new file mode 100644 +index 0000000000..e418c8e8f5 +--- /dev/null ++++ b/linux-user/loongarch64/target_signal.h +@@ -0,0 +1,23 @@ ++#ifndef LOONGARCH_TARGET_SIGNAL_H ++#define LOONGARCH_TARGET_SIGNAL_H ++ ++/* this struct defines a stack used during syscall handling */ ++ ++typedef struct target_sigaltstack { ++ abi_long ss_sp; ++ abi_int ss_flags; ++ abi_ulong ss_size; ++} target_stack_t; ++ ++/* ++ * sigaltstack controls ++ */ ++#define TARGET_SS_ONSTACK 1 ++#define TARGET_SS_DISABLE 2 ++ ++#define TARGET_MINSIGSTKSZ 2048 ++#define TARGET_SIGSTKSZ 8192 ++ ++#include "../generic/signal.h" ++ ++#endif /* LOONGARCH_TARGET_SIGNAL_H */ +diff --git a/linux-user/loongarch64/target_structs.h b/linux-user/loongarch64/target_structs.h +new file mode 100644 +index 0000000000..280acd0971 +--- /dev/null ++++ b/linux-user/loongarch64/target_structs.h +@@ -0,0 +1,62 @@ ++/* ++ * LOONGARCH specific structures for linux-user ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#ifndef LOONGARCH_TARGET_STRUCTS_H ++#define LOONGARCH_TARGET_STRUCTS_H ++ ++struct target_ipc_perm { ++ abi_int __key; /* Key. */ ++ abi_uint uid; /* Owner's user ID. */ ++ abi_uint gid; /* Owner's group ID. */ ++ abi_uint cuid; /* Creator's user ID. */ ++ abi_uint cgid; /* Creator's group ID. */ ++ abi_uint mode; /* Read/write permission. */ ++ abi_ushort __seq; /* Sequence number. */ ++ abi_ushort __pad1; ++ abi_ulong __unused1; ++ abi_ulong __unused2; ++}; ++ ++struct target_shmid_ds { ++ struct target_ipc_perm shm_perm; /* operation permission struct */ ++ abi_long shm_segsz; /* size of segment in bytes */ ++ abi_ulong shm_atime; /* time of last shmat() */ ++ abi_ulong shm_dtime; /* time of last shmdt() */ ++ abi_ulong shm_ctime; /* time of last change by shmctl() */ ++ abi_int shm_cpid; /* pid of creator */ ++ abi_int shm_lpid; /* pid of last shmop */ ++ abi_ulong shm_nattch; /* number of current attaches */ ++ abi_ulong __unused1; ++ abi_ulong __unused2; ++}; ++ ++#define TARGET_SEMID64_DS ++ ++/* ++ * The semid64_ds structure for the MIPS architecture. ++ * Note extra padding because this structure is passed back and forth ++ * between kernel and user space. ++ */ ++struct target_semid64_ds { ++ struct target_ipc_perm sem_perm; ++ abi_ulong sem_otime; ++ abi_ulong sem_ctime; ++ abi_ulong sem_nsems; ++ abi_ulong __unused1; ++ abi_ulong __unused2; ++}; ++ ++#endif +diff --git a/linux-user/loongarch64/target_syscall.h b/linux-user/loongarch64/target_syscall.h +new file mode 100644 +index 0000000000..cb77f07080 +--- /dev/null ++++ b/linux-user/loongarch64/target_syscall.h +@@ -0,0 +1,44 @@ ++#ifndef LOONGARCH_TARGET_SYSCALL_H ++#define LOONGARCH_TARGET_SYSCALL_H ++ ++/* this struct defines the way the registers are stored on the ++ stack during a system call. */ ++ ++struct target_pt_regs { ++ /* Saved main processor registers. */ ++ target_ulong regs[32]; ++ ++ /* Saved special registers. */ ++ /* Saved special registers. */ ++ target_ulong csr_crmd; ++ target_ulong csr_prmd; ++ target_ulong csr_euen; ++ target_ulong csr_ecfg; ++ target_ulong csr_estat; ++ target_ulong csr_era; ++ target_ulong csr_badvaddr; ++ target_ulong orig_a0; ++ target_ulong __last[0]; ++}; ++ ++#define UNAME_MACHINE "loongarch" ++#define UNAME_MINIMUM_RELEASE "2.6.32" ++ ++#define TARGET_CLONE_BACKWARDS ++#define TARGET_MINSIGSTKSZ 2048 ++#define TARGET_MLOCKALL_MCL_CURRENT 1 ++#define TARGET_MLOCKALL_MCL_FUTURE 2 ++ ++#define TARGET_FORCE_SHMLBA ++ ++static inline abi_ulong target_shmlba(CPULOONGARCHState *env) ++{ ++ return 0x40000; ++} ++ ++#define TARGET_PR_SET_FP_MODE 45 ++#define TARGET_PR_GET_FP_MODE 46 ++#define TARGET_PR_FP_MODE_FR (1 << 0) ++#define TARGET_PR_FP_MODE_FRE (1 << 1) ++ ++#endif /* LOONGARCH_TARGET_SYSCALL_H */ +diff --git a/linux-user/loongarch64/termbits.h b/linux-user/loongarch64/termbits.h +new file mode 100644 +index 0000000000..6c613a1973 +--- /dev/null ++++ b/linux-user/loongarch64/termbits.h +@@ -0,0 +1,224 @@ ++#ifndef LINUX_USER_LOONGARCH_TERMBITS_H ++#define LINUX_USER_LOONGARCH_TERMBITS_H ++ ++#define TARGET_NCCS 19 ++ ++struct target_termios { ++ unsigned int c_iflag; /* input mode flags */ ++ unsigned int c_oflag; /* output mode flags */ ++ unsigned int c_cflag; /* control mode flags */ ++ unsigned int c_lflag; /* local mode flags */ ++ unsigned char c_line; /* line discipline */ ++ unsigned char c_cc[TARGET_NCCS]; /* control characters */ ++}; ++ ++/* c_iflag bits */ ++#define TARGET_IGNBRK 0000001 ++#define TARGET_BRKINT 0000002 ++#define TARGET_IGNPAR 0000004 ++#define TARGET_PARMRK 0000010 ++#define TARGET_INPCK 0000020 ++#define TARGET_ISTRIP 0000040 ++#define TARGET_INLCR 0000100 ++#define TARGET_IGNCR 0000200 ++#define TARGET_ICRNL 0000400 ++#define TARGET_IUCLC 0001000 ++#define TARGET_IXON 0002000 ++#define TARGET_IXANY 0004000 ++#define TARGET_IXOFF 0010000 ++#define TARGET_IMAXBEL 0020000 ++#define TARGET_IUTF8 0040000 ++ ++/* c_oflag bits */ ++#define TARGET_OPOST 0000001 ++#define TARGET_OLCUC 0000002 ++#define TARGET_ONLCR 0000004 ++#define TARGET_OCRNL 0000010 ++#define TARGET_ONOCR 0000020 ++#define TARGET_ONLRET 0000040 ++#define TARGET_OFILL 0000100 ++#define TARGET_OFDEL 0000200 ++#define TARGET_NLDLY 0000400 ++#define TARGET_NL0 0000000 ++#define TARGET_NL1 0000400 ++#define TARGET_CRDLY 0003000 ++#define TARGET_CR0 0000000 ++#define TARGET_CR1 0001000 ++#define TARGET_CR2 0002000 ++#define TARGET_CR3 0003000 ++#define TARGET_TABDLY 0014000 ++#define TARGET_TAB0 0000000 ++#define TARGET_TAB1 0004000 ++#define TARGET_TAB2 0010000 ++#define TARGET_TAB3 0014000 ++#define TARGET_XTABS 0014000 ++#define TARGET_BSDLY 0020000 ++#define TARGET_BS0 0000000 ++#define TARGET_BS1 0020000 ++#define TARGET_VTDLY 0040000 ++#define TARGET_VT0 0000000 ++#define TARGET_VT1 0040000 ++#define TARGET_FFDLY 0100000 ++#define TARGET_FF0 0000000 ++#define TARGET_FF1 0100000 ++ ++/* c_cflag bit meaning */ ++#define TARGET_CBAUD 0010017 ++#define TARGET_B0 0000000 /* hang up */ ++#define TARGET_B50 0000001 ++#define TARGET_B75 0000002 ++#define TARGET_B110 0000003 ++#define TARGET_B134 0000004 ++#define TARGET_B150 0000005 ++#define TARGET_B200 0000006 ++#define TARGET_B300 0000007 ++#define TARGET_B600 0000010 ++#define TARGET_B1200 0000011 ++#define TARGET_B1800 0000012 ++#define TARGET_B2400 0000013 ++#define TARGET_B4800 0000014 ++#define TARGET_B9600 0000015 ++#define TARGET_B19200 0000016 ++#define TARGET_B38400 0000017 ++#define TARGET_EXTA B19200 ++#define TARGET_EXTB B38400 ++#define TARGET_CSIZE 0000060 ++#define TARGET_CS5 0000000 ++#define TARGET_CS6 0000020 ++#define TARGET_CS7 0000040 ++#define TARGET_CS8 0000060 ++#define TARGET_CSTOPB 0000100 ++#define TARGET_CREAD 0000200 ++#define TARGET_PARENB 0000400 ++#define TARGET_PARODD 0001000 ++#define TARGET_HUPCL 0002000 ++#define TARGET_CLOCAL 0004000 ++#define TARGET_CBAUDEX 0010000 ++#define TARGET_B57600 0010001 ++#define TARGET_B115200 0010002 ++#define TARGET_B230400 0010003 ++#define TARGET_B460800 0010004 ++#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */ ++#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ ++#define TARGET_CRTSCTS 020000000000 /* flow control */ ++ ++/* c_lflag bits */ ++#define TARGET_ISIG 0000001 ++#define TARGET_ICANON 0000002 ++#define TARGET_XCASE 0000004 ++#define TARGET_ECHO 0000010 ++#define TARGET_ECHOE 0000020 ++#define TARGET_ECHOK 0000040 ++#define TARGET_ECHONL 0000100 ++#define TARGET_NOFLSH 0000200 ++#define TARGET_TOSTOP 0000400 ++#define TARGET_ECHOCTL 0001000 ++#define TARGET_ECHOPRT 0002000 ++#define TARGET_ECHOKE 0004000 ++#define TARGET_FLUSHO 0010000 ++#define TARGET_PENDIN 0040000 ++#define TARGET_IEXTEN 0100000 ++ ++/* c_cc character offsets */ ++#define TARGET_VINTR 0 ++#define TARGET_VQUIT 1 ++#define TARGET_VERASE 2 ++#define TARGET_VKILL 3 ++#define TARGET_VEOF 4 ++#define TARGET_VTIME 5 ++#define TARGET_VMIN 6 ++#define TARGET_VSWTC 7 ++#define TARGET_VSTART 8 ++#define TARGET_VSTOP 9 ++#define TARGET_VSUSP 10 ++#define TARGET_VEOL 11 ++#define TARGET_VREPRINT 12 ++#define TARGET_VDISCARD 13 ++#define TARGET_VWERASE 14 ++#define TARGET_VLNEXT 15 ++#define TARGET_VEOL2 16 ++ ++/* ioctls */ ++ ++#define TARGET_TCGETS 0x5401 ++#define TARGET_TCSETS 0x5402 ++#define TARGET_TCSETSW 0x5403 ++#define TARGET_TCSETSF 0x5404 ++#define TARGET_TCGETA 0x5405 ++#define TARGET_TCSETA 0x5406 ++#define TARGET_TCSETAW 0x5407 ++#define TARGET_TCSETAF 0x5408 ++#define TARGET_TCSBRK 0x5409 ++#define TARGET_TCXONC 0x540A ++#define TARGET_TCFLSH 0x540B ++ ++#define TARGET_TIOCEXCL 0x540C ++#define TARGET_TIOCNXCL 0x540D ++#define TARGET_TIOCSCTTY 0x540E ++#define TARGET_TIOCGPGRP 0x540F ++#define TARGET_TIOCSPGRP 0x5410 ++#define TARGET_TIOCOUTQ 0x5411 ++#define TARGET_TIOCSTI 0x5412 ++#define TARGET_TIOCGWINSZ 0x5413 ++#define TARGET_TIOCSWINSZ 0x5414 ++#define TARGET_TIOCMGET 0x5415 ++#define TARGET_TIOCMBIS 0x5416 ++#define TARGET_TIOCMBIC 0x5417 ++#define TARGET_TIOCMSET 0x5418 ++#define TARGET_TIOCGSOFTCAR 0x5419 ++#define TARGET_TIOCSSOFTCAR 0x541A ++#define TARGET_FIONREAD 0x541B ++#define TARGET_TIOCINQ TARGET_FIONREAD ++#define TARGET_TIOCLINUX 0x541C ++#define TARGET_TIOCCONS 0x541D ++#define TARGET_TIOCGSERIAL 0x541E ++#define TARGET_TIOCSSERIAL 0x541F ++#define TARGET_TIOCPKT 0x5420 ++#define TARGET_FIONBIO 0x5421 ++#define TARGET_TIOCNOTTY 0x5422 ++#define TARGET_TIOCSETD 0x5423 ++#define TARGET_TIOCGETD 0x5424 ++#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ ++#define TARGET_TIOCTTYGSTRUCT 0x5426 /* For debugging only */ ++#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ ++#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ ++#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */ ++#define TARGET_TIOCGPTN TARGET_IOR('T', 0x30, unsigned int) ++ /* Get Pty Number (of pty-mux device) */ ++#define TARGET_TIOCSPTLCK TARGET_IOW('T', 0x31, int) ++ /* Lock/unlock Pty */ ++#define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41) ++ /* Safely open the slave */ ++ ++#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */ ++#define TARGET_FIOCLEX 0x5451 ++#define TARGET_FIOASYNC 0x5452 ++#define TARGET_TIOCSERCONFIG 0x5453 ++#define TARGET_TIOCSERGWILD 0x5454 ++#define TARGET_TIOCSERSWILD 0x5455 ++#define TARGET_TIOCGLCKTRMIOS 0x5456 ++#define TARGET_TIOCSLCKTRMIOS 0x5457 ++#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */ ++#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */ ++#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */ ++#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */ ++ ++#define TARGET_TIOCMIWAIT 0x545C ++ /* wait for a change on serial input line(s) */ ++#define TARGET_TIOCGICOUNT 0x545D ++ /* read serial port inline interrupt counts */ ++#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ ++#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ ++ ++/* Used for packet mode */ ++#define TARGET_TIOCPKT_DATA 0 ++#define TARGET_TIOCPKT_FLUSHREAD 1 ++#define TARGET_TIOCPKT_FLUSHWRITE 2 ++#define TARGET_TIOCPKT_STOP 4 ++#define TARGET_TIOCPKT_START 8 ++#define TARGET_TIOCPKT_NOSTOP 16 ++#define TARGET_TIOCPKT_DOSTOP 32 ++ ++#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */ ++ ++#endif +-- +2.27.0 + diff --git a/0006-Add-disas-gdb.patch b/0006-Add-disas-gdb.patch new file mode 100644 index 0000000..00d9b5e --- /dev/null +++ b/0006-Add-disas-gdb.patch @@ -0,0 +1,3183 @@ +From 0789663b3a2ad105a209c7aa36d102a5b05f1397 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Fri, 19 Aug 2022 23:51:12 -0400 +Subject: [PATCH 6/8] Add disas gdb. + +Change-Id: If41c0fc8aa128796e342319c7673fab3ccbf3913 +Signed-off-by: lixianglai +--- + .../devices/loongarch64-softmmu/default.mak | 154 + + configs/targets/loongarch64-softmmu.mak | 4 + + disas/loongarch.c | 2748 +++++++++++++++++ + disas/meson.build | 1 + + gdb-xml/loongarch-base32.xml | 43 + + gdb-xml/loongarch-base64.xml | 43 + + gdb-xml/loongarch-fpu32.xml | 52 + + gdb-xml/loongarch-fpu64.xml | 57 + + 8 files changed, 3102 insertions(+) + create mode 100644 configs/devices/loongarch64-softmmu/default.mak + create mode 100644 configs/targets/loongarch64-softmmu.mak + create mode 100644 disas/loongarch.c + create mode 100644 gdb-xml/loongarch-base32.xml + create mode 100644 gdb-xml/loongarch-base64.xml + create mode 100644 gdb-xml/loongarch-fpu32.xml + create mode 100644 gdb-xml/loongarch-fpu64.xml + +diff --git a/configs/devices/loongarch64-softmmu/default.mak b/configs/devices/loongarch64-softmmu/default.mak +new file mode 100644 +index 0000000000..fcb7e45dd2 +--- /dev/null ++++ b/configs/devices/loongarch64-softmmu/default.mak +@@ -0,0 +1,154 @@ ++# Default configuration for loongarch-softmmu ++ ++CONFIG_PCI=y ++CONFIG_ACPI_PCI=y ++# For now, CONFIG_IDE_CORE requires ISA, so we enable it here ++CONFIG_ISA_BUS=y ++CONFIG_VIRTIO_PCI=y ++ ++CONFIG_VGA_PCI=y ++CONFIG_ACPI_SMBUS=y ++#CONFIG_VHOST_USER_SCSI=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) ++CONFIG_VHOST_USER_SCSI=y ++#CONFIG_VHOST_USER_BLK=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) ++CONFIG_VHOST_USER_BLK=y ++CONFIG_VIRTIO=y ++CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_BLK=y ++CONFIG_VIRTIO_CRYPTO=y ++CONFIG_VIRTIO_GPU=y ++CONFIG_VIRTIO_INPUT=y ++CONFIG_VIRTIO_NET=y ++CONFIG_VIRTIO_RNG=y ++CONFIG_SCSI=y ++CONFIG_VIRTIO_SCSI=y ++CONFIG_VIRTIO_SERIAL=y ++ ++CONFIG_USB_UHCI=y ++CONFIG_USB_OHCI=y ++CONFIG_USB_OHCI_PCI=y ++CONFIG_USB_XHCI=y ++CONFIG_USB_XHCI_NEC=y ++CONFIG_NE2000_PCI=y ++CONFIG_EEPRO100_PCI=y ++CONFIG_PCNET_PCI=y ++CONFIG_PCNET_COMMON=y ++CONFIG_AC97=y ++CONFIG_HDA=y ++CONFIG_ES1370=y ++CONFIG_SCSI=y ++CONFIG_LSI_SCSI_PCI=y ++CONFIG_VMW_PVSCSI_SCSI_PCI=y ++CONFIG_MEGASAS_SCSI_PCI=y ++CONFIG_MPTSAS_SCSI_PCI=y ++CONFIG_RTL8139_PCI=y ++CONFIG_E1000_PCI=y ++CONFIG_IDE_CORE=y ++CONFIG_IDE_QDEV=y ++CONFIG_IDE_PCI=y ++CONFIG_AHCI=y ++CONFIG_AHCI_ICH9=y ++CONFIG_ESP=y ++CONFIG_ESP_PCI=y ++CONFIG_SERIAL=y ++CONFIG_SERIAL_ISA=y ++CONFIG_SERIAL_PCI=y ++CONFIG_CAN_BUS=y ++CONFIG_CAN_SJA1000=y ++CONFIG_CAN_PCI=y ++CONFIG_USB_UHCI=y ++CONFIG_USB_OHCI=y ++CONFIG_USB_XHCI=y ++CONFIG_USB_XHCI_NEC=y ++CONFIG_NE2000_PCI=y ++CONFIG_EEPRO100_PCI=y ++CONFIG_PCNET_PCI=y ++CONFIG_PCNET_COMMON=y ++CONFIG_AC97=y ++CONFIG_HDA=y ++CONFIG_ES1370=y ++CONFIG_SCSI=y ++CONFIG_LSI_SCSI_PCI=y ++CONFIG_VMW_PVSCSI_SCSI_PCI=y ++CONFIG_MEGASAS_SCSI_PCI=y ++CONFIG_MPTSAS_SCSI_PCI=y ++CONFIG_RTL8139_PCI=y ++CONFIG_E1000_PCI=y ++CONFIG_IDE_CORE=y ++CONFIG_IDE_QDEV=y ++CONFIG_IDE_PCI=y ++CONFIG_AHCI=y ++CONFIG_ESP=y ++CONFIG_ESP_PCI=y ++CONFIG_SERIAL=y ++CONFIG_SERIAL_ISA=y ++CONFIG_SERIAL_PCI=y ++CONFIG_CAN_BUS=y ++CONFIG_CAN_SJA1000=y ++CONFIG_CAN_PCI=y ++ ++CONFIG_SPICE=y ++CONFIG_QXL=y ++CONFIG_ESP=y ++CONFIG_SCSI=y ++CONFIG_VGA_ISA=y ++CONFIG_VGA_ISA_MM=y ++CONFIG_VGA_CIRRUS=y ++CONFIG_VMWARE_VGA=y ++CONFIG_VIRTIO_VGA=y ++CONFIG_SERIAL=y ++CONFIG_SERIAL_ISA=y ++CONFIG_PARALLEL=y ++CONFIG_I8254=y ++CONFIG_PCSPK=y ++CONFIG_PCKBD=y ++CONFIG_FDC=y ++CONFIG_ACPI=y ++CONFIG_ACPI_MEMORY_HOTPLUG=y ++CONFIG_ACPI_NVDIMM=y ++CONFIG_ACPI_CPU_HOTPLUG=y ++CONFIG_APM=y ++CONFIG_I8257=y ++CONFIG_PIIX4=y ++CONFIG_IDE_ISA=y ++CONFIG_IDE_PIIX=y ++#CONFIG_NE2000_ISA=y ++CONFIG_MIPSNET=y ++CONFIG_PFLASH_CFI01=y ++CONFIG_I8259=y ++CONFIG_MC146818RTC=y ++CONFIG_ISA_TESTDEV=y ++CONFIG_EMPTY_SLOT=y ++CONFIG_I2C=y ++CONFIG_DIMM=y ++CONFIG_MEM_DEVICE=y ++ ++# Arch Specified CONFIG defines ++CONFIG_IDE_VIA=y ++CONFIG_VT82C686=y ++CONFIG_RC4030=y ++CONFIG_DP8393X=y ++CONFIG_DS1225Y=y ++CONFIG_FITLOADER=y ++CONFIG_SMBIOS=y ++ ++CONFIG_PCIE_PORT=y ++CONFIG_I82801B11=y ++CONFIG_XIO3130=y ++CONFIG_PCI_EXPRESS=y ++CONFIG_MSI_NONBROKEN=y ++CONFIG_IOH3420=y ++CONFIG_SD=y ++CONFIG_SDHCI=y ++CONFIG_VIRTFS=y ++CONFIG_VIRTIO_9P=y ++CONFIG_USB_EHCI=y ++CONFIG_USB_EHCI_PCI=y ++CONFIG_USB_EHCI_SYSBUS=y ++CONFIG_USB_STORAGE_BOT=y ++CONFIG_TPM_EMULATOR=y ++CONFIG_TPM_TIS=y ++CONFIG_PLATFORM_BUS=y ++CONFIG_TPM_TIS_SYSBUS=y ++CONFIG_ACPI_LOONGARCH=y ++CONFIG_LS7A_RTC=y +diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak +new file mode 100644 +index 0000000000..dc5ab39661 +--- /dev/null ++++ b/configs/targets/loongarch64-softmmu.mak +@@ -0,0 +1,4 @@ ++TARGET_ARCH=loongarch64 ++TARGET_SUPPORTS_MTTCG=y ++TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu64.xml ++ +diff --git a/disas/loongarch.c b/disas/loongarch.c +new file mode 100644 +index 0000000000..14dd131e2e +--- /dev/null ++++ b/disas/loongarch.c +@@ -0,0 +1,2748 @@ ++/* ++ * QEMU Loongarch Disassembler ++ * ++ * Copyright (c) 2020-2021. ++ * Author: Song Gao, gaosong@loongson.cn ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2 or later, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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 . ++ */ ++ ++#include "qemu/osdep.h" ++#include "disas/dis-asm.h" ++ ++#define INSNLEN 4 ++ ++/* types */ ++ ++typedef uint16_t la_opcode; ++ ++/* enums */ ++ ++typedef enum { ++ la_op_illegal = 0, ++ la_op_gr2scr = 1, ++ la_op_scr2gr = 2, ++ la_op_clo_w = 3, ++ la_op_clz_w = 4, ++ la_op_cto_w = 5, ++ la_op_ctz_w = 6, ++ la_op_clo_d = 7, ++ la_op_clz_d = 8, ++ la_op_cto_d = 9, ++ la_op_ctz_d = 10, ++ la_op_revb_2h = 11, ++ la_op_revb_4h = 12, ++ la_op_revb_2w = 13, ++ la_op_revb_d = 14, ++ la_op_revh_2w = 15, ++ la_op_revh_d = 16, ++ la_op_bitrev_4b = 17, ++ la_op_bitrev_8b = 18, ++ la_op_bitrev_w = 19, ++ la_op_bitrev_d = 20, ++ la_op_ext_w_h = 21, ++ la_op_ext_w_b = 22, ++ la_op_rdtime_d = 23, ++ la_op_cpucfg = 24, ++ la_op_asrtle_d = 25, ++ la_op_asrtgt_d = 26, ++ la_op_alsl_w = 27, ++ la_op_alsl_wu = 28, ++ la_op_bytepick_w = 29, ++ la_op_bytepick_d = 30, ++ la_op_add_w = 31, ++ la_op_add_d = 32, ++ la_op_sub_w = 33, ++ la_op_sub_d = 34, ++ la_op_slt = 35, ++ la_op_sltu = 36, ++ la_op_maskeqz = 37, ++ la_op_masknez = 38, ++ la_op_nor = 39, ++ la_op_and = 40, ++ la_op_or = 41, ++ la_op_xor = 42, ++ la_op_orn = 43, ++ la_op_andn = 44, ++ la_op_sll_w = 45, ++ la_op_srl_w = 46, ++ la_op_sra_w = 47, ++ la_op_sll_d = 48, ++ la_op_srl_d = 49, ++ la_op_sra_d = 50, ++ la_op_rotr_w = 51, ++ la_op_rotr_d = 52, ++ la_op_mul_w = 53, ++ la_op_mulh_w = 54, ++ la_op_mulh_wu = 55, ++ la_op_mul_d = 56, ++ la_op_mulh_d = 57, ++ la_op_mulh_du = 58, ++ la_op_mulw_d_w = 59, ++ la_op_mulw_d_wu = 60, ++ la_op_div_w = 61, ++ la_op_mod_w = 62, ++ la_op_div_wu = 63, ++ la_op_mod_wu = 64, ++ la_op_div_d = 65, ++ la_op_mod_d = 66, ++ la_op_div_du = 67, ++ la_op_mod_du = 68, ++ la_op_crc_w_b_w = 69, ++ la_op_crc_w_h_w = 70, ++ la_op_crc_w_w_w = 71, ++ la_op_crc_w_d_w = 72, ++ la_op_crcc_w_b_w = 73, ++ la_op_crcc_w_h_w = 74, ++ la_op_crcc_w_w_w = 75, ++ la_op_crcc_w_d_w = 76, ++ la_op_break = 77, ++ la_op_dbcl = 78, ++ la_op_syscall = 79, ++ la_op_alsl_d = 80, ++ la_op_slli_w = 81, ++ la_op_slli_d = 82, ++ la_op_srli_w = 83, ++ la_op_srli_d = 84, ++ la_op_srai_w = 85, ++ la_op_srai_d = 86, ++ la_op_rotri_w = 87, ++ la_op_rotri_d = 88, ++ la_op_bstrins_w = 89, ++ la_op_bstrpick_w = 90, ++ la_op_bstrins_d = 91, ++ la_op_bstrpick_d = 92, ++ la_op_fadd_s = 93, ++ la_op_fadd_d = 94, ++ la_op_fsub_s = 95, ++ la_op_fsub_d = 96, ++ la_op_fmul_s = 97, ++ la_op_fmul_d = 98, ++ la_op_fdiv_s = 99, ++ la_op_fdiv_d = 100, ++ la_op_fmax_s = 101, ++ la_op_fmax_d = 102, ++ la_op_fmin_s = 103, ++ la_op_fmin_d = 104, ++ la_op_fmaxa_s = 105, ++ la_op_fmaxa_d = 106, ++ la_op_fmina_s = 107, ++ la_op_fmina_d = 108, ++ la_op_fscaleb_s = 109, ++ la_op_fscaleb_d = 110, ++ la_op_fcopysign_s = 111, ++ la_op_fcopysign_d = 112, ++ la_op_fabs_s = 113, ++ la_op_fabs_d = 114, ++ la_op_fneg_s = 115, ++ la_op_fneg_d = 116, ++ la_op_flogb_s = 117, ++ la_op_flogb_d = 118, ++ la_op_fclass_s = 119, ++ la_op_fclass_d = 120, ++ la_op_fsqrt_s = 121, ++ la_op_fsqrt_d = 122, ++ la_op_frecip_s = 123, ++ la_op_frecip_d = 124, ++ la_op_frsqrt_s = 125, ++ la_op_frsqrt_d = 126, ++ la_op_fmov_s = 127, ++ la_op_fmov_d = 128, ++ la_op_movgr2fr_w = 129, ++ la_op_movgr2fr_d = 130, ++ la_op_movgr2frh_w = 131, ++ la_op_movfr2gr_s = 132, ++ la_op_movfr2gr_d = 133, ++ la_op_movfrh2gr_s = 134, ++ la_op_movgr2fcsr = 135, ++ la_op_movfcsr2gr = 136, ++ la_op_movfr2cf = 137, ++ la_op_movcf2fr = 138, ++ la_op_movgr2cf = 139, ++ la_op_movcf2gr = 140, ++ la_op_fcvt_s_d = 141, ++ la_op_fcvt_d_s = 142, ++ ++ la_op_ftintrm_w_s = 143, ++ la_op_ftintrm_w_d = 144, ++ la_op_ftintrm_l_s = 145, ++ la_op_ftintrm_l_d = 146, ++ la_op_ftintrp_w_s = 147, ++ la_op_ftintrp_w_d = 148, ++ la_op_ftintrp_l_s = 149, ++ la_op_ftintrp_l_d = 150, ++ la_op_ftintrz_w_s = 151, ++ la_op_ftintrz_w_d = 152, ++ la_op_ftintrz_l_s = 153, ++ la_op_ftintrz_l_d = 154, ++ la_op_ftintrne_w_s = 155, ++ la_op_ftintrne_w_d = 156, ++ la_op_ftintrne_l_s = 157, ++ la_op_ftintrne_l_d = 158, ++ la_op_ftint_w_s = 159, ++ la_op_ftint_w_d = 160, ++ la_op_ftint_l_s = 161, ++ la_op_ftint_l_d = 162, ++ la_op_ffint_s_w = 163, ++ la_op_ffint_s_l = 164, ++ la_op_ffint_d_w = 165, ++ la_op_ffint_d_l = 166, ++ la_op_frint_s = 167, ++ la_op_frint_d = 168, ++ ++ la_op_slti = 169, ++ la_op_sltui = 170, ++ la_op_addi_w = 171, ++ la_op_addi_d = 172, ++ la_op_lu52i_d = 173, ++ la_op_addi = 174, ++ la_op_ori = 175, ++ la_op_xori = 176, ++ ++ la_op_csrxchg = 177, ++ la_op_cacop = 178, ++ la_op_lddir = 179, ++ la_op_ldpte = 180, ++ la_op_iocsrrd_b = 181, ++ la_op_iocsrrd_h = 182, ++ la_op_iocsrrd_w = 183, ++ la_op_iocsrrd_d = 184, ++ la_op_iocsrwr_b = 185, ++ la_op_iocsrwr_h = 186, ++ la_op_iocsrwr_w = 187, ++ la_op_iocsrwr_d = 188, ++ la_op_tlbclr = 189, ++ la_op_tlbflush = 190, ++ la_op_tlbsrch = 191, ++ la_op_tlbrd = 192, ++ la_op_tlbwr = 193, ++ la_op_tlbfill = 194, ++ la_op_ertn = 195, ++ la_op_idle = 196, ++ la_op_invtlb = 197, ++ ++ la_op_fmadd_s = 198, ++ la_op_fmadd_d = 199, ++ la_op_fmsub_s = 200, ++ la_op_fmsub_d = 201, ++ la_op_fnmadd_s = 202, ++ la_op_fnmadd_d = 203, ++ la_op_fnmsub_s = 204, ++ la_op_fnmsub_d = 205, ++ la_op_fcmp_cond_s = 206, ++ la_op_fcmp_cond_d = 207, ++ la_op_fsel = 208, ++ la_op_addu16i_d = 209, ++ la_op_lu12i_w = 210, ++ la_op_lu32i_d = 211, ++ la_op_pcaddi = 212, ++ la_op_pcalau12i = 213, ++ la_op_pcaddu12i = 214, ++ la_op_pcaddu18i = 215, ++ ++ la_op_ll_w = 216, ++ la_op_sc_w = 217, ++ la_op_ll_d = 218, ++ la_op_sc_d = 219, ++ la_op_ldptr_w = 220, ++ la_op_stptr_w = 221, ++ la_op_ldptr_d = 222, ++ la_op_stptr_d = 223, ++ la_op_ld_b = 224, ++ la_op_ld_h = 225, ++ la_op_ld_w = 226, ++ la_op_ld_d = 227, ++ la_op_st_b = 228, ++ la_op_st_h = 229, ++ la_op_st_w = 230, ++ la_op_st_d = 231, ++ la_op_ld_bu = 232, ++ la_op_ld_hu = 233, ++ la_op_ld_wu = 234, ++ la_op_preld = 235, ++ la_op_fld_s = 236, ++ la_op_fst_s = 237, ++ la_op_fld_d = 238, ++ la_op_fst_d = 239, ++ la_op_ldl_w = 240, ++ la_op_ldr_w = 241, ++ la_op_ldl_d = 242, ++ la_op_ldr_d = 243, ++ la_op_stl_d = 244, ++ la_op_str_d = 245, ++ la_op_ldx_b = 246, ++ la_op_ldx_h = 247, ++ la_op_ldx_w = 248, ++ la_op_ldx_d = 249, ++ la_op_stx_b = 250, ++ la_op_stx_h = 251, ++ la_op_stx_w = 252, ++ la_op_stx_d = 253, ++ la_op_ldx_bu = 254, ++ la_op_ldx_hu = 255, ++ la_op_ldx_wu = 256, ++ la_op_fldx_s = 257, ++ la_op_fldx_d = 258, ++ la_op_fstx_s = 259, ++ la_op_fstx_d = 260, ++ ++ la_op_amswap_w = 261, ++ la_op_amswap_d = 262, ++ la_op_amadd_w = 263, ++ la_op_amadd_d = 264, ++ la_op_amand_w = 265, ++ la_op_amand_d = 266, ++ la_op_amor_w = 267, ++ la_op_amor_d = 268, ++ la_op_amxor_w = 269, ++ la_op_amxor_d = 270, ++ la_op_ammax_w = 271, ++ la_op_ammax_d = 272, ++ la_op_ammin_w = 273, ++ la_op_ammin_d = 274, ++ la_op_ammax_wu = 275, ++ la_op_ammax_du = 276, ++ la_op_ammin_wu = 277, ++ la_op_ammin_du = 278, ++ la_op_amswap_db_w = 279, ++ la_op_amswap_db_d = 280, ++ la_op_amadd_db_w = 281, ++ la_op_amadd_db_d = 282, ++ la_op_amand_db_w = 283, ++ la_op_amand_db_d = 284, ++ la_op_amor_db_w = 285, ++ la_op_amor_db_d = 286, ++ la_op_amxor_db_w = 287, ++ la_op_amxor_db_d = 288, ++ la_op_ammax_db_w = 289, ++ la_op_ammax_db_d = 290, ++ la_op_ammin_db_w = 291, ++ la_op_ammin_db_d = 292, ++ la_op_ammax_db_wu = 293, ++ la_op_ammax_db_du = 294, ++ la_op_ammin_db_wu = 295, ++ la_op_ammin_db_du = 296, ++ la_op_dbar = 297, ++ la_op_ibar = 298, ++ la_op_fldgt_s = 299, ++ la_op_fldgt_d = 300, ++ la_op_fldle_s = 301, ++ la_op_fldle_d = 302, ++ la_op_fstgt_s = 303, ++ la_op_fstgt_d = 304, ++ ls_op_fstle_s = 305, ++ la_op_fstle_d = 306, ++ la_op_ldgt_b = 307, ++ la_op_ldgt_h = 308, ++ la_op_ldgt_w = 309, ++ la_op_ldgt_d = 310, ++ la_op_ldle_b = 311, ++ la_op_ldle_h = 312, ++ la_op_ldle_w = 313, ++ la_op_ldle_d = 314, ++ la_op_stgt_b = 315, ++ la_op_stgt_h = 316, ++ la_op_stgt_w = 317, ++ la_op_stgt_d = 318, ++ la_op_stle_b = 319, ++ la_op_stle_h = 320, ++ la_op_stle_w = 321, ++ la_op_stle_d = 322, ++ la_op_beqz = 323, ++ la_op_bnez = 324, ++ la_op_bceqz = 325, ++ la_op_bcnez = 326, ++ la_op_jirl = 327, ++ la_op_b = 328, ++ la_op_bl = 329, ++ la_op_beq = 330, ++ la_op_bne = 331, ++ la_op_blt = 332, ++ la_op_bge = 333, ++ la_op_bltu = 334, ++ la_op_bgeu = 335, ++ ++ /* vz insn */ ++ la_op_hvcl = 336, ++ ++} la_op; ++ ++typedef enum { ++ la_codec_illegal, ++ la_codec_empty, ++ la_codec_2r, ++ la_codec_2r_u5, ++ la_codec_2r_u6, ++ la_codec_2r_2bw, ++ la_codec_2r_2bd, ++ la_codec_3r, ++ la_codec_3r_rd0, ++ la_codec_3r_sa2, ++ la_codec_3r_sa3, ++ la_codec_4r, ++ la_codec_r_im20, ++ la_codec_2r_im16, ++ la_codec_2r_im14, ++ la_codec_2r_im12, ++ la_codec_im5_r_im12, ++ la_codec_2r_im8, ++ la_codec_r_sd, ++ la_codec_r_sj, ++ la_codec_r_cd, ++ la_codec_r_cj, ++ la_codec_r_seq, ++ la_codec_code, ++ la_codec_whint, ++ la_codec_invtlb, ++ la_codec_r_ofs21, ++ la_codec_cj_ofs21, ++ la_codec_ofs26, ++ la_codec_cond, ++ la_codec_sel, ++ ++} la_codec; ++ ++#define la_fmt_illegal "nte" ++#define la_fmt_empty "nt" ++#define la_fmt_sd_rj "ntA,1" ++#define la_fmt_rd_sj "nt0,B" ++#define la_fmt_rd_rj "nt0,1" ++#define la_fmt_rj_rk "nt1,2" ++#define la_fmt_rj_seq "nt1,x" ++#define la_fmt_rd_si20 "nt0,i(x)" ++#define la_fmt_rd_rj_ui5 "nt0,1,C" ++#define la_fmt_rd_rj_ui6 "nt0,1.C" ++#define la_fmt_rd_rj_level "nt0,1,x" ++#define la_fmt_rd_rj_msbw_lsbw "nt0,1,C,D" ++#define la_fmt_rd_rj_msbd_lsbd "nt0,1,C,D" ++#define la_fmt_rd_rj_si12 "nt0,1,i(x)" ++#define la_fmt_hint_rj_si12 "ntE,1,i(x)" ++#define la_fmt_rd_rj_csr "nt0,1,x" ++#define la_fmt_rd_rj_si14 "nt0,1,i(x)" ++#define la_fmt_rd_rj_si16 "nt0,1,i(x)" ++#define la_fmt_rd_rj_rk "nt0,1,2" ++#define la_fmt_fd_rj_rk "nt3,1,2" ++#define la_fmt_rd_rj_rk_sa2 "nt0,1,2,D" ++#define la_fmt_rd_rj_rk_sa3 "nt0,1,2,D" ++#define la_fmt_fd_rj "nt3,1" ++#define la_fmt_rd_fj "nt0,4" ++#define la_fmt_fd_fj "nt3,4" ++#define la_fmt_fd_fj_si12 "nt3,4,i(x)" ++#define la_fmt_fcsrd_rj "ntF,1" ++#define la_fmt_rd_fcsrs "nt0,G" ++#define la_fmt_cd_fj "ntH,4" ++#define la_fmt_fd_cj "nt3,I" ++#define la_fmt_fd_fj_fk "nt3,4,5" ++#define la_fmt_code "ntJ" ++#define la_fmt_whint "ntx" ++#define la_fmt_invtlb "ntx,1,2" /* op,rj,rk */ ++#define la_fmt_offs26 "nto(X)p" ++#define la_fmt_rj_offs21 "nt1,o(X)p" ++#define la_fmt_cj_offs21 "ntQ,o(X)p" ++#define la_fmt_rd_rj_offs16 "nt0,1,o(X)" ++#define la_fmt_rj_rd_offs16 "nt1,0,o(X)p" ++#define la_fmt_s_cd_fj_fk "K.stH,4,5" ++#define la_fmt_d_cd_fj_fk "K.dtH,4,5" ++#define la_fmt_fd_fj_fk_fa "nt3,4,5,6" ++#define la_fmt_fd_fj_fk_ca "nt3,4,5,L" ++#define la_fmt_cop_rj_si12 "ntM,1,i(x)" ++ ++/* structures */ ++ ++typedef struct { ++ uint32_t pc; ++ uint32_t insn; ++ int32_t imm; ++ int32_t imm2; ++ uint16_t op; ++ uint16_t code; ++ uint8_t codec; ++ uint8_t r1; ++ uint8_t r2; ++ uint8_t r3; ++ uint8_t r4; ++ uint8_t bit; ++} la_decode; ++ ++typedef struct { ++ const char * const name; ++ const la_codec codec; ++ const char * const format; ++} la_opcode_data; ++ ++/* reg names */ ++ ++const char * const loongarch_r_normal_name[32] = { ++ "$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", "$r27", "$r28", "$r29", "$r30", "$r31", ++}; ++ ++const char * const loongarch_f_normal_name[32] = { ++ "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", ++ "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", ++ "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", ++ "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", ++}; ++ ++const char * const loongarch_cr_normal_name[4] = { ++ "$scr0", "$scr1", "$scr2", "$scr3", ++}; ++ ++const char * const loongarch_c_normal_name[8] = { ++ "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7", ++}; ++ ++/* instruction data */ ++ ++const la_opcode_data opcode_data[] = { ++ { "illegal", la_codec_illegal, la_fmt_illegal }, ++ { "gr2scr", la_codec_r_sd, la_fmt_sd_rj }, ++ { "scr2gr", la_codec_r_sj, la_fmt_rd_sj }, ++ { "clo.w", la_codec_2r, la_fmt_rd_rj }, ++ { "clz.w", la_codec_2r, la_fmt_rd_rj }, ++ { "cto.w", la_codec_2r, la_fmt_rd_rj }, ++ { "ctz.w", la_codec_2r, la_fmt_rd_rj }, ++ { "clo.d", la_codec_2r, la_fmt_rd_rj }, ++ { "clz.d", la_codec_2r, la_fmt_rd_rj }, ++ { "cto.d", la_codec_2r, la_fmt_rd_rj }, ++ { "ctz_d", la_codec_2r, la_fmt_rd_rj }, ++ { "revb.2h", la_codec_2r, la_fmt_rd_rj }, ++ { "revb.4h", la_codec_2r, la_fmt_rd_rj }, ++ { "revb.2w", la_codec_2r, la_fmt_rd_rj }, ++ { "revb.d", la_codec_2r, la_fmt_rd_rj }, ++ { "revh.2w", la_codec_2r, la_fmt_rd_rj }, ++ { "revh.d", la_codec_2r, la_fmt_rd_rj }, ++ { "bitrev.4b", la_codec_2r, la_fmt_rd_rj }, ++ { "bitrev.8b", la_codec_2r, la_fmt_rd_rj }, ++ { "bitrev.w", la_codec_2r, la_fmt_rd_rj }, ++ { "bitrev.d", la_codec_2r, la_fmt_rd_rj }, ++ { "ext.w.h", la_codec_2r, la_fmt_rd_rj }, ++ { "ext.w.b", la_codec_2r, la_fmt_rd_rj }, ++ { "rdtime.d", la_codec_2r, la_fmt_rd_rj }, ++ { "cpucfg", la_codec_2r, la_fmt_rd_rj }, ++ { "asrtle.d", la_codec_3r_rd0, la_fmt_rj_rk }, ++ { "asrtgt.d", la_codec_3r_rd0, la_fmt_rj_rk }, ++ { "alsl.w", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, ++ { "alsl.wu", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, ++ { "bytepick.w", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, ++ { "bytepick.d", la_codec_3r_sa3, la_fmt_rd_rj_rk_sa3 }, ++ { "add.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "add.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sub.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sub.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "slt", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sltu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "maskeqz", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "masknez", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "nor", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "and", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "or", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "xor", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "orn", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "andn", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sll.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "srl.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sra.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sll.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "srl.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sra.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "rotr.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "rotr.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mul.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mulh.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mulh.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mul.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mulh.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mulh.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mulw.d.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mulw.d.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "div.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mod.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "div.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mod.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "div.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mod.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "div.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mod.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crc.w.b.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crc.w.h.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crc.w.w.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crc.w.d.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crcc.w.b.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crcc.w.h.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crcc.w.w.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crcc.w.d.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "break", la_codec_code, la_fmt_code }, ++ { "dbcl", la_codec_code, la_fmt_code }, ++ { "syscall", la_codec_code, la_fmt_code }, ++ { "alsl.d", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, ++ { "slli.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, ++ { "slli.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, ++ { "srli.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, ++ { "srli.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, ++ { "srai.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, ++ { "srai.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, ++ { "rotri.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, ++ { "rotri.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, ++ { "bstrins.w", la_codec_2r_2bw, la_fmt_rd_rj_msbw_lsbw }, ++ { "bstrpick.w", la_codec_2r_2bw, la_fmt_rd_rj_msbw_lsbw }, ++ { "bstrins.d", la_codec_2r_2bd, la_fmt_rd_rj_msbd_lsbd }, ++ { "bstrpick.d", la_codec_2r_2bd, la_fmt_rd_rj_msbd_lsbd }, ++ { "fadd.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fadd.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fsub.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fsub.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmul.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmul.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fdiv.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fdiv.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmax.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmax.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmin.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmin.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmaxa.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmaxa.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmina.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmina.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fscaleb.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fscaleb.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fcopysign.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fcopysign.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fabs.s", la_codec_2r, la_fmt_fd_fj }, ++ { "fabs.d", la_codec_2r, la_fmt_fd_fj }, ++ { "fneg.s", la_codec_2r, la_fmt_fd_fj }, ++ { "fneg.d", la_codec_2r, la_fmt_fd_fj }, ++ { "flogb.s", la_codec_2r, la_fmt_fd_fj }, ++ { "flogb.d", la_codec_2r, la_fmt_fd_fj }, ++ { "fclass.s", la_codec_2r, la_fmt_fd_fj }, ++ { "fclass.d", la_codec_2r, la_fmt_fd_fj }, ++ { "fsqrt.s", la_codec_2r, la_fmt_fd_fj }, ++ { "fsqrt.d", la_codec_2r, la_fmt_fd_fj }, ++ { "frecip.s", la_codec_2r, la_fmt_fd_fj }, ++ { "frecip.d", la_codec_2r, la_fmt_fd_fj }, ++ { "frsqrt.s", la_codec_2r, la_fmt_fd_fj }, ++ { "frsqrt.d", la_codec_2r, la_fmt_fd_fj }, ++ { "fmov.s", la_codec_2r, la_fmt_fd_fj }, ++ { "fmov.d", la_codec_2r, la_fmt_fd_fj }, ++ { "movgr2fr.w", la_codec_2r, la_fmt_fd_rj }, ++ { "movgr2fr.d", la_codec_2r, la_fmt_fd_rj }, ++ { "movgr2frh.w", la_codec_2r, la_fmt_fd_rj }, ++ { "movfr2gr.s", la_codec_2r, la_fmt_rd_fj }, ++ { "movfr2gr.d", la_codec_2r, la_fmt_rd_fj }, ++ { "movfrh2gr.s", la_codec_2r, la_fmt_rd_fj }, ++ { "movgr2fcsr", la_codec_2r, la_fmt_fcsrd_rj }, ++ { "movfcsr2gr", la_codec_2r, la_fmt_rd_fcsrs }, ++ { "movfr2cf", la_codec_r_cd, la_fmt_cd_fj }, ++ { "movcf2fr", la_codec_r_cj, la_fmt_fd_cj }, ++ { "movgr2cf", la_codec_r_cd, la_fmt_cd_fj }, ++ { "movcf2gr", la_codec_r_cj, la_fmt_fd_cj }, ++ { "fcvt.s.d", la_codec_2r, la_fmt_fd_fj }, ++ { "fcvt.d.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrm.w.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrm.w.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrm.l.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrm.l.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrp.w.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrp.w.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrp.l.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrp.l.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrz.w.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrz.w.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrz.l.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrz.l.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrne.w.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrne.w.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrne.l.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrne.l.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftint.w.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftint.w.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftint.l.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftint.l.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ffint.s.w", la_codec_2r, la_fmt_fd_fj }, ++ { "ffint.s.l", la_codec_2r, la_fmt_fd_fj }, ++ { "ffint.d.w", la_codec_2r, la_fmt_fd_fj }, ++ { "ffint.d.l", la_codec_2r, la_fmt_fd_fj }, ++ { "frint.s", la_codec_2r, la_fmt_fd_fj }, ++ { "frint.d", la_codec_2r, la_fmt_fd_fj }, ++ { "slti", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "sltui", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "addi.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "addi.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "lu52i.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "addi", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ori", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "xori", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "csrxchg", la_codec_2r_im14, la_fmt_rd_rj_csr }, ++ { "cacop", la_codec_im5_r_im12, la_fmt_cop_rj_si12 }, ++ { "lddir", la_codec_2r_im8, la_fmt_rd_rj_level }, ++ { "ldpte", la_codec_r_seq, la_fmt_rj_seq }, ++ { "iocsrrd.b", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrrd.h", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrrd.w", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrrd.d", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrwr.b", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrwr.h", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrwr.w", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrwr.d", la_codec_2r, la_fmt_rd_rj }, ++ { "tlbclr", la_codec_empty, la_fmt_empty }, ++ { "tlbflush", la_codec_empty, la_fmt_empty }, ++ { "tlbsrch", la_codec_empty, la_fmt_empty }, ++ { "tlbrd", la_codec_empty, la_fmt_empty }, ++ { "tlbwr", la_codec_empty, la_fmt_empty }, ++ { "tlbfill", la_codec_empty, la_fmt_empty }, ++ { "ertn", la_codec_empty, la_fmt_empty }, ++ { "idle", la_codec_whint, la_fmt_whint }, ++ { "invtlb", la_codec_invtlb, la_fmt_invtlb }, ++ { "fmadd.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fmadd.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fmsub.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fmsub.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fnmadd.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fnmadd.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fnmsub.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fnmsub.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fcmp.cond.s", la_codec_cond, la_fmt_s_cd_fj_fk }, ++ { "fcmp.cond.d", la_codec_cond, la_fmt_d_cd_fj_fk }, ++ { "fsel", la_codec_sel, la_fmt_fd_fj_fk_ca }, ++ { "addu16i.d", la_codec_2r_im16, la_fmt_rd_rj_si16 }, ++ { "lu12i.w", la_codec_r_im20, la_fmt_rd_si20 }, ++ { "lu32i.d", la_codec_r_im20, la_fmt_rd_si20 }, ++ { "pcaddi", la_codec_r_im20, la_fmt_rd_si20 }, ++ { "pcalau12i", la_codec_r_im20, la_fmt_rd_si20 }, ++ { "pcaddu12i", la_codec_r_im20, la_fmt_rd_si20 }, ++ { "pcaddu18i", la_codec_r_im20, la_fmt_rd_si20 }, ++ { "ll.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "sc.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "ll.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "sc.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "ldptr.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "stptr.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "ldptr.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "stptr.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "ld.b", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ld.h", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ld.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ld.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "st.b", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "st.h", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "st.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "st.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ld.bu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ld.hu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ld.wu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "preld", la_codec_2r_im12, la_fmt_hint_rj_si12 }, ++ { "fld.s", la_codec_2r_im12, la_fmt_fd_fj_si12 }, ++ { "fst.s", la_codec_2r_im12, la_fmt_fd_fj_si12 }, ++ { "fld.d", la_codec_2r_im12, la_fmt_fd_fj_si12 }, ++ { "fst.d", la_codec_2r_im12, la_fmt_fd_fj_si12 }, ++ { "ldl.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ldr.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ldl.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ldr.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "stl.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "str.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ldx.b", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldx.h", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldx.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldx.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stx.b", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stx.h", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stx.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stx.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldx.bu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldx.hu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldx.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "fldx.s", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fldx.d", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fstx.s", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fstx.d", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "amswap.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amswap.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amadd.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amadd.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amand.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amand.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amor.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amor.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amxor.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amxor.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amswap.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amswap.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amadd.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amadd.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amand.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amand.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amor.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amor.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amxor.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amxor.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.db.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.db.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.db.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.db.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "dbar", la_codec_whint, la_fmt_whint }, ++ { "ibar", la_codec_whint, la_fmt_whint }, ++ { "fldgt.s", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fldgt.d", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fldle.s", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fldle.d", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fstgt.s", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fstgt.d", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fstle.s", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fstle.d", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "ldgt.b", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldgt.h", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldgt.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldgt.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldle.b", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldle.h", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldle.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldle.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stgt.b", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stgt.h", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stgt.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stgt.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stle.b", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stle.h", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stle.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stle.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "beqz", la_codec_r_ofs21, la_fmt_rj_offs21 }, ++ { "bnez", la_codec_r_ofs21, la_fmt_rj_offs21 }, ++ { "bceqz", la_codec_cj_ofs21, la_fmt_cj_offs21 }, ++ { "bcnez", la_codec_cj_ofs21, la_fmt_cj_offs21 }, ++ { "jirl", la_codec_2r_im16, la_fmt_rd_rj_offs16 }, ++ { "b", la_codec_ofs26, la_fmt_offs26 }, ++ { "bl", la_codec_ofs26, la_fmt_offs26 }, ++ { "beq", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, ++ { "bne", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, ++ { "blt", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, ++ { "bge", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, ++ { "bltu", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, ++ { "bgeu", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, ++ ++ /* vz insn */ ++ { "hvcl", la_codec_code, la_fmt_code }, ++ ++}; ++ ++ ++/* decode opcode */ ++ ++static void decode_insn_opcode(la_decode *dec) ++{ ++ uint32_t insn = dec->insn; ++ uint16_t op = la_op_illegal; ++ switch ((insn >> 26) & 0x3f) { ++ case 0x0: ++ switch ((insn >> 22) & 0xf) { ++ case 0x0: ++ switch ((insn >> 18) & 0xf) { ++ case 0x0: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x2: ++ switch ((insn >> 2) & 0x7) { ++ case 0x0: ++ op = la_op_gr2scr; ++ break; ++ } ++ break; ++ case 0x3: ++ switch ((insn >> 7) & 0x7) { ++ case 0x0: ++ op = la_op_scr2gr; ++ break; ++ } ++ break; ++ case 0x4: ++ op = la_op_clo_w; ++ break; ++ case 0x5: ++ op = la_op_clz_w; ++ break; ++ case 0x6: ++ op = la_op_cto_w; ++ break; ++ case 0x7: ++ op = la_op_ctz_w; ++ break; ++ case 0x8: ++ op = la_op_clo_d; ++ break; ++ case 0x9: ++ op = la_op_clz_d; ++ break; ++ case 0xa: ++ op = la_op_cto_d; ++ break; ++ case 0xb: ++ op = la_op_ctz_d; ++ break; ++ case 0xc: ++ op = la_op_revb_2h; ++ break; ++ case 0xd: ++ op = la_op_revb_4h; ++ break; ++ case 0xe: ++ op = la_op_revb_2w; ++ break; ++ case 0xf: ++ op = la_op_revb_d; ++ break; ++ case 0x10: ++ op = la_op_revh_2w; ++ break; ++ case 0x11: ++ op = la_op_revh_d; ++ break; ++ case 0x12: ++ op = la_op_bitrev_4b; ++ break; ++ case 0x13: ++ op = la_op_bitrev_8b; ++ break; ++ case 0x14: ++ op = la_op_bitrev_w; ++ break; ++ case 0x15: ++ op = la_op_bitrev_d; ++ break; ++ case 0x16: ++ op = la_op_ext_w_h; ++ break; ++ case 0x17: ++ op = la_op_ext_w_b; ++ break; ++ case 0x1a: ++ op = la_op_rdtime_d; ++ break; ++ case 0x1b: ++ op = la_op_cpucfg; ++ break; ++ } ++ break; ++ case 0x2: ++ switch (insn & 0x0000001f) { ++ case 0x00000000: ++ op = la_op_asrtle_d; ++ break; ++ } ++ break; ++ case 0x3: ++ switch (insn & 0x0000001f) { ++ case 0x00000000: ++ op = la_op_asrtgt_d; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x1: ++ switch ((insn >> 17) & 0x1) { ++ case 0x0: ++ op = la_op_alsl_w; ++ break; ++ case 0x1: ++ op = la_op_alsl_wu; ++ break; ++ } ++ break; ++ case 0x2: ++ switch ((insn >> 17) & 0x1) { ++ case 0x0: ++ op = la_op_bytepick_w; ++ break; ++ } ++ break; ++ case 0x3: ++ op = la_op_bytepick_d; ++ break; ++ case 0x4: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ op = la_op_add_w; ++ break; ++ case 0x1: ++ op = la_op_add_d; ++ break; ++ case 0x2: ++ op = la_op_sub_w; ++ break; ++ case 0x3: ++ op = la_op_sub_d; ++ break; ++ case 0x4: ++ op = la_op_slt; ++ break; ++ case 0x5: ++ op = la_op_sltu; ++ break; ++ case 0x6: ++ op = la_op_maskeqz; ++ break; ++ case 0x7: ++ op = la_op_masknez; ++ break; ++ } ++ break; ++ case 0x5: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ op = la_op_nor; ++ break; ++ case 0x1: ++ op = la_op_and; ++ break; ++ case 0x2: ++ op = la_op_or; ++ break; ++ case 0x3: ++ op = la_op_xor; ++ break; ++ case 0x4: ++ op = la_op_orn; ++ break; ++ case 0x5: ++ op = la_op_andn; ++ break; ++ case 0x6: ++ op = la_op_sll_w; ++ break; ++ case 0x7: ++ op = la_op_srl_w; ++ break; ++ } ++ break; ++ case 0x6: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ op = la_op_sra_w; ++ break; ++ case 0x1: ++ op = la_op_sll_d; ++ break; ++ case 0x2: ++ op = la_op_srl_d; ++ break; ++ case 0x3: ++ op = la_op_sra_d; ++ break; ++ case 0x6: ++ op = la_op_rotr_w; ++ break; ++ case 0x7: ++ op = la_op_rotr_d; ++ break; ++ } ++ break; ++ case 0x7: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ op = la_op_mul_w; ++ break; ++ case 0x1: ++ op = la_op_mulh_w; ++ break; ++ case 0x2: ++ op = la_op_mulh_wu; ++ break; ++ case 0x3: ++ op = la_op_mul_d; ++ break; ++ case 0x4: ++ op = la_op_mulh_d; ++ break; ++ case 0x5: ++ op = la_op_mulh_du; ++ break; ++ case 0x6: ++ op = la_op_mulw_d_w; ++ break; ++ case 0x7: ++ op = la_op_mulw_d_wu; ++ break; ++ } ++ break; ++ case 0x8: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ op = la_op_div_w; ++ break; ++ case 0x1: ++ op = la_op_mod_w; ++ break; ++ case 0x2: ++ op = la_op_div_wu; ++ break; ++ case 0x3: ++ op = la_op_mod_wu; ++ break; ++ case 0x4: ++ op = la_op_div_d; ++ break; ++ case 0x5: ++ op = la_op_mod_d; ++ break; ++ case 0x6: ++ op = la_op_div_du; ++ break; ++ case 0x7: ++ op = la_op_mod_du; ++ break; ++ } ++ break; ++ case 0x9: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ op = la_op_crc_w_b_w; ++ break; ++ case 0x1: ++ op = la_op_crc_w_h_w; ++ break; ++ case 0x2: ++ op = la_op_crc_w_w_w; ++ break; ++ case 0x3: ++ op = la_op_crc_w_d_w; ++ break; ++ case 0x4: ++ op = la_op_crcc_w_b_w; ++ break; ++ case 0x5: ++ op = la_op_crcc_w_h_w; ++ break; ++ case 0x6: ++ op = la_op_crcc_w_w_w; ++ break; ++ case 0x7: ++ op = la_op_crcc_w_d_w; ++ break; ++ } ++ break; ++ case 0xa: ++ switch ((insn >> 15) & 0x7) { ++ case 0x4: ++ op = la_op_break; ++ break; ++ case 0x5: ++ op = la_op_dbcl; ++ break; ++ case 0x6: ++ op = la_op_syscall; ++ break; ++ case 0x7: ++ op = la_op_hvcl; ++ break; ++ } ++ break; ++ case 0xb: ++ switch ((insn >> 17) & 0x1) { ++ case 0x0: ++ op = la_op_alsl_d; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x1: ++ switch ((insn >> 21) & 0x1) { ++ case 0x0: ++ switch ((insn >> 16) & 0x1f) { ++ case 0x0: ++ switch ((insn >> 15) & 0x1) { ++ case 0x1: ++ op = la_op_slli_w; ++ break; ++ } ++ break; ++ case 0x1: ++ op = la_op_slli_d; ++ break; ++ case 0x4: ++ switch ((insn >> 15) & 0x1) { ++ case 0x1: ++ op = la_op_srli_w; ++ break; ++ } ++ break; ++ case 0x5: ++ op = la_op_srli_d; ++ break; ++ case 0x8: ++ switch ((insn >> 15) & 0x1) { ++ case 0x1: ++ op = la_op_srai_w; ++ break; ++ } ++ break; ++ case 0x9: ++ op = la_op_srai_d; ++ break; ++ case 0xc: ++ switch ((insn >> 15) & 0x1) { ++ case 0x1: ++ op = la_op_rotri_w; ++ break; ++ } ++ break; ++ case 0xd: ++ op = la_op_rotri_d; ++ break; ++ } ++ break; ++ case 0x1: ++ switch ((insn >> 15) & 0x1) { ++ case 0x0: ++ op = la_op_bstrins_w; ++ break; ++ case 0x1: ++ op = la_op_bstrpick_w; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x2: ++ op = la_op_bstrins_d; ++ break; ++ case 0x3: ++ op = la_op_bstrpick_d; ++ break; ++ case 0x4: ++ switch ((insn >> 15) & 0x7f) { ++ case 0x1: ++ op = la_op_fadd_s; ++ break; ++ case 0x2: ++ op = la_op_fadd_d; ++ break; ++ case 0x5: ++ op = la_op_fsub_s; ++ break; ++ case 0x6: ++ op = la_op_fsub_d; ++ break; ++ case 0x9: ++ op = la_op_fmul_s; ++ break; ++ case 0xa: ++ op = la_op_fmul_d; ++ break; ++ case 0xd: ++ op = la_op_fdiv_s; ++ break; ++ case 0xe: ++ op = la_op_fdiv_d; ++ break; ++ case 0x11: ++ op = la_op_fmax_s; ++ break; ++ case 0x12: ++ op = la_op_fmax_d; ++ break; ++ case 0x15: ++ op = la_op_fmin_s; ++ break; ++ case 0x16: ++ op = la_op_fmin_d; ++ break; ++ case 0x19: ++ op = la_op_fmaxa_s; ++ break; ++ case 0x1a: ++ op = la_op_fmaxa_d; ++ break; ++ case 0x1d: ++ op = la_op_fmina_s; ++ break; ++ case 0x1e: ++ op = la_op_fmina_d; ++ break; ++ case 0x21: ++ op = la_op_fscaleb_s; ++ break; ++ case 0x22: ++ op = la_op_fscaleb_d; ++ break; ++ case 0x25: ++ op = la_op_fcopysign_s; ++ break; ++ case 0x26: ++ op = la_op_fcopysign_d; ++ break; ++ case 0x28: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x1: ++ op = la_op_fabs_s; ++ break; ++ case 0x2: ++ op = la_op_fabs_d; ++ break; ++ case 0x5: ++ op = la_op_fneg_s; ++ break; ++ case 0x6: ++ op = la_op_fneg_d; ++ break; ++ case 0x9: ++ op = la_op_flogb_s; ++ break; ++ case 0xa: ++ op = la_op_flogb_d; ++ break; ++ case 0xd: ++ op = la_op_fclass_s; ++ break; ++ case 0xe: ++ op = la_op_fclass_d; ++ break; ++ case 0x11: ++ op = la_op_fsqrt_s; ++ break; ++ case 0x12: ++ op = la_op_fsqrt_d; ++ break; ++ case 0x15: ++ op = la_op_frecip_s; ++ break; ++ case 0x16: ++ op = la_op_frecip_d; ++ break; ++ case 0x19: ++ op = la_op_frsqrt_s; ++ break; ++ case 0x1a: ++ op = la_op_frsqrt_d; ++ break; ++ } ++ break; ++ case 0x29: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x5: ++ op = la_op_fmov_s; ++ break; ++ case 0x6: ++ op = la_op_fmov_d; ++ break; ++ case 0x9: ++ op = la_op_movgr2fr_w; ++ break; ++ case 0xa: ++ op = la_op_movgr2fr_d; ++ break; ++ case 0xb: ++ op = la_op_movgr2frh_w; ++ break; ++ case 0xd: ++ op = la_op_movfr2gr_s; ++ break; ++ case 0xe: ++ op = la_op_movfr2gr_d; ++ break; ++ case 0xf: ++ op = la_op_movfrh2gr_s; ++ break; ++ case 0x10: ++ op = la_op_movgr2fcsr; ++ break; ++ case 0x12: ++ op = la_op_movfcsr2gr; ++ break; ++ case 0x14: ++ switch ((insn >> 3) & 0x3) { ++ case 0x0: ++ op = la_op_movfr2cf; ++ break; ++ } ++ break; ++ case 0x15: ++ switch ((insn >> 8) & 0x3) { ++ case 0x0: ++ op = la_op_movcf2fr; ++ break; ++ } ++ break; ++ case 0x16: ++ switch ((insn >> 3) & 0x3) { ++ case 0x0: ++ op = la_op_movgr2cf; ++ break; ++ } ++ break; ++ case 0x17: ++ switch ((insn >> 8) & 0x3) { ++ case 0x0: ++ op = la_op_movcf2gr; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x32: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x6: ++ op = la_op_fcvt_s_d; ++ break; ++ case 0x9: ++ op = la_op_fcvt_d_s; ++ break; ++ } ++ break; ++ case 0x34: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x1: ++ op = la_op_ftintrm_w_s; ++ break; ++ case 0x2: ++ op = la_op_ftintrm_w_d; ++ break; ++ case 0x9: ++ op = la_op_ftintrm_l_s; ++ break; ++ case 0xa: ++ op = la_op_ftintrm_l_d; ++ break; ++ case 0x11: ++ op = la_op_ftintrp_w_s; ++ break; ++ case 0x12: ++ op = la_op_ftintrp_w_d; ++ break; ++ case 0x19: ++ op = la_op_ftintrp_l_s; ++ break; ++ case 0x1a: ++ op = la_op_ftintrp_l_d; ++ break; ++ } ++ break; ++ case 0x35: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x1: ++ op = la_op_ftintrz_w_s; ++ break; ++ case 0x2: ++ op = la_op_ftintrz_w_d; ++ break; ++ case 0x9: ++ op = la_op_ftintrz_l_s; ++ break; ++ case 0xa: ++ op = la_op_ftintrz_l_d; ++ break; ++ case 0x11: ++ op = la_op_ftintrne_w_s; ++ break; ++ case 0x12: ++ op = la_op_ftintrne_w_d; ++ break; ++ case 0x19: ++ op = la_op_ftintrne_l_s; ++ break; ++ case 0x1a: ++ op = la_op_ftintrne_l_d; ++ break; ++ } ++ break; ++ case 0x36: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x1: ++ op = la_op_ftint_w_s; ++ break; ++ case 0x2: ++ op = la_op_ftint_w_d; ++ break; ++ case 0x9: ++ op = la_op_ftint_l_s; ++ break; ++ case 0xa: ++ op = la_op_ftint_l_d; ++ break; ++ } ++ break; ++ case 0x3a: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x4: ++ op = la_op_ffint_s_w; ++ break; ++ case 0x6: ++ op = la_op_ffint_s_l; ++ break; ++ case 0x8: ++ op = la_op_ffint_d_w; ++ break; ++ case 0xa: ++ op = la_op_ffint_d_l; ++ break; ++ } ++ break; ++ case 0x3c: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x11: ++ op = la_op_frint_s; ++ break; ++ case 0x12: ++ op = la_op_frint_d; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x8: ++ op = la_op_slti; ++ break; ++ case 0x9: ++ op = la_op_sltui; ++ break; ++ case 0xa: ++ op = la_op_addi_w; ++ break; ++ case 0xb: ++ op = la_op_addi_d; ++ break; ++ case 0xc: ++ op = la_op_lu52i_d; ++ break; ++ case 0xd: ++ op = la_op_addi; ++ break; ++ case 0xe: ++ op = la_op_ori; ++ break; ++ case 0xf: ++ op = la_op_xori; ++ break; ++ } ++ break; ++ case 0x1: ++ switch ((insn >> 24) & 0x3) { ++ case 0x0: ++ op = la_op_csrxchg; ++ break; ++ case 0x2: ++ switch ((insn >> 22) & 0x3) { ++ case 0x0: ++ op = la_op_cacop; ++ break; ++ case 0x1: ++ switch ((insn >> 18) & 0xf) { ++ case 0x0: ++ op = la_op_lddir; ++ break; ++ case 0x1: ++ switch (insn & 0x0000001f) { ++ case 0x00000000: ++ op = la_op_ldpte; ++ break; ++ } ++ break; ++ case 0x2: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x0: ++ op = la_op_iocsrrd_b; ++ break; ++ case 0x1: ++ op = la_op_iocsrrd_h; ++ break; ++ case 0x2: ++ op = la_op_iocsrrd_w; ++ break; ++ case 0x3: ++ op = la_op_iocsrrd_d; ++ break; ++ case 0x4: ++ op = la_op_iocsrwr_b; ++ break; ++ case 0x5: ++ op = la_op_iocsrwr_h; ++ break; ++ case 0x6: ++ op = la_op_iocsrwr_w; ++ break; ++ case 0x7: ++ op = la_op_iocsrwr_d; ++ break; ++ case 0x8: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_tlbclr; ++ break; ++ } ++ break; ++ case 0x9: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_tlbflush; ++ break; ++ } ++ break; ++ case 0xa: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_tlbsrch; ++ break; ++ } ++ break; ++ case 0xb: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_tlbrd; ++ break; ++ } ++ break; ++ case 0xc: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_tlbwr; ++ break; ++ } ++ break; ++ case 0xd: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_tlbfill; ++ break; ++ } ++ break; ++ case 0xe: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_ertn; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x1: ++ op = la_op_idle; ++ break; ++ case 0x3: ++ op = la_op_invtlb; ++ break; ++ } ++ break; ++ } ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x2: ++ switch ((insn >> 20) & 0x3f) { ++ case 0x1: ++ op = la_op_fmadd_s; ++ break; ++ case 0x2: ++ op = la_op_fmadd_d; ++ break; ++ case 0x5: ++ op = la_op_fmsub_s; ++ break; ++ case 0x6: ++ op = la_op_fmsub_d; ++ break; ++ case 0x9: ++ op = la_op_fnmadd_s; ++ break; ++ case 0xa: ++ op = la_op_fnmadd_d; ++ break; ++ case 0xd: ++ op = la_op_fnmsub_s; ++ break; ++ case 0xe: ++ op = la_op_fnmsub_d; ++ break; ++ } ++ break; ++ case 0x3: ++ switch ((insn >> 20) & 0x3f) { ++ case 0x1: ++ switch ((insn >> 3) & 0x3) { ++ case 0x0: ++ op = la_op_fcmp_cond_s; ++ break; ++ } ++ break; ++ case 0x2: ++ switch ((insn >> 3) & 0x3) { ++ case 0x0: ++ op = la_op_fcmp_cond_d; ++ break; ++ } ++ break; ++ case 0x10: ++ switch ((insn >> 18) & 0x3) { ++ case 0x0: ++ op = la_op_fsel; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x4: ++ op = la_op_addu16i_d; ++ break; ++ case 0x5: ++ switch ((insn >> 25) & 0x1) { ++ case 0x0: ++ op = la_op_lu12i_w; ++ break; ++ case 0x1: ++ op = la_op_lu32i_d; ++ break; ++ } ++ break; ++ case 0x6: ++ switch ((insn >> 25) & 0x1) { ++ case 0x0: ++ op = la_op_pcaddi; ++ break; ++ case 0x1: ++ op = la_op_pcalau12i; ++ break; ++ } ++ break; ++ case 0x7: ++ switch ((insn >> 25) & 0x1) { ++ case 0x0: ++ op = la_op_pcaddu12i; ++ break; ++ case 0x1: ++ op = la_op_pcaddu18i; ++ break; ++ } ++ break; ++ case 0x8: ++ switch ((insn >> 24) & 0x3) { ++ case 0x0: ++ op = la_op_ll_w; ++ break; ++ case 0x1: ++ op = la_op_sc_w; ++ break; ++ case 0x2: ++ op = la_op_ll_d; ++ break; ++ case 0x3: ++ op = la_op_sc_d; ++ break; ++ } ++ break; ++ case 0x9: ++ switch ((insn >> 24) & 0x3) { ++ case 0x0: ++ op = la_op_ldptr_w; ++ break; ++ case 0x1: ++ op = la_op_stptr_w; ++ break; ++ case 0x2: ++ op = la_op_ldptr_d; ++ break; ++ case 0x3: ++ op = la_op_stptr_d; ++ break; ++ } ++ break; ++ case 0xa: ++ switch ((insn >> 22) & 0xf) { ++ case 0x0: ++ op = la_op_ld_b; ++ break; ++ case 0x1: ++ op = la_op_ld_h; ++ break; ++ case 0x2: ++ op = la_op_ld_w; ++ break; ++ case 0x3: ++ op = la_op_ld_d; ++ break; ++ case 0x4: ++ op = la_op_st_b; ++ break; ++ case 0x5: ++ op = la_op_st_h; ++ break; ++ case 0x6: ++ op = la_op_st_w; ++ break; ++ case 0x7: ++ op = la_op_st_d; ++ break; ++ case 0x8: ++ op = la_op_ld_bu; ++ break; ++ case 0x9: ++ op = la_op_ld_hu; ++ break; ++ case 0xa: ++ op = la_op_ld_wu; ++ break; ++ case 0xb: ++ op = la_op_preld; ++ break; ++ case 0xc: ++ op = la_op_fld_s; ++ break; ++ case 0xd: ++ op = la_op_fst_s; ++ break; ++ case 0xe: ++ op = la_op_fld_d; ++ break; ++ case 0xf: ++ op = la_op_fst_d; ++ break; ++ } ++ break; ++ case 0xb: ++ switch ((insn >> 22) & 0xf) { ++ case 0x8: ++ op = la_op_ldl_w; ++ break; ++ case 0x9: ++ op = la_op_ldr_w; ++ break; ++ case 0xa: ++ op = la_op_ldl_d; ++ break; ++ case 0xb: ++ op = la_op_ldr_d; ++ break; ++ case 0xe: ++ op = la_op_stl_d; ++ break; ++ case 0xf: ++ op = la_op_str_d; ++ break; ++ } ++ break; ++ case 0xe: ++ switch ((insn >> 15) & 0x7ff) { ++ case 0x0: ++ op = la_op_ldx_b; ++ break; ++ case 0x8: ++ op = la_op_ldx_h; ++ break; ++ case 0x10: ++ op = la_op_ldx_w; ++ break; ++ case 0x18: ++ op = la_op_ldx_d; ++ break; ++ case 0x20: ++ op = la_op_stx_b; ++ break; ++ case 0x28: ++ op = la_op_stx_h; ++ break; ++ case 0x30: ++ op = la_op_stx_w; ++ break; ++ case 0x38: ++ op = la_op_stx_d; ++ break; ++ case 0x40: ++ op = la_op_ldx_bu; ++ break; ++ case 0x48: ++ op = la_op_ldx_hu; ++ break; ++ case 0x50: ++ op = la_op_ldx_wu; ++ break; ++ case 0x60: ++ op = la_op_fldx_s; ++ break; ++ case 0x68: ++ op = la_op_fldx_d; ++ break; ++ case 0x70: ++ op = la_op_fstx_s; ++ break; ++ case 0x78: ++ op = la_op_fstx_d; ++ break; ++ case 0xc0: ++ op = la_op_amswap_w; ++ break; ++ case 0xc1: ++ op = la_op_amswap_d; ++ break; ++ case 0xc2: ++ op = la_op_amadd_w; ++ break; ++ case 0xc3: ++ op = la_op_amadd_d; ++ break; ++ case 0xc4: ++ op = la_op_amand_w; ++ break; ++ case 0xc5: ++ op = la_op_amand_d; ++ break; ++ case 0xc6: ++ op = la_op_amor_w; ++ break; ++ case 0xc7: ++ op = la_op_amor_d; ++ break; ++ case 0xc8: ++ op = la_op_amxor_w; ++ break; ++ case 0xc9: ++ op = la_op_amxor_d; ++ break; ++ case 0xca: ++ op = la_op_ammax_w; ++ break; ++ case 0xcb: ++ op = la_op_ammax_d; ++ break; ++ case 0xcc: ++ op = la_op_ammin_w; ++ break; ++ case 0xcd: ++ op = la_op_ammin_d; ++ break; ++ case 0xce: ++ op = la_op_ammax_wu; ++ break; ++ case 0xcf: ++ op = la_op_ammax_du; ++ break; ++ case 0xd0: ++ op = la_op_ammin_wu; ++ break; ++ case 0xd1: ++ op = la_op_ammin_du; ++ break; ++ case 0xd2: ++ op = la_op_amswap_db_w; ++ break; ++ case 0xd3: ++ op = la_op_amswap_db_d; ++ break; ++ case 0xd4: ++ op = la_op_amadd_db_w; ++ break; ++ case 0xd5: ++ op = la_op_amadd_db_d; ++ break; ++ case 0xd6: ++ op = la_op_amand_db_w; ++ break; ++ case 0xd7: ++ op = la_op_amand_db_d; ++ break; ++ case 0xd8: ++ op = la_op_amor_db_w; ++ break; ++ case 0xd9: ++ op = la_op_amor_db_d; ++ break; ++ case 0xda: ++ op = la_op_amxor_db_w; ++ break; ++ case 0xdb: ++ op = la_op_amxor_db_d; ++ break; ++ case 0xdc: ++ op = la_op_ammax_db_w; ++ break; ++ case 0xdd: ++ op = la_op_ammax_db_d; ++ break; ++ case 0xde: ++ op = la_op_ammin_db_w; ++ break; ++ case 0xdf: ++ op = la_op_ammin_db_d; ++ break; ++ case 0xe0: ++ op = la_op_ammax_db_wu; ++ break; ++ case 0xe1: ++ op = la_op_ammax_db_du; ++ break; ++ case 0xe2: ++ op = la_op_ammin_db_wu; ++ break; ++ case 0xe3: ++ op = la_op_ammin_db_du; ++ break; ++ case 0xe4: ++ op = la_op_dbar; ++ break; ++ case 0xe5: ++ op = la_op_ibar; ++ break; ++ case 0xe8: ++ op = la_op_fldgt_s; ++ break; ++ case 0xe9: ++ op = la_op_fldgt_d; ++ break; ++ case 0xea: ++ op = la_op_fldle_s; ++ break; ++ case 0xeb: ++ op = la_op_fldle_d; ++ break; ++ case 0xec: ++ op = la_op_fstgt_s; ++ break; ++ case 0xed: ++ op = la_op_fstgt_d; ++ break; ++ case 0xee: ++ op = ls_op_fstle_s; ++ break; ++ case 0xef: ++ op = la_op_fstle_d; ++ break; ++ case 0xf0: ++ op = la_op_ldgt_b; ++ break; ++ case 0xf1: ++ op = la_op_ldgt_h; ++ break; ++ case 0xf2: ++ op = la_op_ldgt_w; ++ break; ++ case 0xf3: ++ op = la_op_ldgt_d; ++ break; ++ case 0xf4: ++ op = la_op_ldle_b; ++ break; ++ case 0xf5: ++ op = la_op_ldle_h; ++ break; ++ case 0xf6: ++ op = la_op_ldle_w; ++ break; ++ case 0xf7: ++ op = la_op_ldle_d; ++ break; ++ case 0xf8: ++ op = la_op_stgt_b; ++ break; ++ case 0xf9: ++ op = la_op_stgt_h; ++ break; ++ case 0xfa: ++ op = la_op_stgt_w; ++ break; ++ case 0xfb: ++ op = la_op_stgt_d; ++ break; ++ case 0xfc: ++ op = la_op_stle_b; ++ break; ++ case 0xfd: ++ op = la_op_stle_h; ++ break; ++ case 0xfe: ++ op = la_op_stle_w; ++ break; ++ case 0xff: ++ op = la_op_stle_d; ++ break; ++ } ++ break; ++ case 0x10: ++ op = la_op_beqz; ++ break; ++ case 0x11: ++ op = la_op_bnez; ++ break; ++ case 0x12: ++ switch ((insn >> 8) & 0x3) { ++ case 0x0: ++ op = la_op_bceqz; ++ break; ++ case 0x1: ++ op = la_op_bcnez; ++ break; ++ } ++ break; ++ case 0x13: ++ op = la_op_jirl; ++ break; ++ case 0x14: ++ op = la_op_b; ++ break; ++ case 0x15: ++ op = la_op_bl; ++ break; ++ case 0x16: ++ op = la_op_beq; ++ break; ++ case 0x17: ++ op = la_op_bne; ++ break; ++ case 0x18: ++ op = la_op_blt; ++ break; ++ case 0x19: ++ op = la_op_bge; ++ break; ++ case 0x1a: ++ op = la_op_bltu; ++ break; ++ case 0x1b: ++ op = la_op_bgeu; ++ break; ++ default: ++ op = la_op_illegal; ++ break; ++ } ++ dec->op = op; ++} ++ ++/* operand extractors */ ++ ++#define IM_5 5 ++#define IM_8 8 ++#define IM_12 12 ++#define IM_14 14 ++#define IM_15 15 ++#define IM_16 16 ++#define IM_20 20 ++#define IM_21 21 ++#define IM_26 26 ++ ++static uint32_t operand_r1(uint32_t insn) ++{ ++ return insn & 0x1f; ++} ++ ++static uint32_t operand_r2(uint32_t insn) ++{ ++ return (insn >> 5) & 0x1f; ++} ++ ++static uint32_t operand_r3(uint32_t insn) ++{ ++ return (insn >> 10) & 0x1f; ++} ++ ++static uint32_t operand_r4(uint32_t insn) ++{ ++ return (insn >> 15) & 0x1f; ++} ++ ++static uint32_t operand_u6(uint32_t insn) ++{ ++ return (insn >> 10) & 0x3f; ++} ++ ++static uint32_t operand_bw1(uint32_t insn) ++{ ++ return (insn >> 10) & 0x1f; ++} ++ ++static uint32_t operand_bw2(uint32_t insn) ++{ ++ return (insn >> 16) & 0x1f; ++} ++ ++static uint32_t operand_bd1(uint32_t insn) ++{ ++ return (insn >> 10) & 0x3f; ++} ++ ++static uint32_t operand_bd2(uint32_t insn) ++{ ++ return (insn >> 16) & 0x3f; ++} ++ ++static uint32_t operand_sa2(uint32_t insn) ++{ ++ return (insn >> 15) & 0x3; ++} ++ ++static uint32_t operand_sa3(uint32_t insn) ++{ ++ return (insn >> 15) & 0x3; ++} ++ ++static int32_t operand_im20(uint32_t insn) ++{ ++ int32_t imm = (int32_t)((insn >> 5) & 0xfffff); ++ return imm > (1 << 19) ? imm - (1 << 20) : imm; ++} ++ ++static int32_t operand_im16(uint32_t insn) ++{ ++ int32_t imm = (int32_t)((insn >> 10) & 0xffff); ++ return imm > (1 << 15) ? imm - (1 << 16) : imm; ++} ++ ++static int32_t operand_im14(uint32_t insn) ++{ ++ int32_t imm = (int32_t)((insn >> 10) & 0x3fff); ++ return imm > (1 << 13) ? imm - (1 << 14) : imm; ++} ++ ++static int32_t operand_im12(uint32_t insn) ++{ ++ int32_t imm = (int32_t)((insn >> 10) & 0xfff); ++ return imm > (1 << 11) ? imm - (1 << 12) : imm; ++} ++ ++static int32_t operand_im8(uint32_t insn) ++{ ++ int32_t imm = (int32_t)((insn >> 10) & 0xff); ++ return imm > (1 << 7) ? imm - (1 << 8) : imm; ++} ++ ++static uint32_t operand_sd(uint32_t insn) ++{ ++ return insn & 0x3; ++} ++ ++static uint32_t operand_sj(uint32_t insn) ++{ ++ return (insn >> 5) & 0x3; ++} ++ ++static uint32_t operand_cd(uint32_t insn) ++{ ++ return insn & 0x7; ++} ++ ++static uint32_t operand_cj(uint32_t insn) ++{ ++ return (insn >> 5) & 0x7; ++} ++ ++static uint32_t operand_code(uint32_t insn) ++{ ++ return insn & 0x7fff; ++} ++ ++static int32_t operand_whint(uint32_t insn) ++{ ++ int32_t imm = (int32_t)(insn & 0x7fff); ++ return imm > (1 << 14) ? imm - (1 << 15) : imm; ++} ++ ++static int32_t operand_invop(uint32_t insn) ++{ ++ int32_t imm = (int32_t)(insn & 0x1f); ++ return imm > (1 << 4) ? imm - (1 << 5) : imm; ++} ++ ++static int32_t operand_ofs21(uint32_t insn) ++{ ++ int32_t imm = (((int32_t)insn & 0x1f) << 16) | ++ ((insn >> 10) & 0xffff); ++ return imm > (1 << 20) ? imm - (1 << 21) : imm; ++} ++ ++static int32_t operand_ofs26(uint32_t insn) ++{ ++ int32_t imm = (((int32_t)insn & 0x3ff) << 16) | ++ ((insn >> 10) & 0xffff); ++ return imm > (1 << 25) ? imm - (1 << 26) : imm; ++} ++ ++static uint32_t operand_fcond(uint32_t insn) ++{ ++ return (insn >> 15) & 0x1f; ++} ++ ++static uint32_t operand_sel(uint32_t insn) ++{ ++ return (insn >> 15) & 0x7; ++} ++ ++/* decode operands */ ++ ++static void decode_insn_operands(la_decode *dec) ++{ ++ uint32_t insn = dec->insn; ++ dec->codec = opcode_data[dec->op].codec; ++ switch (dec->codec) { ++ case la_codec_illegal: ++ case la_codec_empty: ++ break; ++ case la_codec_2r: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ break; ++ case la_codec_2r_u5: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ break; ++ case la_codec_2r_u6: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_u6(insn); ++ break; ++ case la_codec_2r_2bw: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_bw1(insn); ++ dec->r4 = operand_bw2(insn); ++ break; ++ case la_codec_2r_2bd: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_bd1(insn); ++ dec->r4 = operand_bd2(insn); ++ break; ++ case la_codec_3r: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ break; ++ case la_codec_3r_rd0: ++ dec->r1 = 0; ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ break; ++ case la_codec_3r_sa2: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ dec->r4 = operand_sa2(insn); ++ break; ++ case la_codec_3r_sa3: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ dec->r4 = operand_sa3(insn); ++ break; ++ case la_codec_4r: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ dec->r4 = operand_r4(insn); ++ break; ++ case la_codec_r_im20: ++ dec->r1 = operand_r1(insn); ++ dec->imm = operand_im20(insn); ++ dec->bit = IM_20; ++ break; ++ case la_codec_2r_im16: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->imm = operand_im16(insn); ++ dec->bit = IM_16; ++ break; ++ case la_codec_2r_im14: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->imm = operand_im14(insn); ++ dec->bit = IM_14; ++ break; ++ case la_codec_im5_r_im12: ++ dec->imm2 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->imm = operand_im12(insn); ++ dec->bit = IM_12; ++ break; ++ case la_codec_2r_im12: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->imm = operand_im12(insn); ++ dec->bit = IM_12; ++ break; ++ case la_codec_2r_im8: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->imm = operand_im8(insn); ++ dec->bit = IM_8; ++ break; ++ case la_codec_r_sd: ++ dec->r1 = operand_sd(insn); ++ dec->r2 = operand_r2(insn); ++ break; ++ case la_codec_r_sj: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_sj(insn); ++ break; ++ case la_codec_r_cd: ++ dec->r1 = operand_cd(insn); ++ dec->r2 = operand_r2(insn); ++ break; ++ case la_codec_r_cj: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_cj(insn); ++ break; ++ case la_codec_r_seq: ++ dec->r1 = 0; ++ dec->r2 = operand_r1(insn); ++ dec->imm = operand_im8(insn); ++ dec->bit = IM_8; ++ break; ++ case la_codec_code: ++ dec->code = operand_code(insn); ++ break; ++ case la_codec_whint: ++ dec->imm = operand_whint(insn); ++ dec->bit = IM_15; ++ break; ++ case la_codec_invtlb: ++ dec->imm = operand_invop(insn); ++ dec->bit = IM_5; ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ break; ++ case la_codec_r_ofs21: ++ dec->imm = operand_ofs21(insn); ++ dec->bit = IM_21; ++ dec->r2 = operand_r2(insn); ++ break; ++ case la_codec_cj_ofs21: ++ dec->imm = operand_ofs21(insn); ++ dec->bit = IM_21; ++ dec->r2 = operand_cj(insn); ++ break; ++ case la_codec_ofs26: ++ dec->imm = operand_ofs26(insn); ++ dec->bit = IM_26; ++ break; ++ case la_codec_cond: ++ dec->r1 = operand_cd(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ dec->r4 = operand_fcond(insn); ++ break; ++ case la_codec_sel: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ dec->r4 = operand_sel(insn); ++ break; ++ } ++} ++ ++/* format instruction */ ++ ++static void append(char *s1, const char *s2, size_t n) ++{ ++ size_t l1 = strlen(s1); ++ if (n - l1 - 1 > 0) { ++ strncat(s1, s2, n - l1); ++ } ++} ++ ++static void format_insn(char *buf, size_t buflen, size_t tab, la_decode *dec) ++{ ++ char tmp[16]; ++ const char *fmt; ++ ++ fmt = opcode_data[dec->op].format; ++ while (*fmt) { ++ switch (*fmt) { ++ case 'n': /* name */ ++ append(buf, opcode_data[dec->op].name, buflen); ++ break; ++ case 's': ++ append(buf, "s", buflen); ++ break; ++ case 'd': ++ append(buf, "d", buflen); ++ break; ++ case 'e': /* illegal */ ++ snprintf(tmp, sizeof(tmp), "%x", dec->insn); ++ append(buf, tmp, buflen); ++ break; ++ case 't': ++ while (strlen(buf) < tab) { ++ append(buf, " ", buflen); ++ } ++ break; ++ case '(': ++ append(buf, "(", buflen); ++ break; ++ case ',': ++ append(buf, ",", buflen); ++ break; ++ case '.': ++ append(buf, ".", buflen); ++ break; ++ case ')': ++ append(buf, ")", buflen); ++ break; ++ case '0': /* rd */ ++ append(buf, loongarch_r_normal_name[dec->r1], buflen); ++ break; ++ case '1': /* rj */ ++ append(buf, loongarch_r_normal_name[dec->r2], buflen); ++ break; ++ case '2': /* rk */ ++ append(buf, loongarch_r_normal_name[dec->r3], buflen); ++ break; ++ case '3': /* fd */ ++ append(buf, loongarch_f_normal_name[dec->r1], buflen); ++ break; ++ case '4': /* fj */ ++ append(buf, loongarch_f_normal_name[dec->r2], buflen); ++ break; ++ case '5': /* fk */ ++ append(buf, loongarch_f_normal_name[dec->r3], buflen); ++ break; ++ case '6': /* fa */ ++ append(buf, loongarch_f_normal_name[dec->r4], buflen); ++ break; ++ case 'A': /* sd */ ++ append(buf, loongarch_cr_normal_name[dec->r1], buflen); ++ break; ++ case 'B': /* sj */ ++ append(buf, loongarch_cr_normal_name[dec->r2], buflen); ++ break; ++ case 'C': /* r3 */ ++ snprintf(tmp, sizeof(tmp), "%x", dec->r3); ++ append(buf, tmp, buflen); ++ break; ++ case 'D': /* r4 */ ++ snprintf(tmp, sizeof(tmp), "%x", dec->r4); ++ append(buf, tmp, buflen); ++ break; ++ case 'E': /* r1 */ ++ snprintf(tmp, sizeof(tmp), "%x", dec->r1); ++ append(buf, tmp, buflen); ++ break; ++ case 'F': /* fcsrd */ ++ append(buf, loongarch_r_normal_name[dec->r1], buflen); ++ break; ++ case 'G': /* fcsrs */ ++ append(buf, loongarch_r_normal_name[dec->r2], buflen); ++ break; ++ case 'H': /* cd */ ++ append(buf, loongarch_c_normal_name[dec->r1], buflen); ++ break; ++ case 'I': /* cj */ ++ append(buf, loongarch_c_normal_name[dec->r2], buflen); ++ break; ++ case 'J': /* code */ ++ snprintf(tmp, sizeof(tmp), "0x%x", dec->code); ++ append(buf, tmp, buflen); ++ break; ++ case 'K': /* cond */ ++ switch (dec->r4) { ++ case 0x0: ++ append(buf, "caf", buflen); ++ break; ++ case 0x1: ++ append(buf, "saf", buflen); ++ break; ++ case 0x2: ++ append(buf, "clt", buflen); ++ break; ++ case 0x3: ++ append(buf, "slt", buflen); ++ break; ++ case 0x4: ++ append(buf, "ceq", buflen); ++ break; ++ case 0x5: ++ append(buf, "seq", buflen); ++ break; ++ case 0x6: ++ append(buf, "cle", buflen); ++ break; ++ case 0x7: ++ append(buf, "sle", buflen); ++ break; ++ case 0x8: ++ append(buf, "cun", buflen); ++ break; ++ case 0x9: ++ append(buf, "sun", buflen); ++ break; ++ case 0xA: ++ append(buf, "cult", buflen); ++ break; ++ case 0xB: ++ append(buf, "sult", buflen); ++ break; ++ case 0xC: ++ append(buf, "cueq", buflen); ++ break; ++ case 0xD: ++ append(buf, "sueq", buflen); ++ break; ++ case 0xE: ++ append(buf, "cule", buflen); ++ break; ++ case 0xF: ++ append(buf, "sule", buflen); ++ break; ++ case 0x10: ++ append(buf, "cne", buflen); ++ break; ++ case 0x11: ++ append(buf, "sne", buflen); ++ break; ++ case 0x14: ++ append(buf, "cor", buflen); ++ break; ++ case 0x15: ++ append(buf, "sor", buflen); ++ break; ++ case 0x18: ++ append(buf, "cune", buflen); ++ break; ++ case 0x19: ++ append(buf, "sune", buflen); ++ break; ++ } ++ break; ++ case 'L': /* ca */ ++ append(buf, loongarch_c_normal_name[dec->r4], buflen); ++ break; ++ case 'M': /* cop */ ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm2) & 0x1f); ++ append(buf, tmp, buflen); ++ break; ++ case 'i': /* sixx d */ ++ snprintf(tmp, sizeof(tmp), "%d", dec->imm); ++ append(buf, tmp, buflen); ++ break; ++ case 'o': /* offset */ ++ snprintf(tmp, sizeof(tmp), "%d", (dec->imm) << 2); ++ append(buf, tmp, buflen); ++ break; ++ case 'x': /* sixx x */ ++ switch (dec->bit) { ++ case IM_5: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x1f); ++ append(buf, tmp, buflen); ++ break; ++ case IM_8: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_12: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xfff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_14: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x3fff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_15: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x7fff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_16: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xffff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_20: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xfffff); ++ append(buf, tmp, buflen); ++ break; ++ default: ++ snprintf(tmp, sizeof(tmp), "0x%x", dec->imm); ++ append(buf, tmp, buflen); ++ break; ++ } ++ break; ++ case 'X': /* offset x*/ ++ switch (dec->bit) { ++ case IM_16: ++ snprintf(tmp, sizeof(tmp), "0x%x", ++ ((dec->imm) << 2) & 0xffff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_21: ++ snprintf(tmp, sizeof(tmp), "0x%x", ++ ((dec->imm) << 2) & 0x1fffff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_26: ++ snprintf(tmp, sizeof(tmp), "0x%x", ++ ((dec->imm) << 2) & 0x3ffffff); ++ append(buf, tmp, buflen); ++ break; ++ default: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) << 2); ++ append(buf, tmp, buflen); ++ break; ++ } ++ break; ++ case 'p': /* pc */ ++ snprintf(tmp, sizeof(tmp), " # 0x%"PRIx32"", ++ dec->pc + ((dec->imm) << 2)); ++ append(buf, tmp, buflen); ++ break; ++ default: ++ break; ++ } ++ fmt++; ++ } ++} ++ ++ ++/* disassemble instruction */ ++ ++static void ++disasm_insn(char *buf, size_t buflen, bfd_vma pc, unsigned long int insn) ++{ ++ la_decode dec = { 0 }; ++ dec.pc = pc; ++ dec.insn = insn; ++ decode_insn_opcode(&dec); ++ decode_insn_operands(&dec); ++ format_insn(buf, buflen, 16, &dec); ++} ++ ++int ++print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info) ++{ ++ char buf[128] = { 0 }; ++ bfd_byte buffer[INSNLEN]; ++ unsigned long insn; ++ int status; ++ ++ status = (*info->read_memory_func)(memaddr, buffer, INSNLEN, info); ++ if (status == 0) { ++ insn = (uint32_t) bfd_getl32(buffer); ++ (*info->fprintf_func)(info->stream, "%08" PRIx64 " ", insn); ++ } else { ++ (*info->memory_error_func)(status, memaddr, info); ++ return -1; ++ } ++ disasm_insn(buf, sizeof(buf), memaddr, insn); ++ (*info->fprintf_func)(info->stream, "\t%s", buf); ++ return INSNLEN; ++} +diff --git a/disas/meson.build b/disas/meson.build +index 449f99e1de..06a69d9d72 100644 +--- a/disas/meson.build ++++ b/disas/meson.build +@@ -12,6 +12,7 @@ common_ss.add(when: 'CONFIG_I386_DIS', if_true: files('i386.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_LOONGARCH_DIS', if_true: files('loongarch.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/gdb-xml/loongarch-base32.xml b/gdb-xml/loongarch-base32.xml +new file mode 100644 +index 0000000000..04891e023f +--- /dev/null ++++ b/gdb-xml/loongarch-base32.xml +@@ -0,0 +1,43 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb-xml/loongarch-base64.xml b/gdb-xml/loongarch-base64.xml +new file mode 100644 +index 0000000000..6308fb6ecb +--- /dev/null ++++ b/gdb-xml/loongarch-base64.xml +@@ -0,0 +1,43 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb-xml/loongarch-fpu32.xml b/gdb-xml/loongarch-fpu32.xml +new file mode 100644 +index 0000000000..a5b4d80e6c +--- /dev/null ++++ b/gdb-xml/loongarch-fpu32.xml +@@ -0,0 +1,52 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb-xml/loongarch-fpu64.xml b/gdb-xml/loongarch-fpu64.xml +new file mode 100644 +index 0000000000..74ab55a015 +--- /dev/null ++++ b/gdb-xml/loongarch-fpu64.xml +@@ -0,0 +1,57 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.27.0 + diff --git a/0007-Modify-kvm-cpu-vga-qapi.patch b/0007-Modify-kvm-cpu-vga-qapi.patch new file mode 100644 index 0000000..c2b94f1 --- /dev/null +++ b/0007-Modify-kvm-cpu-vga-qapi.patch @@ -0,0 +1,480 @@ +From 6e52e755bd54efb15afa052dac6dd0c7f696e366 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Sat, 20 Aug 2022 02:18:41 -0400 +Subject: [PATCH 7/8] Modify kvm cpu vga qapi. + +Change-Id: I7923af804bdbe6d44d3f521df1859aa081afceba +Signed-off-by: lixianglai +Signed-off-by: Mao Bibo +--- + hw/acpi/cpu.c | 11 ++++++ + hw/loongarch/iocsr.c | 2 ++ + hw/loongarch/larch_3a.c | 18 +++++----- + hw/meson.build | 1 + + include/disas/dis-asm.h | 1 + + include/elf.h | 2 ++ + include/hw/loongarch/larch.h | 1 - + include/qemu/osdep.h | 3 ++ + include/sysemu/arch_init.h | 1 + + linux-headers/linux/kvm.h | 23 ++++++++++++ + linux-user/elfload.c | 67 +++++++++++++++++++++++++++++++++++ + linux-user/meson.build | 1 + + linux-user/qemu.h | 2 +- + linux-user/syscall.c | 3 ++ + linux-user/syscall_defs.h | 9 ++--- + meson.build | 1 + + pc-bios/loongarch_bios.bin | Bin 0 -> 4190208 bytes + pc-bios/meson.build | 1 + + qapi/machine-target.json | 6 ++-- + qapi/machine.json | 2 +- + qapi/misc-target.json | 1 + + 21 files changed, 138 insertions(+), 18 deletions(-) + create mode 100644 pc-bios/loongarch_bios.bin + +diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c +index b20903ea30..cd73fab65b 100644 +--- a/hw/acpi/cpu.c ++++ b/hw/acpi/cpu.c +@@ -371,14 +371,25 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, + aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0)); + + crs = aml_resource_template(); ++#ifdef __loongarch__ ++ aml_append(crs, aml_memory32_fixed(io_base, ++ ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE)); ++#else + aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1, + ACPI_CPU_HOTPLUG_REG_LEN)); ++#endif + aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs)); + + /* declare CPU hotplug MMIO region with related access fields */ ++#ifdef __loongarch__ ++ aml_append(cpu_ctrl_dev, ++ aml_operation_region("PRST", AML_SYSTEM_MEMORY, aml_int(io_base), ++ ACPI_CPU_HOTPLUG_REG_LEN)); ++#else + aml_append(cpu_ctrl_dev, + aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base), + ACPI_CPU_HOTPLUG_REG_LEN)); ++#endif + + field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, + AML_WRITE_AS_ZEROS); +diff --git a/hw/loongarch/iocsr.c b/hw/loongarch/iocsr.c +index 14521c2d5c..60daafd6e1 100644 +--- a/hw/loongarch/iocsr.c ++++ b/hw/loongarch/iocsr.c +@@ -59,6 +59,7 @@ enum { + IOCSR_MAX + }; + ++#ifdef CONFIG_KVM + static uint32_t iocsr_array[IOCSR_MAX] = { + [IOCSR_FEATURES] = LOONGARCH_IOCSR_FEATURES, + [IOCSR_VENDOR] = LOONGARCH_IOCSR_VENDOR, +@@ -66,6 +67,7 @@ static uint32_t iocsr_array[IOCSR_MAX] = { + [IOCSR_NODECNT] = LOONGARCH_IOCSR_NODECNT, + [IOCSR_MISC_FUNC] = LOONGARCH_IOCSR_MISC_FUNC, + }; ++#endif + + + #define TYPE_IOCSR "iocsr" +diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c +index 3db269274f..3194a822cc 100644 +--- a/hw/loongarch/larch_3a.c ++++ b/hw/loongarch/larch_3a.c +@@ -846,7 +846,7 @@ static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg, + if (0 < initrd_size) { + if (initrd_size > highram_size) { + error_report("initrd size is too big, should below %ld MB", +- highram_size / S_1MiB); ++ highram_size / MiB); + /*prevent write io memory address space*/ + exit(1); + } +@@ -1033,7 +1033,9 @@ static void *ls3a_intctl_init(MachineState *machine, CPULOONGARCHState *env[]) + SysBusDevice *busdev; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *iomem = NULL; ++#ifdef CONFIG_KVM + int i; ++#endif + + s = g_malloc0(sizeof(ls3a_intctlstate)); + +@@ -1214,8 +1216,6 @@ static void loongarch_build_smbios(LoongarchMachineState *lsms) + product = "Loongarch-3A5K-7A1000-TCG"; + } + +- host_cpufreq = get_host_cpu_freq(); +- + smbios_set_defaults("Loongson", product, lsmc->cpu_name, false, + true, NULL, NULL, SMBIOS_ENTRY_POINT_30); + +@@ -1672,15 +1672,15 @@ static void ls3a5k_init(MachineState *args) + + offset += lowram_size; + if (nb_numa_nodes > 0) { +- highram_size = numa_info[0].node_mem - S_256MiB; +- if (numa_info[0].node_mem > S_1GiB) { +- memmap_size = numa_info[0].node_mem - S_1GiB; ++ highram_size = numa_info[0].node_mem - 256 * MiB; ++ if (numa_info[0].node_mem > GiB) { ++ memmap_size = numa_info[0].node_mem - GiB; + la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); + } + } else { +- highram_size = ram_size - S_256MiB; +- if (ram_size > S_1GiB) { +- memmap_size = ram_size - S_1GiB; ++ highram_size = ram_size - 256 * MiB; ++ if (ram_size > GiB) { ++ memmap_size = ram_size - GiB; + la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); + } + } +diff --git a/hw/meson.build b/hw/meson.build +index b3366c888e..f224f8ad28 100644 +--- a/hw/meson.build ++++ b/hw/meson.build +@@ -17,6 +17,7 @@ subdir('intc') + subdir('ipack') + subdir('ipmi') + subdir('isa') ++subdir('loongarch') + subdir('mem') + subdir('misc') + subdir('net') +diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h +index 08e1beec85..95b93f1002 100644 +--- a/include/disas/dis-asm.h ++++ b/include/disas/dis-asm.h +@@ -461,6 +461,7 @@ int print_insn_riscv32 (bfd_vma, disassemble_info*); + int print_insn_riscv64 (bfd_vma, disassemble_info*); + int print_insn_rx(bfd_vma, disassemble_info *); + int print_insn_hexagon(bfd_vma, disassemble_info *); ++int print_insn_loongarch (bfd_vma, disassemble_info*); + + #ifdef CONFIG_CAPSTONE + bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size); +diff --git a/include/elf.h b/include/elf.h +index 811bf4a1cb..66030f4906 100644 +--- a/include/elf.h ++++ b/include/elf.h +@@ -182,6 +182,8 @@ typedef struct mips_elf_abiflags_v0 { + + #define EM_NANOMIPS 249 /* Wave Computing nanoMIPS */ + ++#define EM_LOONGARCH 258 /* Loongarch */ ++ + /* + * This is an interim value that we will use until the committee comes + * up with a final number. +diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h +index 0886ed52af..62e2830e27 100644 +--- a/include/hw/loongarch/larch.h ++++ b/include/hw/loongarch/larch.h +@@ -159,5 +159,4 @@ bool loongarch_is_acpi_enabled(LoongarchMachineState *vms); + void ls7a_madt_cpu_entry(AcpiDeviceIf *adev, int uid, + const CPUArchIdList *apic_ids, GArray *entry, bool force_enabled); + void slave_cpu_reset(void *opaque); +-extern uint64_t host_cpufreq; + #endif +diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h +index 60718fc342..903475bb21 100644 +--- a/include/qemu/osdep.h ++++ b/include/qemu/osdep.h +@@ -533,6 +533,9 @@ static inline void qemu_cleanup_generic_vfree(void *p) + Valgrind does not support alignments larger than 1 MiB, + therefore we need special code which handles running on Valgrind. */ + # define QEMU_VMALLOC_ALIGN (512 * 4096) ++#elif defined(__linux__) && defined(__loongarch__) ++ /* Use 32 MiB alignment so transparent hugepages can be used by KVM. */ ++# define QEMU_VMALLOC_ALIGN (qemu_real_host_page_size * qemu_real_host_page_size / 8) + #elif defined(__linux__) && defined(__s390x__) + /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */ + # define QEMU_VMALLOC_ALIGN (256 * 4096) +diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h +index 70c579560a..62d1a4b92d 100644 +--- a/include/sysemu/arch_init.h ++++ b/include/sysemu/arch_init.h +@@ -24,6 +24,7 @@ enum { + QEMU_ARCH_RX = (1 << 20), + QEMU_ARCH_AVR = (1 << 21), + QEMU_ARCH_HEXAGON = (1 << 22), ++ QEMU_ARCH_LOONGARCH64 = (1 << 23), + }; + + extern const uint32_t arch_type; +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index bcaf66cc4d..20b90426f5 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -2002,6 +2002,29 @@ struct kvm_stats_desc { + char name[]; + }; + ++#ifdef __loongarch__ ++struct kvm_loongarch_vcpu_state { ++ __u8 online_vcpus; ++ __u8 is_migrate; ++ __u32 cpu_freq; ++ __u32 count_ctl; ++ __u64 pending_exceptions; ++ __u64 pending_exceptions_clr; ++ __u64 core_ext_ioisr[4]; ++}; ++ ++#define KVM_CAP_LOONGARCH_FPU 165 ++#define KVM_CAP_LOONGARCH_LSX 166 ++#define KVM_CAP_LOONGARCH_VZ 167 ++#define KVM_REG_LOONGARCH 0x8000000000000000ULL ++#define KVM_LARCH_GET_VCPU_STATE _IOR(KVMIO, 0xc0, struct kvm_loongarch_vcpu_state) ++#define KVM_LARCH_SET_VCPU_STATE _IOW(KVMIO, 0xc1, struct kvm_loongarch_vcpu_state) ++#define KVM_LARCH_GET_CPUCFG _IOR(KVMIO, 0xc2, struct kvm_cpucfg) ++#define KVM_LOONGARCH_GET_IOCSR _IOR(KVMIO, 0xc3, struct kvm_iocsr_entry) ++#define KVM_LOONGARCH_SET_IOCSR _IOW(KVMIO, 0xc4, struct kvm_iocsr_entry) ++#define KVM_LARCH_SET_CPUCFG _IOR(KVMIO, 0xc5, struct kvm_cpucfg) ++#endif ++ + #define KVM_GET_STATS_FD _IO(KVMIO, 0xce) + + /* Available with KVM_CAP_XSAVE2 */ +diff --git a/linux-user/elfload.c b/linux-user/elfload.c +index 767f54c76d..9fb632780a 100644 +--- a/linux-user/elfload.c ++++ b/linux-user/elfload.c +@@ -1041,6 +1041,73 @@ static uint32_t get_elf_hwcap(void) + + #endif /* TARGET_MIPS */ + ++#ifdef TARGET_LOONGARCH64 ++ ++#define ELF_START_MMAP 0x80000000 ++ ++#define ELF_CLASS ELFCLASS64 ++#define ELF_ARCH EM_LOONGARCH ++ ++#define elf_check_arch(x) ((x) == EM_LOONGARCH) ++ ++static inline void init_thread(struct target_pt_regs *regs, ++ struct image_info *infop) ++{ ++ regs->csr_crmd = 2 << 3; ++ regs->csr_era = infop->entry; ++ regs->regs[3] = infop->start_stack; ++} ++ ++/* See linux kernel: arch/mips/include/asm/elf.h. */ ++#define ELF_NREG 45 ++typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG]; ++ ++/* See linux kernel: arch/loongarch/include/uapi/asm/reg.h */ ++enum { ++ TARGET_EF_R0 = 0, ++ TARGET_EF_R26 = TARGET_EF_R0 + 26, ++ TARGET_EF_R27 = TARGET_EF_R0 + 27, ++ TARGET_EF_CSR_ERA = TARGET_EF_R0 + 32, ++ TARGET_EF_CSR_BADV = TARGET_EF_R0 + 33, ++ TARGET_EF_CSR_CRMD = TARGET_EF_R0 + 34, ++ TARGET_EF_CSR_ESTAT = TARGET_EF_R0 + 38 ++}; ++ ++/* See linux kernel: arch/loongarch/kernel/process.c:elf_dump_regs. */ ++static void elf_core_copy_regs(target_elf_gregset_t *regs, ++ const CPULOONGARCHState *env) ++{ ++ int i; ++ ++ for (i = 0; i < TARGET_EF_R0; i++) { ++ (*regs)[i] = 0; ++ } ++ (*regs)[TARGET_EF_R0] = 0; ++ ++ for (i = 1; i < ARRAY_SIZE(env->active_tc.gpr); i++) { ++ (*regs)[TARGET_EF_R0 + i] = tswapreg(env->active_tc.gpr[i]); ++ } ++ ++ (*regs)[TARGET_EF_R26] = 0; ++ (*regs)[TARGET_EF_R27] = 0; ++ (*regs)[TARGET_EF_CSR_ERA] = tswapreg(env->active_tc.PC); ++ (*regs)[TARGET_EF_CSR_BADV] = tswapreg(env->CSR_BADV); ++ (*regs)[TARGET_EF_CSR_CRMD] = tswapreg(env->CSR_CRMD); ++ (*regs)[TARGET_EF_CSR_ESTAT] = tswapreg(env->CSR_ESTAT); ++} ++ ++#define USE_ELF_CORE_DUMP ++#define ELF_EXEC_PAGESIZE 4096 ++ ++#define ELF_HWCAP get_elf_hwcap() ++ ++static uint32_t get_elf_hwcap(void) ++{ ++ return 0; ++} ++ ++#endif /* TARGET_LOONGARCH64 */ ++ + #ifdef TARGET_MICROBLAZE + + #define ELF_START_MMAP 0x80000000 +diff --git a/linux-user/meson.build b/linux-user/meson.build +index bf62c13e37..195f9e83ac 100644 +--- a/linux-user/meson.build ++++ b/linux-user/meson.build +@@ -39,3 +39,4 @@ subdir('sh4') + subdir('sparc') + subdir('x86_64') + subdir('xtensa') ++subdir('loongarch64') +diff --git a/linux-user/qemu.h b/linux-user/qemu.h +index 5c713fa8ab..66ddb25d1c 100644 +--- a/linux-user/qemu.h ++++ b/linux-user/qemu.h +@@ -61,7 +61,7 @@ struct image_info { + /* For target-specific processing of NT_GNU_PROPERTY_TYPE_0. */ + uint32_t note_flags; + +-#ifdef TARGET_MIPS ++#if defined(TARGET_MIPS) || defined(TARGET_LOONGARCH64) + int fp_abi; + int interp_fp_abi; + #endif +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index f1cfcc8104..729131ecd0 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -1614,6 +1614,9 @@ static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, + #elif defined(TARGET_MIPS) + ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1]; + return host_pipe[0]; ++#elif defined(TARGET_LOONGARCH64) ++ ((CPULOONGARCHState *)cpu_env)->active_tc.gpr[5] = host_pipe[1]; ++ return host_pipe[0]; + #elif defined(TARGET_SH4) + ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1]; + return host_pipe[0]; +diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h +index 0b13975937..7e2915d53e 100644 +--- a/linux-user/syscall_defs.h ++++ b/linux-user/syscall_defs.h +@@ -74,7 +74,7 @@ + || defined(TARGET_M68K) || defined(TARGET_CRIS) \ + || defined(TARGET_S390X) || defined(TARGET_OPENRISC) \ + || defined(TARGET_NIOS2) || defined(TARGET_RISCV) \ +- || defined(TARGET_XTENSA) ++ || defined(TARGET_XTENSA) || defined(TARGET_LOONGARCH64) + + #define TARGET_IOC_SIZEBITS 14 + #define TARGET_IOC_DIRBITS 2 +@@ -450,7 +450,7 @@ struct target_dirent64 { + #define TARGET_SIG_IGN ((abi_long)1) /* ignore signal */ + #define TARGET_SIG_ERR ((abi_long)-1) /* error return from signal */ + +-#ifdef TARGET_MIPS ++#if defined(TARGET_MIPS) || defined(TARGET_LOONGARCH64) + #define TARGET_NSIG 128 + #else + #define TARGET_NSIG 64 +@@ -2133,7 +2133,7 @@ struct target_stat64 { + abi_ulong __unused5; + }; + +-#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || defined(TARGET_RISCV) ++#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || defined(TARGET_RISCV) || defined(TARGET_LOONGARCH64) + + /* These are the asm-generic versions of the stat and stat64 structures */ + +@@ -2161,7 +2161,7 @@ struct target_stat { + unsigned int __unused5; + }; + +-#if !defined(TARGET_RISCV64) ++#if !(defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)) + #define TARGET_HAS_STRUCT_STAT64 + struct target_stat64 { + uint64_t st_dev; +@@ -2331,6 +2331,7 @@ struct target_statfs64 { + }; + #elif (defined(TARGET_PPC64) || defined(TARGET_X86_64) || \ + defined(TARGET_SPARC64) || defined(TARGET_AARCH64) || \ ++ defined(TARGET_LOONGARCH64) || \ + defined(TARGET_RISCV)) && !defined(TARGET_ABI32) + struct target_statfs { + abi_long f_type; +diff --git a/meson.build b/meson.build +index 5f6ba86dbb..fc2dc58f33 100644 +--- a/meson.build ++++ b/meson.build +@@ -1814,6 +1814,7 @@ disassemblers = { + 'sh4' : ['CONFIG_SH4_DIS'], + 'sparc' : ['CONFIG_SPARC_DIS'], + 'xtensa' : ['CONFIG_XTENSA_DIS'], ++ 'loongarch64' : ['CONFIG_LOONGARCH_DIS'], + } + if link_language == 'cpp' + disassemblers += { + +diff --git a/pc-bios/meson.build b/pc-bios/meson.build +index b40ff3f2bd..a09ca4d03c 100644 +--- a/pc-bios/meson.build ++++ b/pc-bios/meson.build +@@ -83,6 +83,7 @@ blobs = files( + 'opensbi-riscv32-generic-fw_dynamic.elf', + 'opensbi-riscv64-generic-fw_dynamic.elf', + 'npcm7xx_bootrom.bin', ++ 'loongarch_bios.bin', + ) + + if get_option('install_blobs') +diff --git a/qapi/machine-target.json b/qapi/machine-target.json +index f5ec4bc172..682dc86b42 100644 +--- a/qapi/machine-target.json ++++ b/qapi/machine-target.json +@@ -324,7 +324,8 @@ + 'TARGET_ARM', + 'TARGET_I386', + 'TARGET_S390X', +- 'TARGET_MIPS' ] } } ++ 'TARGET_MIPS', ++ 'TARGET_LOONGARCH64' ] } } + + ## + # @query-cpu-definitions: +@@ -340,4 +341,5 @@ + 'TARGET_ARM', + 'TARGET_I386', + 'TARGET_S390X', +- 'TARGET_MIPS' ] } } ++ 'TARGET_MIPS', ++ 'TARGET_LOONGARCH64' ] } } +diff --git a/qapi/machine.json b/qapi/machine.json +index a9f33d0f27..cd47b8d6bc 100644 +--- a/qapi/machine.json ++++ b/qapi/machine.json +@@ -34,7 +34,7 @@ + 'mips64el', 'mipsel', 'nios2', 'or1k', 'ppc', + 'ppc64', 'riscv32', 'riscv64', 'rx', 's390x', 'sh4', + 'sh4eb', 'sparc', 'sparc64', 'tricore', +- 'x86_64', 'xtensa', 'xtensaeb' ] } ++ 'x86_64', 'xtensa', 'xtensaeb', 'loongarch64' ] } + + ## + # @CpuS390State: +diff --git a/qapi/misc-target.json b/qapi/misc-target.json +index 4bc45d2474..63cebef573 100644 +--- a/qapi/misc-target.json ++++ b/qapi/misc-target.json +@@ -33,6 +33,7 @@ + 'TARGET_PPC64', + 'TARGET_S390X', + 'TARGET_SH4', ++ 'TARGET_LOONGARCH64', + 'TARGET_SPARC' ] } } + + ## +-- +2.27.0 + diff --git a/0008-Modify-compile-script.patch b/0008-Modify-compile-script.patch new file mode 100644 index 0000000..87054ee --- /dev/null +++ b/0008-Modify-compile-script.patch @@ -0,0 +1,36 @@ +From b051f9fdabc2cd49c1c80ef50bbee276b6946609 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Mon, 22 Aug 2022 08:22:03 -0400 +Subject: [PATCH 08/10] Modify compile script. + +Change-Id: I8573477d64f5974092001869d7aa9bb093f347e8 +Signed-off-by: lixianglai +--- + meson.build | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/meson.build b/meson.build +index fc2dc58f33..c0fb5788f7 100644 +--- a/meson.build ++++ b/meson.build +@@ -56,7 +56,7 @@ python = import('python').find_installation() + + supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux'] + supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64', +- 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64'] ++ 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64', 'loongarch64'] + + cpu = host_machine.cpu_family() + +@@ -77,6 +77,8 @@ elif cpu in ['ppc', 'ppc64'] + kvm_targets = ['ppc-softmmu', 'ppc64-softmmu'] + elif cpu in ['mips', 'mips64'] + kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu'] ++elif cpu == 'loongarch64' ++ kvm_targets = ['loongarch64-softmmu'] + else + kvm_targets = [] + endif +-- +2.27.0 + diff --git a/0009-Add-loongarch64-rh-devices.mak.patch b/0009-Add-loongarch64-rh-devices.mak.patch new file mode 100644 index 0000000..ef7533d --- /dev/null +++ b/0009-Add-loongarch64-rh-devices.mak.patch @@ -0,0 +1,3227 @@ +From d2163a939cd14d3d9a8a4afb9d9eacbb71b61517 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Wed, 24 Aug 2022 22:56:29 -0400 +Subject: [PATCH 09/10] Add loongarch64-rh-devices.mak. + +Change-Id: I375face82c0aa68c053254b879267830d6981756 +Signed-off-by: lixianglai +--- + .../loongarch64-rh-devices.mak | 155 ++ + configure | 5 + + meson.build | 2 + + pc-bios/meson.build | 1 + + tcg/loongarch64/tcg-insn-defs.c.inc | 979 +++++++++ + tcg/loongarch64/tcg-target-con-set.h | 31 + + tcg/loongarch64/tcg-target-con-str.h | 28 + + tcg/loongarch64/tcg-target.c.inc | 1744 +++++++++++++++++ + tcg/loongarch64/tcg-target.h | 178 ++ + 9 files changed, 3123 insertions(+) + create mode 100644 configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak + create mode 100644 tcg/loongarch64/tcg-insn-defs.c.inc + create mode 100644 tcg/loongarch64/tcg-target-con-set.h + create mode 100644 tcg/loongarch64/tcg-target-con-str.h + create mode 100644 tcg/loongarch64/tcg-target.c.inc + create mode 100644 tcg/loongarch64/tcg-target.h + +diff --git a/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak +new file mode 100644 +index 0000000000..e7b5bdc8e9 +--- /dev/null ++++ b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak +@@ -0,0 +1,155 @@ ++ ++include ../rh-virtio.mak ++# Default configuration for loongarch-softmmu ++ ++CONFIG_PCI=y ++CONFIG_ACPI_PCI=y ++# For now, CONFIG_IDE_CORE requires ISA, so we enable it here ++CONFIG_ISA_BUS=y ++CONFIG_VIRTIO_PCI=y ++ ++CONFIG_VGA_PCI=y ++CONFIG_ACPI_SMBUS=y ++#CONFIG_VHOST_USER_SCSI=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) ++CONFIG_VHOST_USER_SCSI=y ++#CONFIG_VHOST_USER_BLK=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) ++CONFIG_VHOST_USER_BLK=y ++CONFIG_VIRTIO=y ++CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_BLK=y ++CONFIG_VIRTIO_CRYPTO=y ++CONFIG_VIRTIO_GPU=y ++CONFIG_VIRTIO_INPUT=y ++CONFIG_VIRTIO_NET=y ++CONFIG_VIRTIO_RNG=y ++CONFIG_SCSI=y ++CONFIG_VIRTIO_SCSI=y ++CONFIG_VIRTIO_SERIAL=y ++ ++CONFIG_USB_UHCI=y ++CONFIG_USB_OHCI=y ++CONFIG_USB_OHCI_PCI=y ++CONFIG_USB_XHCI=y ++CONFIG_USB_XHCI_NEC=y ++CONFIG_NE2000_PCI=y ++CONFIG_EEPRO100_PCI=y ++CONFIG_PCNET_PCI=y ++CONFIG_PCNET_COMMON=y ++CONFIG_AC97=y ++CONFIG_HDA=y ++CONFIG_ES1370=y ++CONFIG_SCSI=y ++CONFIG_LSI_SCSI_PCI=y ++CONFIG_VMW_PVSCSI_SCSI_PCI=y ++CONFIG_MEGASAS_SCSI_PCI=y ++CONFIG_MPTSAS_SCSI_PCI=y ++CONFIG_RTL8139_PCI=y ++CONFIG_E1000_PCI=y ++CONFIG_IDE_CORE=y ++CONFIG_IDE_QDEV=y ++CONFIG_IDE_PCI=y ++CONFIG_AHCI=y ++CONFIG_AHCI_ICH9=y ++CONFIG_ESP=y ++CONFIG_ESP_PCI=y ++CONFIG_SERIAL=y ++CONFIG_SERIAL_ISA=y ++CONFIG_SERIAL_PCI=y ++CONFIG_CAN_BUS=y ++CONFIG_CAN_SJA1000=y ++CONFIG_CAN_PCI=y ++CONFIG_USB_UHCI=y ++CONFIG_USB_OHCI=y ++CONFIG_USB_XHCI=y ++CONFIG_USB_XHCI_NEC=y ++CONFIG_NE2000_PCI=y ++CONFIG_EEPRO100_PCI=y ++CONFIG_PCNET_PCI=y ++CONFIG_PCNET_COMMON=y ++CONFIG_AC97=y ++CONFIG_HDA=y ++CONFIG_ES1370=y ++CONFIG_SCSI=y ++CONFIG_LSI_SCSI_PCI=y ++CONFIG_VMW_PVSCSI_SCSI_PCI=y ++CONFIG_MEGASAS_SCSI_PCI=y ++CONFIG_MPTSAS_SCSI_PCI=y ++CONFIG_RTL8139_PCI=y ++CONFIG_E1000_PCI=y ++CONFIG_IDE_CORE=y ++CONFIG_IDE_QDEV=y ++CONFIG_IDE_PCI=y ++CONFIG_AHCI=y ++CONFIG_ESP=y ++CONFIG_ESP_PCI=y ++CONFIG_SERIAL=y ++CONFIG_SERIAL_ISA=y ++CONFIG_SERIAL_PCI=y ++CONFIG_CAN_BUS=y ++CONFIG_CAN_SJA1000=y ++CONFIG_CAN_PCI=y ++ ++CONFIG_SPICE=y ++CONFIG_QXL=y ++CONFIG_ESP=y ++CONFIG_SCSI=y ++CONFIG_VGA_ISA=y ++CONFIG_VGA_ISA_MM=y ++CONFIG_VGA_CIRRUS=y ++CONFIG_VMWARE_VGA=y ++CONFIG_VIRTIO_VGA=y ++CONFIG_SERIAL_ISA=y ++CONFIG_PARALLEL=y ++CONFIG_I8254=y ++CONFIG_PCSPK=y ++CONFIG_PCKBD=y ++CONFIG_FDC=y ++CONFIG_ACPI=y ++CONFIG_ACPI_MEMORY_HOTPLUG=y ++CONFIG_ACPI_NVDIMM=y ++CONFIG_ACPI_CPU_HOTPLUG=y ++CONFIG_APM=y ++CONFIG_I8257=y ++CONFIG_PIIX4=y ++CONFIG_IDE_ISA=y ++CONFIG_IDE_PIIX=y ++#CONFIG_NE2000_ISA=y ++CONFIG_MIPSNET=y ++CONFIG_PFLASH_CFI01=y ++CONFIG_I8259=y ++CONFIG_MC146818RTC=y ++CONFIG_ISA_TESTDEV=y ++CONFIG_EMPTY_SLOT=y ++CONFIG_I2C=y ++CONFIG_DIMM=y ++CONFIG_MEM_DEVICE=y ++ ++# Arch Specified CONFIG defines ++CONFIG_IDE_VIA=y ++CONFIG_VT82C686=y ++CONFIG_RC4030=y ++CONFIG_DP8393X=y ++CONFIG_DS1225Y=y ++CONFIG_FITLOADER=y ++CONFIG_SMBIOS=y ++ ++CONFIG_PCIE_PORT=y ++CONFIG_I82801B11=y ++CONFIG_XIO3130=y ++CONFIG_PCI_EXPRESS=y ++CONFIG_MSI_NONBROKEN=y ++CONFIG_IOH3420=y ++CONFIG_SD=y ++CONFIG_SDHCI=y ++CONFIG_VIRTFS=y ++CONFIG_VIRTIO_9P=y ++CONFIG_USB_EHCI=y ++CONFIG_USB_EHCI_PCI=y ++CONFIG_USB_EHCI_SYSBUS=y ++CONFIG_USB_STORAGE_BOT=y ++CONFIG_TPM_EMULATOR=y ++CONFIG_TPM_TIS=y ++CONFIG_PLATFORM_BUS=y ++CONFIG_TPM_TIS_SYSBUS=y ++CONFIG_ACPI_LOONGARCH=y ++CONFIG_LS7A_RTC=y +diff --git a/configure b/configure +index 48c21775f3..1f932f7eeb 100755 +--- a/configure ++++ b/configure +@@ -581,6 +581,8 @@ elif check_define __arm__ ; then + cpu="arm" + elif check_define __aarch64__ ; then + cpu="aarch64" ++elif check_define __loongarch__ ; then ++ cpu="loongarch64" + else + cpu=$(uname -m) + fi +@@ -606,6 +608,9 @@ case "$cpu" in + aarch64) + cpu="aarch64" + ;; ++ loongarch64) ++ cpu="loongarch64" ++ ;; + mips*) + cpu="mips" + ;; +diff --git a/meson.build b/meson.build +index c0fb5788f7..c5fdb78569 100644 +--- a/meson.build ++++ b/meson.build +@@ -361,6 +361,8 @@ if not get_option('tcg').disabled() + tcg_arch = 'i386' + elif config_host['ARCH'] == 'ppc64' + tcg_arch = 'ppc' ++ elif config_host['ARCH'] == 'loongarch64' ++ tcg_arch = 'loongarch64' + endif + add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch, + language: ['c', 'cpp', 'objc']) +diff --git a/pc-bios/meson.build b/pc-bios/meson.build +index a09ca4d03c..60009bd89e 100644 +--- a/pc-bios/meson.build ++++ b/pc-bios/meson.build +@@ -84,6 +84,7 @@ blobs = files( + 'opensbi-riscv64-generic-fw_dynamic.elf', + 'npcm7xx_bootrom.bin', + 'loongarch_bios.bin', ++ 'loongarch_vars.bin', + ) + + if get_option('install_blobs') +diff --git a/tcg/loongarch64/tcg-insn-defs.c.inc b/tcg/loongarch64/tcg-insn-defs.c.inc +new file mode 100644 +index 0000000000..d162571856 +--- /dev/null ++++ b/tcg/loongarch64/tcg-insn-defs.c.inc +@@ -0,0 +1,979 @@ ++/* SPDX-License-Identifier: MIT */ ++/* ++ * LoongArch instruction formats, opcodes, and encoders for TCG use. ++ * ++ * This file is auto-generated by genqemutcgdefs from ++ * https://github.com/loongson-community/loongarch-opcodes, ++ * from commit 961f0c60f5b63e574d785995600c71ad5413fdc4. ++ * DO NOT EDIT. ++ */ ++ ++typedef enum { ++ OPC_CLZ_W = 0x00001400, ++ OPC_CTZ_W = 0x00001c00, ++ OPC_CLZ_D = 0x00002400, ++ OPC_CTZ_D = 0x00002c00, ++ OPC_REVB_2H = 0x00003000, ++ OPC_REVB_2W = 0x00003800, ++ OPC_REVB_D = 0x00003c00, ++ OPC_SEXT_H = 0x00005800, ++ OPC_SEXT_B = 0x00005c00, ++ OPC_ADD_W = 0x00100000, ++ OPC_ADD_D = 0x00108000, ++ OPC_SUB_W = 0x00110000, ++ OPC_SUB_D = 0x00118000, ++ OPC_SLT = 0x00120000, ++ OPC_SLTU = 0x00128000, ++ OPC_MASKEQZ = 0x00130000, ++ OPC_MASKNEZ = 0x00138000, ++ OPC_NOR = 0x00140000, ++ OPC_AND = 0x00148000, ++ OPC_OR = 0x00150000, ++ OPC_XOR = 0x00158000, ++ OPC_ORN = 0x00160000, ++ OPC_ANDN = 0x00168000, ++ OPC_SLL_W = 0x00170000, ++ OPC_SRL_W = 0x00178000, ++ OPC_SRA_W = 0x00180000, ++ OPC_SLL_D = 0x00188000, ++ OPC_SRL_D = 0x00190000, ++ OPC_SRA_D = 0x00198000, ++ OPC_ROTR_W = 0x001b0000, ++ OPC_ROTR_D = 0x001b8000, ++ OPC_MUL_W = 0x001c0000, ++ OPC_MULH_W = 0x001c8000, ++ OPC_MULH_WU = 0x001d0000, ++ OPC_MUL_D = 0x001d8000, ++ OPC_MULH_D = 0x001e0000, ++ OPC_MULH_DU = 0x001e8000, ++ OPC_DIV_W = 0x00200000, ++ OPC_MOD_W = 0x00208000, ++ OPC_DIV_WU = 0x00210000, ++ OPC_MOD_WU = 0x00218000, ++ OPC_DIV_D = 0x00220000, ++ OPC_MOD_D = 0x00228000, ++ OPC_DIV_DU = 0x00230000, ++ OPC_MOD_DU = 0x00238000, ++ OPC_SLLI_W = 0x00408000, ++ OPC_SLLI_D = 0x00410000, ++ OPC_SRLI_W = 0x00448000, ++ OPC_SRLI_D = 0x00450000, ++ OPC_SRAI_W = 0x00488000, ++ OPC_SRAI_D = 0x00490000, ++ OPC_ROTRI_W = 0x004c8000, ++ OPC_ROTRI_D = 0x004d0000, ++ OPC_BSTRINS_W = 0x00600000, ++ OPC_BSTRPICK_W = 0x00608000, ++ OPC_BSTRINS_D = 0x00800000, ++ OPC_BSTRPICK_D = 0x00c00000, ++ OPC_SLTI = 0x02000000, ++ OPC_SLTUI = 0x02400000, ++ OPC_ADDI_W = 0x02800000, ++ OPC_ADDI_D = 0x02c00000, ++ OPC_CU52I_D = 0x03000000, ++ OPC_ANDI = 0x03400000, ++ OPC_ORI = 0x03800000, ++ OPC_XORI = 0x03c00000, ++ OPC_LU12I_W = 0x14000000, ++ OPC_CU32I_D = 0x16000000, ++ OPC_PCADDU2I = 0x18000000, ++ OPC_PCALAU12I = 0x1a000000, ++ OPC_PCADDU12I = 0x1c000000, ++ OPC_PCADDU18I = 0x1e000000, ++ OPC_LD_B = 0x28000000, ++ OPC_LD_H = 0x28400000, ++ OPC_LD_W = 0x28800000, ++ OPC_LD_D = 0x28c00000, ++ OPC_ST_B = 0x29000000, ++ OPC_ST_H = 0x29400000, ++ OPC_ST_W = 0x29800000, ++ OPC_ST_D = 0x29c00000, ++ OPC_LD_BU = 0x2a000000, ++ OPC_LD_HU = 0x2a400000, ++ OPC_LD_WU = 0x2a800000, ++ OPC_LDX_B = 0x38000000, ++ OPC_LDX_H = 0x38040000, ++ OPC_LDX_W = 0x38080000, ++ OPC_LDX_D = 0x380c0000, ++ OPC_STX_B = 0x38100000, ++ OPC_STX_H = 0x38140000, ++ OPC_STX_W = 0x38180000, ++ OPC_STX_D = 0x381c0000, ++ OPC_LDX_BU = 0x38200000, ++ OPC_LDX_HU = 0x38240000, ++ OPC_LDX_WU = 0x38280000, ++ OPC_DBAR = 0x38720000, ++ OPC_JIRL = 0x4c000000, ++ OPC_B = 0x50000000, ++ OPC_BL = 0x54000000, ++ OPC_BEQ = 0x58000000, ++ OPC_BNE = 0x5c000000, ++ OPC_BGT = 0x60000000, ++ OPC_BLE = 0x64000000, ++ OPC_BGTU = 0x68000000, ++ OPC_BLEU = 0x6c000000, ++} LoongArchInsn; ++ ++static int32_t __attribute__((unused)) ++encode_d_slot(LoongArchInsn opc, uint32_t d) ++{ ++ return opc | d; ++} ++ ++static int32_t __attribute__((unused)) ++encode_dj_slots(LoongArchInsn opc, uint32_t d, uint32_t j) ++{ ++ return opc | d | j << 5; ++} ++ ++static int32_t __attribute__((unused)) ++encode_djk_slots(LoongArchInsn opc, uint32_t d, uint32_t j, uint32_t k) ++{ ++ return opc | d | j << 5 | k << 10; ++} ++ ++static int32_t __attribute__((unused)) ++encode_djkm_slots(LoongArchInsn opc, uint32_t d, uint32_t j, uint32_t k, ++ uint32_t m) ++{ ++ return opc | d | j << 5 | k << 10 | m << 16; ++} ++ ++static int32_t __attribute__((unused)) ++encode_dk_slots(LoongArchInsn opc, uint32_t d, uint32_t k) ++{ ++ return opc | d | k << 10; ++} ++ ++static int32_t __attribute__((unused)) ++encode_dj_insn(LoongArchInsn opc, TCGReg d, TCGReg j) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ return encode_dj_slots(opc, d, j); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djk_insn(LoongArchInsn opc, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(k >= 0 && k <= 0x1f); ++ return encode_djk_slots(opc, d, j, k); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djsk12_insn(LoongArchInsn opc, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(sk12 >= -0x800 && sk12 <= 0x7ff); ++ return encode_djk_slots(opc, d, j, sk12 & 0xfff); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djsk16_insn(LoongArchInsn opc, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(sk16 >= -0x8000 && sk16 <= 0x7fff); ++ return encode_djk_slots(opc, d, j, sk16 & 0xffff); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djuk12_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk12) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(uk12 <= 0xfff); ++ return encode_djk_slots(opc, d, j, uk12); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djuk5_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk5) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(uk5 <= 0x1f); ++ return encode_djk_slots(opc, d, j, uk5); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djuk5um5_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk5, ++ uint32_t um5) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(uk5 <= 0x1f); ++ tcg_debug_assert(um5 <= 0x1f); ++ return encode_djkm_slots(opc, d, j, uk5, um5); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djuk6_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk6) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(uk6 <= 0x3f); ++ return encode_djk_slots(opc, d, j, uk6); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djuk6um6_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk6, ++ uint32_t um6) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(uk6 <= 0x3f); ++ tcg_debug_assert(um6 <= 0x3f); ++ return encode_djkm_slots(opc, d, j, uk6, um6); ++} ++ ++static int32_t __attribute__((unused)) ++encode_dsj20_insn(LoongArchInsn opc, TCGReg d, int32_t sj20) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(sj20 >= -0x80000 && sj20 <= 0x7ffff); ++ return encode_dj_slots(opc, d, sj20 & 0xfffff); ++} ++ ++static int32_t __attribute__((unused)) ++encode_sd10k16_insn(LoongArchInsn opc, int32_t sd10k16) ++{ ++ tcg_debug_assert(sd10k16 >= -0x2000000 && sd10k16 <= 0x1ffffff); ++ return encode_dk_slots(opc, (sd10k16 >> 16) & 0x3ff, sd10k16 & 0xffff); ++} ++ ++static int32_t __attribute__((unused)) ++encode_ud15_insn(LoongArchInsn opc, uint32_t ud15) ++{ ++ tcg_debug_assert(ud15 <= 0x7fff); ++ return encode_d_slot(opc, ud15); ++} ++ ++/* Emits the `clz.w d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_clz_w(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_CLZ_W, d, j)); ++} ++ ++/* Emits the `ctz.w d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ctz_w(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_CTZ_W, d, j)); ++} ++ ++/* Emits the `clz.d d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_clz_d(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_CLZ_D, d, j)); ++} ++ ++/* Emits the `ctz.d d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ctz_d(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_CTZ_D, d, j)); ++} ++ ++/* Emits the `revb.2h d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_revb_2h(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_REVB_2H, d, j)); ++} ++ ++/* Emits the `revb.2w d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_revb_2w(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_REVB_2W, d, j)); ++} ++ ++/* Emits the `revb.d d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_revb_d(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_REVB_D, d, j)); ++} ++ ++/* Emits the `sext.h d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sext_h(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_SEXT_H, d, j)); ++} ++ ++/* Emits the `sext.b d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sext_b(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_SEXT_B, d, j)); ++} ++ ++/* Emits the `add.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_add_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_ADD_W, d, j, k)); ++} ++ ++/* Emits the `add.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_add_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_ADD_D, d, j, k)); ++} ++ ++/* Emits the `sub.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sub_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SUB_W, d, j, k)); ++} ++ ++/* Emits the `sub.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sub_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SUB_D, d, j, k)); ++} ++ ++/* Emits the `slt d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_slt(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SLT, d, j, k)); ++} ++ ++/* Emits the `sltu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sltu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SLTU, d, j, k)); ++} ++ ++/* Emits the `maskeqz d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_maskeqz(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MASKEQZ, d, j, k)); ++} ++ ++/* Emits the `masknez d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_masknez(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MASKNEZ, d, j, k)); ++} ++ ++/* Emits the `nor d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_nor(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_NOR, d, j, k)); ++} ++ ++/* Emits the `and d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_and(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_AND, d, j, k)); ++} ++ ++/* Emits the `or d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_or(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_OR, d, j, k)); ++} ++ ++/* Emits the `xor d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_xor(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_XOR, d, j, k)); ++} ++ ++/* Emits the `orn d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_orn(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_ORN, d, j, k)); ++} ++ ++/* Emits the `andn d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_andn(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_ANDN, d, j, k)); ++} ++ ++/* Emits the `sll.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sll_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SLL_W, d, j, k)); ++} ++ ++/* Emits the `srl.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_srl_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SRL_W, d, j, k)); ++} ++ ++/* Emits the `sra.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sra_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SRA_W, d, j, k)); ++} ++ ++/* Emits the `sll.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sll_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SLL_D, d, j, k)); ++} ++ ++/* Emits the `srl.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_srl_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SRL_D, d, j, k)); ++} ++ ++/* Emits the `sra.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sra_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SRA_D, d, j, k)); ++} ++ ++/* Emits the `rotr.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_rotr_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_ROTR_W, d, j, k)); ++} ++ ++/* Emits the `rotr.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_rotr_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_ROTR_D, d, j, k)); ++} ++ ++/* Emits the `mul.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mul_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MUL_W, d, j, k)); ++} ++ ++/* Emits the `mulh.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mulh_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MULH_W, d, j, k)); ++} ++ ++/* Emits the `mulh.wu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mulh_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MULH_WU, d, j, k)); ++} ++ ++/* Emits the `mul.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mul_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MUL_D, d, j, k)); ++} ++ ++/* Emits the `mulh.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mulh_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MULH_D, d, j, k)); ++} ++ ++/* Emits the `mulh.du d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mulh_du(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MULH_DU, d, j, k)); ++} ++ ++/* Emits the `div.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_div_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_DIV_W, d, j, k)); ++} ++ ++/* Emits the `mod.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mod_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MOD_W, d, j, k)); ++} ++ ++/* Emits the `div.wu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_div_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_DIV_WU, d, j, k)); ++} ++ ++/* Emits the `mod.wu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mod_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MOD_WU, d, j, k)); ++} ++ ++/* Emits the `div.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_div_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_DIV_D, d, j, k)); ++} ++ ++/* Emits the `mod.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mod_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MOD_D, d, j, k)); ++} ++ ++/* Emits the `div.du d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_div_du(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_DIV_DU, d, j, k)); ++} ++ ++/* Emits the `mod.du d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mod_du(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MOD_DU, d, j, k)); ++} ++ ++/* Emits the `slli.w d, j, uk5` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_slli_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) ++{ ++ tcg_out32(s, encode_djuk5_insn(OPC_SLLI_W, d, j, uk5)); ++} ++ ++/* Emits the `slli.d d, j, uk6` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_slli_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) ++{ ++ tcg_out32(s, encode_djuk6_insn(OPC_SLLI_D, d, j, uk6)); ++} ++ ++/* Emits the `srli.w d, j, uk5` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_srli_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) ++{ ++ tcg_out32(s, encode_djuk5_insn(OPC_SRLI_W, d, j, uk5)); ++} ++ ++/* Emits the `srli.d d, j, uk6` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_srli_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) ++{ ++ tcg_out32(s, encode_djuk6_insn(OPC_SRLI_D, d, j, uk6)); ++} ++ ++/* Emits the `srai.w d, j, uk5` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_srai_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) ++{ ++ tcg_out32(s, encode_djuk5_insn(OPC_SRAI_W, d, j, uk5)); ++} ++ ++/* Emits the `srai.d d, j, uk6` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_srai_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) ++{ ++ tcg_out32(s, encode_djuk6_insn(OPC_SRAI_D, d, j, uk6)); ++} ++ ++/* Emits the `rotri.w d, j, uk5` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_rotri_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) ++{ ++ tcg_out32(s, encode_djuk5_insn(OPC_ROTRI_W, d, j, uk5)); ++} ++ ++/* Emits the `rotri.d d, j, uk6` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_rotri_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) ++{ ++ tcg_out32(s, encode_djuk6_insn(OPC_ROTRI_D, d, j, uk6)); ++} ++ ++/* Emits the `bstrins.w d, j, uk5, um5` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bstrins_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5, ++ uint32_t um5) ++{ ++ tcg_out32(s, encode_djuk5um5_insn(OPC_BSTRINS_W, d, j, uk5, um5)); ++} ++ ++/* Emits the `bstrpick.w d, j, uk5, um5` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bstrpick_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5, ++ uint32_t um5) ++{ ++ tcg_out32(s, encode_djuk5um5_insn(OPC_BSTRPICK_W, d, j, uk5, um5)); ++} ++ ++/* Emits the `bstrins.d d, j, uk6, um6` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bstrins_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6, ++ uint32_t um6) ++{ ++ tcg_out32(s, encode_djuk6um6_insn(OPC_BSTRINS_D, d, j, uk6, um6)); ++} ++ ++/* Emits the `bstrpick.d d, j, uk6, um6` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bstrpick_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6, ++ uint32_t um6) ++{ ++ tcg_out32(s, encode_djuk6um6_insn(OPC_BSTRPICK_D, d, j, uk6, um6)); ++} ++ ++/* Emits the `slti d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_slti(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_SLTI, d, j, sk12)); ++} ++ ++/* Emits the `sltui d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sltui(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_SLTUI, d, j, sk12)); ++} ++ ++/* Emits the `addi.w d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_addi_w(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_ADDI_W, d, j, sk12)); ++} ++ ++/* Emits the `addi.d d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_addi_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_ADDI_D, d, j, sk12)); ++} ++ ++/* Emits the `cu52i.d d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_cu52i_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_CU52I_D, d, j, sk12)); ++} ++ ++/* Emits the `andi d, j, uk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_andi(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12) ++{ ++ tcg_out32(s, encode_djuk12_insn(OPC_ANDI, d, j, uk12)); ++} ++ ++/* Emits the `ori d, j, uk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ori(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12) ++{ ++ tcg_out32(s, encode_djuk12_insn(OPC_ORI, d, j, uk12)); ++} ++ ++/* Emits the `xori d, j, uk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_xori(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12) ++{ ++ tcg_out32(s, encode_djuk12_insn(OPC_XORI, d, j, uk12)); ++} ++ ++/* Emits the `lu12i.w d, sj20` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_lu12i_w(TCGContext *s, TCGReg d, int32_t sj20) ++{ ++ tcg_out32(s, encode_dsj20_insn(OPC_LU12I_W, d, sj20)); ++} ++ ++/* Emits the `cu32i.d d, sj20` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_cu32i_d(TCGContext *s, TCGReg d, int32_t sj20) ++{ ++ tcg_out32(s, encode_dsj20_insn(OPC_CU32I_D, d, sj20)); ++} ++ ++/* Emits the `pcaddu2i d, sj20` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_pcaddu2i(TCGContext *s, TCGReg d, int32_t sj20) ++{ ++ tcg_out32(s, encode_dsj20_insn(OPC_PCADDU2I, d, sj20)); ++} ++ ++/* Emits the `pcalau12i d, sj20` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_pcalau12i(TCGContext *s, TCGReg d, int32_t sj20) ++{ ++ tcg_out32(s, encode_dsj20_insn(OPC_PCALAU12I, d, sj20)); ++} ++ ++/* Emits the `pcaddu12i d, sj20` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_pcaddu12i(TCGContext *s, TCGReg d, int32_t sj20) ++{ ++ tcg_out32(s, encode_dsj20_insn(OPC_PCADDU12I, d, sj20)); ++} ++ ++/* Emits the `pcaddu18i d, sj20` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_pcaddu18i(TCGContext *s, TCGReg d, int32_t sj20) ++{ ++ tcg_out32(s, encode_dsj20_insn(OPC_PCADDU18I, d, sj20)); ++} ++ ++/* Emits the `ld.b d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_b(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_B, d, j, sk12)); ++} ++ ++/* Emits the `ld.h d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_h(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_H, d, j, sk12)); ++} ++ ++/* Emits the `ld.w d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_w(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_W, d, j, sk12)); ++} ++ ++/* Emits the `ld.d d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_D, d, j, sk12)); ++} ++ ++/* Emits the `st.b d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_st_b(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_ST_B, d, j, sk12)); ++} ++ ++/* Emits the `st.h d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_st_h(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_ST_H, d, j, sk12)); ++} ++ ++/* Emits the `st.w d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_st_w(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_ST_W, d, j, sk12)); ++} ++ ++/* Emits the `st.d d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_st_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_ST_D, d, j, sk12)); ++} ++ ++/* Emits the `ld.bu d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_bu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_BU, d, j, sk12)); ++} ++ ++/* Emits the `ld.hu d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_hu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_HU, d, j, sk12)); ++} ++ ++/* Emits the `ld.wu d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_wu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_WU, d, j, sk12)); ++} ++ ++/* Emits the `ldx.b d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_b(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_B, d, j, k)); ++} ++ ++/* Emits the `ldx.h d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_h(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_H, d, j, k)); ++} ++ ++/* Emits the `ldx.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_W, d, j, k)); ++} ++ ++/* Emits the `ldx.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_D, d, j, k)); ++} ++ ++/* Emits the `stx.b d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_stx_b(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_STX_B, d, j, k)); ++} ++ ++/* Emits the `stx.h d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_stx_h(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_STX_H, d, j, k)); ++} ++ ++/* Emits the `stx.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_stx_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_STX_W, d, j, k)); ++} ++ ++/* Emits the `stx.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_stx_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_STX_D, d, j, k)); ++} ++ ++/* Emits the `ldx.bu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_bu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_BU, d, j, k)); ++} ++ ++/* Emits the `ldx.hu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_hu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_HU, d, j, k)); ++} ++ ++/* Emits the `ldx.wu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_WU, d, j, k)); ++} ++ ++/* Emits the `dbar ud15` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_dbar(TCGContext *s, uint32_t ud15) ++{ ++ tcg_out32(s, encode_ud15_insn(OPC_DBAR, ud15)); ++} ++ ++/* Emits the `jirl d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_jirl(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_JIRL, d, j, sk16)); ++} ++ ++/* Emits the `b sd10k16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_b(TCGContext *s, int32_t sd10k16) ++{ ++ tcg_out32(s, encode_sd10k16_insn(OPC_B, sd10k16)); ++} ++ ++/* Emits the `bl sd10k16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bl(TCGContext *s, int32_t sd10k16) ++{ ++ tcg_out32(s, encode_sd10k16_insn(OPC_BL, sd10k16)); ++} ++ ++/* Emits the `beq d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_beq(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_BEQ, d, j, sk16)); ++} ++ ++/* Emits the `bne d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bne(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_BNE, d, j, sk16)); ++} ++ ++/* Emits the `bgt d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bgt(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_BGT, d, j, sk16)); ++} ++ ++/* Emits the `ble d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ble(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_BLE, d, j, sk16)); ++} ++ ++/* Emits the `bgtu d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bgtu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_BGTU, d, j, sk16)); ++} ++ ++/* Emits the `bleu d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bleu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_BLEU, d, j, sk16)); ++} ++ ++/* End of generated code. */ +diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h +new file mode 100644 +index 0000000000..349c672687 +--- /dev/null ++++ b/tcg/loongarch64/tcg-target-con-set.h +@@ -0,0 +1,31 @@ ++/* SPDX-License-Identifier: MIT */ ++/* ++ * Define LoongArch target-specific constraint sets. ++ * ++ * Copyright (c) 2021 WANG Xuerui ++ * ++ * Based on tcg/riscv/tcg-target-con-set.h ++ * ++ * Copyright (c) 2021 Linaro ++ */ ++ ++/* ++ * C_On_Im(...) defines a constraint set with outputs and inputs. ++ * Each operand should be a sequence of constraint letters as defined by ++ * tcg-target-con-str.h; the constraint combination is inclusive or. ++ */ ++C_O0_I1(r) ++C_O0_I2(rZ, r) ++C_O0_I2(rZ, rZ) ++C_O0_I2(LZ, L) ++C_O1_I1(r, r) ++C_O1_I1(r, L) ++C_O1_I2(r, r, rC) ++C_O1_I2(r, r, ri) ++C_O1_I2(r, r, rI) ++C_O1_I2(r, r, rU) ++C_O1_I2(r, r, rW) ++C_O1_I2(r, r, rZ) ++C_O1_I2(r, 0, rZ) ++C_O1_I2(r, rZ, rN) ++C_O1_I2(r, rZ, rZ) +diff --git a/tcg/loongarch64/tcg-target-con-str.h b/tcg/loongarch64/tcg-target-con-str.h +new file mode 100644 +index 0000000000..c3986a4fd4 +--- /dev/null ++++ b/tcg/loongarch64/tcg-target-con-str.h +@@ -0,0 +1,28 @@ ++/* SPDX-License-Identifier: MIT */ ++/* ++ * Define LoongArch target-specific operand constraints. ++ * ++ * Copyright (c) 2021 WANG Xuerui ++ * ++ * Based on tcg/riscv/tcg-target-con-str.h ++ * ++ * Copyright (c) 2021 Linaro ++ */ ++ ++/* ++ * Define constraint letters for register sets: ++ * REGS(letter, register_mask) ++ */ ++REGS('r', ALL_GENERAL_REGS) ++REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS) ++ ++/* ++ * Define constraint letters for constants: ++ * CONST(letter, TCG_CT_CONST_* bit set) ++ */ ++CONST('I', TCG_CT_CONST_S12) ++CONST('N', TCG_CT_CONST_N12) ++CONST('U', TCG_CT_CONST_U12) ++CONST('Z', TCG_CT_CONST_ZERO) ++CONST('C', TCG_CT_CONST_C12) ++CONST('W', TCG_CT_CONST_WSZ) +diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc +new file mode 100644 +index 0000000000..9b53549edb +--- /dev/null ++++ b/tcg/loongarch64/tcg-target.c.inc +@@ -0,0 +1,1744 @@ ++/* ++ * Tiny Code Generator for QEMU ++ * ++ * Copyright (c) 2021 WANG Xuerui ++ * ++ * Based on tcg/riscv/tcg-target.c.inc ++ * ++ * Copyright (c) 2018 SiFive, Inc ++ * Copyright (c) 2008-2009 Arnaud Patard ++ * Copyright (c) 2009 Aurelien Jarno ++ * Copyright (c) 2008 Fabrice Bellard ++ * ++ * 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 "../tcg-ldst.c.inc" ++ ++#ifdef CONFIG_DEBUG_TCG ++static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { ++ "zero", ++ "ra", ++ "tp", ++ "sp", ++ "a0", ++ "a1", ++ "a2", ++ "a3", ++ "a4", ++ "a5", ++ "a6", ++ "a7", ++ "t0", ++ "t1", ++ "t2", ++ "t3", ++ "t4", ++ "t5", ++ "t6", ++ "t7", ++ "t8", ++ "r21", /* reserved in the LP64* ABI, hence no ABI name */ ++ "s9", ++ "s0", ++ "s1", ++ "s2", ++ "s3", ++ "s4", ++ "s5", ++ "s6", ++ "s7", ++ "s8" ++}; ++#endif ++ ++static const int tcg_target_reg_alloc_order[] = { ++ /* Registers preserved across calls */ ++ /* TCG_REG_S0 reserved for TCG_AREG0 */ ++ TCG_REG_S1, ++ TCG_REG_S2, ++ TCG_REG_S3, ++ TCG_REG_S4, ++ TCG_REG_S5, ++ TCG_REG_S6, ++ TCG_REG_S7, ++ TCG_REG_S8, ++ TCG_REG_S9, ++ ++ /* Registers (potentially) clobbered across calls */ ++ TCG_REG_T0, ++ TCG_REG_T1, ++ TCG_REG_T2, ++ TCG_REG_T3, ++ TCG_REG_T4, ++ TCG_REG_T5, ++ TCG_REG_T6, ++ TCG_REG_T7, ++ TCG_REG_T8, ++ ++ /* Argument registers, opposite order of allocation. */ ++ TCG_REG_A7, ++ TCG_REG_A6, ++ TCG_REG_A5, ++ TCG_REG_A4, ++ TCG_REG_A3, ++ TCG_REG_A2, ++ TCG_REG_A1, ++ TCG_REG_A0, ++}; ++ ++static const int tcg_target_call_iarg_regs[] = { ++ TCG_REG_A0, ++ TCG_REG_A1, ++ TCG_REG_A2, ++ TCG_REG_A3, ++ TCG_REG_A4, ++ TCG_REG_A5, ++ TCG_REG_A6, ++ TCG_REG_A7, ++}; ++ ++static const int tcg_target_call_oarg_regs[] = { ++ TCG_REG_A0, ++ TCG_REG_A1, ++}; ++ ++#ifndef CONFIG_SOFTMMU ++#define USE_GUEST_BASE (guest_base != 0) ++#define TCG_GUEST_BASE_REG TCG_REG_S1 ++#endif ++ ++#define TCG_CT_CONST_ZERO 0x100 ++#define TCG_CT_CONST_S12 0x200 ++#define TCG_CT_CONST_N12 0x400 ++#define TCG_CT_CONST_U12 0x800 ++#define TCG_CT_CONST_C12 0x1000 ++#define TCG_CT_CONST_WSZ 0x2000 ++ ++#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32) ++/* ++ * For softmmu, we need to avoid conflicts with the first 5 ++ * argument registers to call the helper. Some of these are ++ * also used for the tlb lookup. ++ */ ++#ifdef CONFIG_SOFTMMU ++#define SOFTMMU_RESERVE_REGS MAKE_64BIT_MASK(TCG_REG_A0, 5) ++#else ++#define SOFTMMU_RESERVE_REGS 0 ++#endif ++ ++ ++static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len) ++{ ++ return sextract64(val, pos, len); ++} ++ ++/* test if a constant matches the constraint */ ++static bool tcg_target_const_match(int64_t val, TCGType type, int ct) ++{ ++ if (ct & TCG_CT_CONST) { ++ return true; ++ } ++ if ((ct & TCG_CT_CONST_ZERO) && val == 0) { ++ return true; ++ } ++ if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) { ++ return true; ++ } ++ if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) { ++ return true; ++ } ++ if ((ct & TCG_CT_CONST_U12) && val >= 0 && val <= 0xfff) { ++ return true; ++ } ++ if ((ct & TCG_CT_CONST_C12) && ~val >= 0 && ~val <= 0xfff) { ++ return true; ++ } ++ if ((ct & TCG_CT_CONST_WSZ) && val == (type == TCG_TYPE_I32 ? 32 : 64)) { ++ return true; ++ } ++ return false; ++} ++ ++/* ++ * Relocations ++ */ ++ ++/* ++ * Relocation records defined in LoongArch ELF psABI v1.00 is way too ++ * complicated; a whopping stack machine is needed to stuff the fields, at ++ * the very least one SOP_PUSH and one SOP_POP (of the correct format) are ++ * needed. ++ * ++ * Hence, define our own simpler relocation types. Numbers are chosen as to ++ * not collide with potential future additions to the true ELF relocation ++ * type enum. ++ */ ++ ++/* Field Sk16, shifted right by 2; suitable for conditional jumps */ ++#define R_LOONGARCH_BR_SK16 256 ++/* Field Sd10k16, shifted right by 2; suitable for B and BL */ ++#define R_LOONGARCH_BR_SD10K16 257 ++ ++static bool reloc_br_sk16(tcg_insn_unit *src_rw, const tcg_insn_unit *target) ++{ ++ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); ++ intptr_t offset = (intptr_t)target - (intptr_t)src_rx; ++ ++ tcg_debug_assert((offset & 3) == 0); ++ offset >>= 2; ++ if (offset == sextreg(offset, 0, 16)) { ++ *src_rw = deposit64(*src_rw, 10, 16, offset); ++ return true; ++ } ++ ++ return false; ++} ++ ++static bool reloc_br_sd10k16(tcg_insn_unit *src_rw, ++ const tcg_insn_unit *target) ++{ ++ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); ++ intptr_t offset = (intptr_t)target - (intptr_t)src_rx; ++ ++ tcg_debug_assert((offset & 3) == 0); ++ offset >>= 2; ++ if (offset == sextreg(offset, 0, 26)) { ++ *src_rw = deposit64(*src_rw, 0, 10, offset >> 16); /* slot d10 */ ++ *src_rw = deposit64(*src_rw, 10, 16, offset); /* slot k16 */ ++ return true; ++ } ++ ++ return false; ++} ++ ++static bool patch_reloc(tcg_insn_unit *code_ptr, int type, ++ intptr_t value, intptr_t addend) ++{ ++ tcg_debug_assert(addend == 0); ++ switch (type) { ++ case R_LOONGARCH_BR_SK16: ++ return reloc_br_sk16(code_ptr, (tcg_insn_unit *)value); ++ case R_LOONGARCH_BR_SD10K16: ++ return reloc_br_sd10k16(code_ptr, (tcg_insn_unit *)value); ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++#include "tcg-insn-defs.c.inc" ++ ++/* ++ * TCG intrinsics ++ */ ++ ++static void tcg_out_mb(TCGContext *s, TCGArg a0) ++{ ++ /* Baseline LoongArch only has the full barrier, unfortunately. */ ++ tcg_out_opc_dbar(s, 0); ++} ++ ++static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) ++{ ++ if (ret == arg) { ++ return true; ++ } ++ switch (type) { ++ case TCG_TYPE_I32: ++ case TCG_TYPE_I64: ++ /* ++ * Conventional register-register move used in LoongArch is ++ * `or dst, src, zero`. ++ */ ++ tcg_out_opc_or(s, ret, arg, TCG_REG_ZERO); ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++ return true; ++} ++ ++static bool imm_part_needs_loading(bool high_bits_are_ones, ++ tcg_target_long part) ++{ ++ if (high_bits_are_ones) { ++ return part != -1; ++ } else { ++ return part != 0; ++ } ++} ++ ++/* Loads a 32-bit immediate into rd, sign-extended. */ ++static void tcg_out_movi_i32(TCGContext *s, TCGReg rd, int32_t val) ++{ ++ tcg_target_long lo = sextreg(val, 0, 12); ++ tcg_target_long hi12 = sextreg(val, 12, 20); ++ ++ /* Single-instruction cases. */ ++ if (lo == val) { ++ /* val fits in simm12: addi.w rd, zero, val */ ++ tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val); ++ return; ++ } ++ if (0x800 <= val && val <= 0xfff) { ++ /* val fits in uimm12: ori rd, zero, val */ ++ tcg_out_opc_ori(s, rd, TCG_REG_ZERO, val); ++ return; ++ } ++ ++ /* High bits must be set; load with lu12i.w + optional ori. */ ++ tcg_out_opc_lu12i_w(s, rd, hi12); ++ if (lo != 0) { ++ tcg_out_opc_ori(s, rd, rd, lo & 0xfff); ++ } ++} ++ ++static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, ++ tcg_target_long val) ++{ ++ /* ++ * LoongArch conventionally loads 64-bit immediates in at most 4 steps, ++ * with dedicated instructions for filling the respective bitfields ++ * below: ++ * ++ * 6 5 4 3 ++ * 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 ++ * +-----------------------+---------------------------------------+... ++ * | hi52 | hi32 | ++ * +-----------------------+---------------------------------------+... ++ * 3 2 1 ++ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ++ * ...+-------------------------------------+-------------------------+ ++ * | hi12 | lo | ++ * ...+-------------------------------------+-------------------------+ ++ * ++ * Check if val belong to one of the several fast cases, before falling ++ * back to the slow path. ++ */ ++ ++ intptr_t pc_offset; ++ tcg_target_long val_lo, val_hi, pc_hi, offset_hi; ++ tcg_target_long hi32, hi52; ++ bool rd_high_bits_are_ones; ++ ++ /* Value fits in signed i32. */ ++ if (type == TCG_TYPE_I32 || val == (int32_t)val) { ++ tcg_out_movi_i32(s, rd, val); ++ return; ++ } ++ ++ /* PC-relative cases. */ ++ pc_offset = tcg_pcrel_diff(s, (void *)val); ++ if (pc_offset == sextreg(pc_offset, 0, 22) && (pc_offset & 3) == 0) { ++ /* Single pcaddu2i. */ ++ tcg_out_opc_pcaddu2i(s, rd, pc_offset >> 2); ++ return; ++ } ++ ++ if (pc_offset == (int32_t)pc_offset) { ++ /* Offset within 32 bits; load with pcalau12i + ori. */ ++ val_lo = sextreg(val, 0, 12); ++ val_hi = val >> 12; ++ pc_hi = (val - pc_offset) >> 12; ++ offset_hi = val_hi - pc_hi; ++ ++ tcg_debug_assert(offset_hi == sextreg(offset_hi, 0, 20)); ++ tcg_out_opc_pcalau12i(s, rd, offset_hi); ++ if (val_lo != 0) { ++ tcg_out_opc_ori(s, rd, rd, val_lo & 0xfff); ++ } ++ return; ++ } ++ ++ hi32 = sextreg(val, 32, 20); ++ hi52 = sextreg(val, 52, 12); ++ ++ /* Single cu52i.d case. */ ++ if (ctz64(val) >= 52) { ++ tcg_out_opc_cu52i_d(s, rd, TCG_REG_ZERO, hi52); ++ return; ++ } ++ ++ /* Slow path. Initialize the low 32 bits, then concat high bits. */ ++ tcg_out_movi_i32(s, rd, val); ++ rd_high_bits_are_ones = (int32_t)val < 0; ++ ++ if (imm_part_needs_loading(rd_high_bits_are_ones, hi32)) { ++ tcg_out_opc_cu32i_d(s, rd, hi32); ++ rd_high_bits_are_ones = hi32 < 0; ++ } ++ ++ if (imm_part_needs_loading(rd_high_bits_are_ones, hi52)) { ++ tcg_out_opc_cu52i_d(s, rd, rd, hi52); ++ } ++} ++ ++static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg) ++{ ++ tcg_out_opc_andi(s, ret, arg, 0xff); ++} ++ ++static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg) ++{ ++ tcg_out_opc_bstrpick_w(s, ret, arg, 0, 15); ++} ++ ++static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg) ++{ ++ tcg_out_opc_bstrpick_d(s, ret, arg, 0, 31); ++} ++ ++static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg) ++{ ++ tcg_out_opc_sext_b(s, ret, arg); ++} ++ ++static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg) ++{ ++ tcg_out_opc_sext_h(s, ret, arg); ++} ++ ++static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg) ++{ ++ tcg_out_opc_addi_w(s, ret, arg, 0); ++} ++ ++static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc, ++ TCGReg a0, TCGReg a1, TCGReg a2, ++ bool c2, bool is_32bit) ++{ ++ if (c2) { ++ /* ++ * Fast path: semantics already satisfied due to constraint and ++ * insn behavior, single instruction is enough. ++ */ ++ tcg_debug_assert(a2 == (is_32bit ? 32 : 64)); ++ /* all clz/ctz insns belong to DJ-format */ ++ tcg_out32(s, encode_dj_insn(opc, a0, a1)); ++ return; ++ } ++ ++ tcg_out32(s, encode_dj_insn(opc, TCG_REG_TMP0, a1)); ++ /* a0 = a1 ? REG_TMP0 : a2 */ ++ tcg_out_opc_maskeqz(s, TCG_REG_TMP0, TCG_REG_TMP0, a1); ++ tcg_out_opc_masknez(s, a0, a2, a1); ++ tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0); ++} ++ ++static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, ++ TCGReg arg1, TCGReg arg2, bool c2) ++{ ++ TCGReg tmp; ++ ++ if (c2) { ++ tcg_debug_assert(arg2 == 0); ++ } ++ ++ switch (cond) { ++ case TCG_COND_EQ: ++ if (c2) { ++ tmp = arg1; ++ } else { ++ tcg_out_opc_sub_d(s, ret, arg1, arg2); ++ tmp = ret; ++ } ++ tcg_out_opc_sltui(s, ret, tmp, 1); ++ break; ++ case TCG_COND_NE: ++ if (c2) { ++ tmp = arg1; ++ } else { ++ tcg_out_opc_sub_d(s, ret, arg1, arg2); ++ tmp = ret; ++ } ++ tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp); ++ break; ++ case TCG_COND_LT: ++ tcg_out_opc_slt(s, ret, arg1, arg2); ++ break; ++ case TCG_COND_GE: ++ tcg_out_opc_slt(s, ret, arg1, arg2); ++ tcg_out_opc_xori(s, ret, ret, 1); ++ break; ++ case TCG_COND_LE: ++ tcg_out_setcond(s, TCG_COND_GE, ret, arg2, arg1, false); ++ break; ++ case TCG_COND_GT: ++ tcg_out_setcond(s, TCG_COND_LT, ret, arg2, arg1, false); ++ break; ++ case TCG_COND_LTU: ++ tcg_out_opc_sltu(s, ret, arg1, arg2); ++ break; ++ case TCG_COND_GEU: ++ tcg_out_opc_sltu(s, ret, arg1, arg2); ++ tcg_out_opc_xori(s, ret, ret, 1); ++ break; ++ case TCG_COND_LEU: ++ tcg_out_setcond(s, TCG_COND_GEU, ret, arg2, arg1, false); ++ break; ++ case TCG_COND_GTU: ++ tcg_out_setcond(s, TCG_COND_LTU, ret, arg2, arg1, false); ++ break; ++ default: ++ g_assert_not_reached(); ++ break; ++ } ++} ++ ++/* ++ * Branch helpers ++ */ ++ ++static const struct { ++ LoongArchInsn op; ++ bool swap; ++} tcg_brcond_to_loongarch[] = { ++ [TCG_COND_EQ] = { OPC_BEQ, false }, ++ [TCG_COND_NE] = { OPC_BNE, false }, ++ [TCG_COND_LT] = { OPC_BGT, true }, ++ [TCG_COND_GE] = { OPC_BLE, true }, ++ [TCG_COND_LE] = { OPC_BLE, false }, ++ [TCG_COND_GT] = { OPC_BGT, false }, ++ [TCG_COND_LTU] = { OPC_BGTU, true }, ++ [TCG_COND_GEU] = { OPC_BLEU, true }, ++ [TCG_COND_LEU] = { OPC_BLEU, false }, ++ [TCG_COND_GTU] = { OPC_BGTU, false } ++}; ++ ++static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1, ++ TCGReg arg2, TCGLabel *l) ++{ ++ LoongArchInsn op = tcg_brcond_to_loongarch[cond].op; ++ ++ tcg_debug_assert(op != 0); ++ ++ if (tcg_brcond_to_loongarch[cond].swap) { ++ TCGReg t = arg1; ++ arg1 = arg2; ++ arg2 = t; ++ } ++ ++ /* all conditional branch insns belong to DJSk16-format */ ++ tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SK16, l, 0); ++ tcg_out32(s, encode_djsk16_insn(op, arg1, arg2, 0)); ++} ++ ++static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail) ++{ ++ TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA; ++ ptrdiff_t offset = tcg_pcrel_diff(s, arg); ++ ++ tcg_debug_assert((offset & 3) == 0); ++ if (offset == sextreg(offset, 0, 28)) { ++ /* short jump: +/- 256MiB */ ++ if (tail) { ++ tcg_out_opc_b(s, offset >> 2); ++ } else { ++ tcg_out_opc_bl(s, offset >> 2); ++ } ++ } else if (offset == sextreg(offset, 0, 38)) { ++ /* long jump: +/- 256GiB */ ++ tcg_target_long lo = sextreg(offset, 0, 18); ++ tcg_target_long hi = offset - lo; ++ tcg_out_opc_pcaddu18i(s, TCG_REG_TMP0, hi >> 18); ++ tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2); ++ } else { ++ /* far jump: 64-bit */ ++ tcg_target_long lo = sextreg((tcg_target_long)arg, 0, 18); ++ tcg_target_long hi = (tcg_target_long)arg - lo; ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, hi); ++ tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2); ++ } ++} ++ ++static void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg) ++{ ++ tcg_out_call_int(s, arg, false); ++} ++ ++/* ++ * Load/store helpers ++ */ ++ ++static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, TCGReg data, ++ TCGReg addr, intptr_t offset) ++{ ++ intptr_t imm12 = sextreg(offset, 0, 12); ++ ++ if (offset != imm12) { ++ intptr_t diff = offset - (uintptr_t)s->code_ptr; ++ ++ if (addr == TCG_REG_ZERO && diff == (int32_t)diff) { ++ imm12 = sextreg(diff, 0, 12); ++ tcg_out_opc_pcaddu12i(s, TCG_REG_TMP2, (diff - imm12) >> 12); ++ } else { ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP2, offset - imm12); ++ if (addr != TCG_REG_ZERO) { ++ tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, addr); ++ } ++ } ++ addr = TCG_REG_TMP2; ++ } ++ ++ switch (opc) { ++ case OPC_LD_B: ++ case OPC_LD_BU: ++ case OPC_LD_H: ++ case OPC_LD_HU: ++ case OPC_LD_W: ++ case OPC_LD_WU: ++ case OPC_LD_D: ++ case OPC_ST_B: ++ case OPC_ST_H: ++ case OPC_ST_W: ++ case OPC_ST_D: ++ tcg_out32(s, encode_djsk12_insn(opc, data, addr, imm12)); ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, ++ TCGReg arg1, intptr_t arg2) ++{ ++ bool is_32bit = type == TCG_TYPE_I32; ++ tcg_out_ldst(s, is_32bit ? OPC_LD_W : OPC_LD_D, arg, arg1, arg2); ++} ++ ++static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, ++ TCGReg arg1, intptr_t arg2) ++{ ++ bool is_32bit = type == TCG_TYPE_I32; ++ tcg_out_ldst(s, is_32bit ? OPC_ST_W : OPC_ST_D, arg, arg1, arg2); ++} ++ ++static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, ++ TCGReg base, intptr_t ofs) ++{ ++ if (val == 0) { ++ tcg_out_st(s, type, TCG_REG_ZERO, base, ofs); ++ return true; ++ } ++ return false; ++} ++ ++/* ++ * Load/store helpers for SoftMMU, and qemu_ld/st implementations ++ */ ++ ++#if defined(CONFIG_SOFTMMU) ++/* ++ * helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr, ++ * MemOpIdx oi, uintptr_t ra) ++ */ ++static void * const qemu_ld_helpers[4] = { ++ [MO_8] = helper_ret_ldub_mmu, ++ [MO_16] = helper_le_lduw_mmu, ++ [MO_32] = helper_le_ldul_mmu, ++ [MO_64] = helper_le_ldq_mmu, ++}; ++ ++/* ++ * helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr, ++ * uintxx_t val, MemOpIdx oi, ++ * uintptr_t ra) ++ */ ++static void * const qemu_st_helpers[4] = { ++ [MO_8] = helper_ret_stb_mmu, ++ [MO_16] = helper_le_stw_mmu, ++ [MO_32] = helper_le_stl_mmu, ++ [MO_64] = helper_le_stq_mmu, ++}; ++ ++/* We expect to use a 12-bit negative offset from ENV. */ ++QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0); ++QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11)); ++ ++static bool tcg_out_goto(TCGContext *s, const tcg_insn_unit *target) ++{ ++ tcg_out_opc_b(s, 0); ++ return reloc_br_sd10k16(s->code_ptr - 1, target); ++} ++ ++/* ++ * Emits common code for TLB addend lookup, that eventually loads the ++ * addend in TCG_REG_TMP2. ++ */ ++static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl, MemOpIdx oi, ++ tcg_insn_unit **label_ptr, bool is_load) ++{ ++ MemOp opc = get_memop(oi); ++ unsigned s_bits = opc & MO_SIZE; ++ unsigned a_bits = get_alignment_bits(opc); ++ tcg_target_long compare_mask; ++ int mem_index = get_mmuidx(oi); ++ int fast_ofs = TLB_MASK_TABLE_OFS(mem_index); ++ int mask_ofs = fast_ofs + offsetof(CPUTLBDescFast, mask); ++ int table_ofs = fast_ofs + offsetof(CPUTLBDescFast, table); ++ ++ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs); ++ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs); ++ ++ tcg_out_opc_srli_d(s, TCG_REG_TMP2, addrl, ++ TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); ++ tcg_out_opc_and(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP0); ++ tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP1); ++ ++ /* Load the tlb comparator and the addend. */ ++ tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP0, TCG_REG_TMP2, ++ is_load ? offsetof(CPUTLBEntry, addr_read) ++ : offsetof(CPUTLBEntry, addr_write)); ++ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_REG_TMP2, ++ offsetof(CPUTLBEntry, addend)); ++ ++ /* We don't support unaligned accesses. */ ++ if (a_bits < s_bits) { ++ a_bits = s_bits; ++ } ++ /* Clear the non-page, non-alignment bits from the address. */ ++ compare_mask = (tcg_target_long)TARGET_PAGE_MASK | ((1 << a_bits) - 1); ++ tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_TMP1, compare_mask); ++ tcg_out_opc_and(s, TCG_REG_TMP1, TCG_REG_TMP1, addrl); ++ ++ /* Compare masked address with the TLB entry. */ ++ label_ptr[0] = s->code_ptr; ++ tcg_out_opc_bne(s, TCG_REG_TMP0, TCG_REG_TMP1, 0); ++ ++ /* TLB Hit - addend in TCG_REG_TMP2, ready for use. */ ++} ++ ++static void add_qemu_ldst_label(TCGContext *s, int is_ld, MemOpIdx oi, ++ TCGType type, ++ TCGReg datalo, TCGReg addrlo, ++ void *raddr, tcg_insn_unit **label_ptr) ++{ ++ TCGLabelQemuLdst *label = new_ldst_label(s); ++ ++ label->is_ld = is_ld; ++ label->oi = oi; ++ label->type = type; ++ label->datalo_reg = datalo; ++ label->datahi_reg = 0; /* unused */ ++ label->addrlo_reg = addrlo; ++ label->addrhi_reg = 0; /* unused */ ++ label->raddr = tcg_splitwx_to_rx(raddr); ++ label->label_ptr[0] = label_ptr[0]; ++} ++ ++static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) ++{ ++ MemOpIdx oi = l->oi; ++ MemOp opc = get_memop(oi); ++ MemOp size = opc & MO_SIZE; ++ TCGType type = l->type; ++ ++ /* resolve label address */ ++ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { ++ return false; ++ } ++ ++ /* call load helper */ ++ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); ++ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A1, l->addrlo_reg); ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A2, oi); ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A3, (tcg_target_long)l->raddr); ++ ++ tcg_out_call(s, qemu_ld_helpers[size]); ++ ++ switch (opc & MO_SSIZE) { ++ case MO_SB: ++ tcg_out_ext8s(s, l->datalo_reg, TCG_REG_A0); ++ break; ++ case MO_SW: ++ tcg_out_ext16s(s, l->datalo_reg, TCG_REG_A0); ++ break; ++ case MO_SL: ++ tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0); ++ break; ++ case MO_UL: ++ if (type == TCG_TYPE_I32) { ++ /* MO_UL loads of i32 should be sign-extended too */ ++ tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0); ++ break; ++ } ++ /* fallthrough */ ++ default: ++ tcg_out_mov(s, type, l->datalo_reg, TCG_REG_A0); ++ break; ++ } ++ ++ return tcg_out_goto(s, l->raddr); ++} ++ ++static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) ++{ ++ MemOpIdx oi = l->oi; ++ MemOp opc = get_memop(oi); ++ MemOp size = opc & MO_SIZE; ++ ++ /* resolve label address */ ++ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { ++ return false; ++ } ++ ++ /* call store helper */ ++ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); ++ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A1, l->addrlo_reg); ++ switch (size) { ++ case MO_8: ++ tcg_out_ext8u(s, TCG_REG_A2, l->datalo_reg); ++ break; ++ case MO_16: ++ tcg_out_ext16u(s, TCG_REG_A2, l->datalo_reg); ++ break; ++ case MO_32: ++ tcg_out_ext32u(s, TCG_REG_A2, l->datalo_reg); ++ break; ++ case MO_64: ++ tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_A2, l->datalo_reg); ++ break; ++ default: ++ g_assert_not_reached(); ++ break; ++ } ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A3, oi); ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A4, (tcg_target_long)l->raddr); ++ ++ tcg_out_call(s, qemu_st_helpers[size]); ++ ++ return tcg_out_goto(s, l->raddr); ++} ++#else ++ ++/* ++ * Alignment helpers for user-mode emulation ++ */ ++ ++static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addr_reg, ++ unsigned a_bits) ++{ ++ TCGLabelQemuLdst *l = new_ldst_label(s); ++ ++ l->is_ld = is_ld; ++ l->addrlo_reg = addr_reg; ++ ++ /* ++ * Without micro-architecture details, we don't know which of bstrpick or ++ * andi is faster, so use bstrpick as it's not constrained by imm field ++ * width. (Not to say alignments >= 2^12 are going to happen any time ++ * soon, though) ++ */ ++ tcg_out_opc_bstrpick_d(s, TCG_REG_TMP1, addr_reg, 0, a_bits - 1); ++ ++ l->label_ptr[0] = s->code_ptr; ++ tcg_out_opc_bne(s, TCG_REG_TMP1, TCG_REG_ZERO, 0); ++ ++ l->raddr = tcg_splitwx_to_rx(s->code_ptr); ++} ++ ++static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l) ++{ ++ /* resolve label address */ ++ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { ++ return false; ++ } ++ ++ tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_A1, l->addrlo_reg); ++ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); ++ ++ /* tail call, with the return address back inline. */ ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (uintptr_t)l->raddr); ++ tcg_out_call_int(s, (const void *)(l->is_ld ? helper_unaligned_ld ++ : helper_unaligned_st), true); ++ return true; ++} ++ ++static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) ++{ ++ return tcg_out_fail_alignment(s, l); ++} ++ ++static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) ++{ ++ return tcg_out_fail_alignment(s, l); ++} ++ ++#endif /* CONFIG_SOFTMMU */ ++ ++/* ++ * `ext32u` the address register into the temp register given, ++ * if target is 32-bit, no-op otherwise. ++ * ++ * Returns the address register ready for use with TLB addend. ++ */ ++static TCGReg tcg_out_zext_addr_if_32_bit(TCGContext *s, ++ TCGReg addr, TCGReg tmp) ++{ ++ if (TARGET_LONG_BITS == 32) { ++ tcg_out_ext32u(s, tmp, addr); ++ return tmp; ++ } ++ return addr; ++} ++ ++static void tcg_out_qemu_ld_indexed(TCGContext *s, TCGReg rd, TCGReg rj, ++ TCGReg rk, MemOp opc, TCGType type) ++{ ++ /* Byte swapping is left to middle-end expansion. */ ++ tcg_debug_assert((opc & MO_BSWAP) == 0); ++ ++ switch (opc & MO_SSIZE) { ++ case MO_UB: ++ tcg_out_opc_ldx_bu(s, rd, rj, rk); ++ break; ++ case MO_SB: ++ tcg_out_opc_ldx_b(s, rd, rj, rk); ++ break; ++ case MO_UW: ++ tcg_out_opc_ldx_hu(s, rd, rj, rk); ++ break; ++ case MO_SW: ++ tcg_out_opc_ldx_h(s, rd, rj, rk); ++ break; ++ case MO_UL: ++ if (type == TCG_TYPE_I64) { ++ tcg_out_opc_ldx_wu(s, rd, rj, rk); ++ break; ++ } ++ /* fallthrough */ ++ case MO_SL: ++ tcg_out_opc_ldx_w(s, rd, rj, rk); ++ break; ++ case MO_Q: ++ tcg_out_opc_ldx_d(s, rd, rj, rk); ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGType type) ++{ ++ TCGReg addr_regl; ++ TCGReg data_regl; ++ MemOpIdx oi; ++ MemOp opc; ++#if defined(CONFIG_SOFTMMU) ++ tcg_insn_unit *label_ptr[1]; ++#else ++ unsigned a_bits; ++#endif ++ TCGReg base; ++ ++ data_regl = *args++; ++ addr_regl = *args++; ++ oi = *args++; ++ opc = get_memop(oi); ++ ++#if defined(CONFIG_SOFTMMU) ++ tcg_out_tlb_load(s, addr_regl, oi, label_ptr, 1); ++ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); ++ tcg_out_qemu_ld_indexed(s, data_regl, base, TCG_REG_TMP2, opc, type); ++ add_qemu_ldst_label(s, 1, oi, type, ++ data_regl, addr_regl, ++ s->code_ptr, label_ptr); ++#else ++ a_bits = get_alignment_bits(opc); ++ if (a_bits) { ++ tcg_out_test_alignment(s, true, addr_regl, a_bits); ++ } ++ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); ++ TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO; ++ tcg_out_qemu_ld_indexed(s, data_regl, base, guest_base_reg, opc, type); ++#endif ++} ++ ++static void tcg_out_qemu_st_indexed(TCGContext *s, TCGReg data, ++ TCGReg rj, TCGReg rk, MemOp opc) ++{ ++ /* Byte swapping is left to middle-end expansion. */ ++ tcg_debug_assert((opc & MO_BSWAP) == 0); ++ ++ switch (opc & MO_SIZE) { ++ case MO_8: ++ tcg_out_opc_stx_b(s, data, rj, rk); ++ break; ++ case MO_16: ++ tcg_out_opc_stx_h(s, data, rj, rk); ++ break; ++ case MO_32: ++ tcg_out_opc_stx_w(s, data, rj, rk); ++ break; ++ case MO_64: ++ tcg_out_opc_stx_d(s, data, rj, rk); ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args) ++{ ++ TCGReg addr_regl; ++ TCGReg data_regl; ++ MemOpIdx oi; ++ MemOp opc; ++#if defined(CONFIG_SOFTMMU) ++ tcg_insn_unit *label_ptr[1]; ++#else ++ unsigned a_bits; ++#endif ++ TCGReg base; ++ ++ data_regl = *args++; ++ addr_regl = *args++; ++ oi = *args++; ++ opc = get_memop(oi); ++ ++#if defined(CONFIG_SOFTMMU) ++ tcg_out_tlb_load(s, addr_regl, oi, label_ptr, 0); ++ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); ++ tcg_out_qemu_st_indexed(s, data_regl, base, TCG_REG_TMP2, opc); ++ add_qemu_ldst_label(s, 0, oi, ++ 0, /* type param is unused for stores */ ++ data_regl, addr_regl, ++ s->code_ptr, label_ptr); ++#else ++ a_bits = get_alignment_bits(opc); ++ if (a_bits) { ++ tcg_out_test_alignment(s, false, addr_regl, a_bits); ++ } ++ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); ++ TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO; ++ tcg_out_qemu_st_indexed(s, data_regl, base, guest_base_reg, opc); ++#endif ++} ++ ++/* ++ * Entry-points ++ */ ++ ++static const tcg_insn_unit *tb_ret_addr; ++ ++static void tcg_out_op(TCGContext *s, TCGOpcode opc, ++ const TCGArg args[TCG_MAX_OP_ARGS], ++ const int const_args[TCG_MAX_OP_ARGS]) ++{ ++ TCGArg a0 = args[0]; ++ TCGArg a1 = args[1]; ++ TCGArg a2 = args[2]; ++ int c2 = const_args[2]; ++ ++ switch (opc) { ++ case INDEX_op_exit_tb: ++ /* Reuse the zeroing that exists for goto_ptr. */ ++ if (a0 == 0) { ++ tcg_out_call_int(s, tcg_code_gen_epilogue, true); ++ } else { ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, a0); ++ tcg_out_call_int(s, tb_ret_addr, true); ++ } ++ break; ++ ++ case INDEX_op_goto_tb: ++ assert(s->tb_jmp_insn_offset == 0); ++ /* indirect jump method */ ++ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO, ++ (uintptr_t)(s->tb_jmp_target_addr + a0)); ++ tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_TMP0, 0); ++ set_jmp_reset_offset(s, a0); ++ break; ++ ++ case INDEX_op_mb: ++ tcg_out_mb(s, a0); ++ break; ++ ++ case INDEX_op_goto_ptr: ++ tcg_out_opc_jirl(s, TCG_REG_ZERO, a0, 0); ++ break; ++ ++ case INDEX_op_br: ++ tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SD10K16, arg_label(a0), ++ 0); ++ tcg_out_opc_b(s, 0); ++ break; ++ ++ case INDEX_op_brcond_i32: ++ case INDEX_op_brcond_i64: ++ tcg_out_brcond(s, a2, a0, a1, arg_label(args[3])); ++ break; ++ ++ case INDEX_op_ext8s_i32: ++ case INDEX_op_ext8s_i64: ++ tcg_out_ext8s(s, a0, a1); ++ break; ++ ++ case INDEX_op_ext8u_i32: ++ case INDEX_op_ext8u_i64: ++ tcg_out_ext8u(s, a0, a1); ++ break; ++ ++ case INDEX_op_ext16s_i32: ++ case INDEX_op_ext16s_i64: ++ tcg_out_ext16s(s, a0, a1); ++ break; ++ ++ case INDEX_op_ext16u_i32: ++ case INDEX_op_ext16u_i64: ++ tcg_out_ext16u(s, a0, a1); ++ break; ++ ++ case INDEX_op_ext32u_i64: ++ case INDEX_op_extu_i32_i64: ++ tcg_out_ext32u(s, a0, a1); ++ break; ++ ++ case INDEX_op_ext32s_i64: ++ case INDEX_op_extrl_i64_i32: ++ case INDEX_op_ext_i32_i64: ++ tcg_out_ext32s(s, a0, a1); ++ break; ++ ++ case INDEX_op_extrh_i64_i32: ++ tcg_out_opc_srai_d(s, a0, a1, 32); ++ break; ++ ++ case INDEX_op_not_i32: ++ case INDEX_op_not_i64: ++ tcg_out_opc_nor(s, a0, a1, TCG_REG_ZERO); ++ break; ++ ++ case INDEX_op_nor_i32: ++ case INDEX_op_nor_i64: ++ if (c2) { ++ tcg_out_opc_ori(s, a0, a1, a2); ++ tcg_out_opc_nor(s, a0, a0, TCG_REG_ZERO); ++ } else { ++ tcg_out_opc_nor(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_andc_i32: ++ case INDEX_op_andc_i64: ++ if (c2) { ++ /* guaranteed to fit due to constraint */ ++ tcg_out_opc_andi(s, a0, a1, ~a2); ++ } else { ++ tcg_out_opc_andn(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_orc_i32: ++ case INDEX_op_orc_i64: ++ if (c2) { ++ /* guaranteed to fit due to constraint */ ++ tcg_out_opc_ori(s, a0, a1, ~a2); ++ } else { ++ tcg_out_opc_orn(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_and_i32: ++ case INDEX_op_and_i64: ++ if (c2) { ++ tcg_out_opc_andi(s, a0, a1, a2); ++ } else { ++ tcg_out_opc_and(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_or_i32: ++ case INDEX_op_or_i64: ++ if (c2) { ++ tcg_out_opc_ori(s, a0, a1, a2); ++ } else { ++ tcg_out_opc_or(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_xor_i32: ++ case INDEX_op_xor_i64: ++ if (c2) { ++ tcg_out_opc_xori(s, a0, a1, a2); ++ } else { ++ tcg_out_opc_xor(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_extract_i32: ++ tcg_out_opc_bstrpick_w(s, a0, a1, a2, a2 + args[3] - 1); ++ break; ++ case INDEX_op_extract_i64: ++ tcg_out_opc_bstrpick_d(s, a0, a1, a2, a2 + args[3] - 1); ++ break; ++ ++ case INDEX_op_deposit_i32: ++ tcg_out_opc_bstrins_w(s, a0, a2, args[3], args[3] + args[4] - 1); ++ break; ++ case INDEX_op_deposit_i64: ++ tcg_out_opc_bstrins_d(s, a0, a2, args[3], args[3] + args[4] - 1); ++ break; ++ ++ case INDEX_op_bswap16_i32: ++ case INDEX_op_bswap16_i64: ++ tcg_out_opc_revb_2h(s, a0, a1); ++ if (a2 & TCG_BSWAP_OS) { ++ tcg_out_ext16s(s, a0, a0); ++ } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { ++ tcg_out_ext16u(s, a0, a0); ++ } ++ break; ++ ++ case INDEX_op_bswap32_i32: ++ /* All 32-bit values are computed sign-extended in the register. */ ++ a2 = TCG_BSWAP_OS; ++ /* fallthrough */ ++ case INDEX_op_bswap32_i64: ++ tcg_out_opc_revb_2w(s, a0, a1); ++ if (a2 & TCG_BSWAP_OS) { ++ tcg_out_ext32s(s, a0, a0); ++ } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { ++ tcg_out_ext32u(s, a0, a0); ++ } ++ break; ++ ++ case INDEX_op_bswap64_i64: ++ tcg_out_opc_revb_d(s, a0, a1); ++ break; ++ ++ case INDEX_op_clz_i32: ++ tcg_out_clzctz(s, OPC_CLZ_W, a0, a1, a2, c2, true); ++ break; ++ case INDEX_op_clz_i64: ++ tcg_out_clzctz(s, OPC_CLZ_D, a0, a1, a2, c2, false); ++ break; ++ ++ case INDEX_op_ctz_i32: ++ tcg_out_clzctz(s, OPC_CTZ_W, a0, a1, a2, c2, true); ++ break; ++ case INDEX_op_ctz_i64: ++ tcg_out_clzctz(s, OPC_CTZ_D, a0, a1, a2, c2, false); ++ break; ++ ++ case INDEX_op_shl_i32: ++ if (c2) { ++ tcg_out_opc_slli_w(s, a0, a1, a2 & 0x1f); ++ } else { ++ tcg_out_opc_sll_w(s, a0, a1, a2); ++ } ++ break; ++ case INDEX_op_shl_i64: ++ if (c2) { ++ tcg_out_opc_slli_d(s, a0, a1, a2 & 0x3f); ++ } else { ++ tcg_out_opc_sll_d(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_shr_i32: ++ if (c2) { ++ tcg_out_opc_srli_w(s, a0, a1, a2 & 0x1f); ++ } else { ++ tcg_out_opc_srl_w(s, a0, a1, a2); ++ } ++ break; ++ case INDEX_op_shr_i64: ++ if (c2) { ++ tcg_out_opc_srli_d(s, a0, a1, a2 & 0x3f); ++ } else { ++ tcg_out_opc_srl_d(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_sar_i32: ++ if (c2) { ++ tcg_out_opc_srai_w(s, a0, a1, a2 & 0x1f); ++ } else { ++ tcg_out_opc_sra_w(s, a0, a1, a2); ++ } ++ break; ++ case INDEX_op_sar_i64: ++ if (c2) { ++ tcg_out_opc_srai_d(s, a0, a1, a2 & 0x3f); ++ } else { ++ tcg_out_opc_sra_d(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_rotl_i32: ++ /* transform into equivalent rotr/rotri */ ++ if (c2) { ++ tcg_out_opc_rotri_w(s, a0, a1, (32 - a2) & 0x1f); ++ } else { ++ tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2); ++ tcg_out_opc_rotr_w(s, a0, a1, TCG_REG_TMP0); ++ } ++ break; ++ case INDEX_op_rotl_i64: ++ /* transform into equivalent rotr/rotri */ ++ if (c2) { ++ tcg_out_opc_rotri_d(s, a0, a1, (64 - a2) & 0x3f); ++ } else { ++ tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2); ++ tcg_out_opc_rotr_d(s, a0, a1, TCG_REG_TMP0); ++ } ++ break; ++ ++ case INDEX_op_rotr_i32: ++ if (c2) { ++ tcg_out_opc_rotri_w(s, a0, a1, a2 & 0x1f); ++ } else { ++ tcg_out_opc_rotr_w(s, a0, a1, a2); ++ } ++ break; ++ case INDEX_op_rotr_i64: ++ if (c2) { ++ tcg_out_opc_rotri_d(s, a0, a1, a2 & 0x3f); ++ } else { ++ tcg_out_opc_rotr_d(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_add_i32: ++ if (c2) { ++ tcg_out_opc_addi_w(s, a0, a1, a2); ++ } else { ++ tcg_out_opc_add_w(s, a0, a1, a2); ++ } ++ break; ++ case INDEX_op_add_i64: ++ if (c2) { ++ tcg_out_opc_addi_d(s, a0, a1, a2); ++ } else { ++ tcg_out_opc_add_d(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_sub_i32: ++ if (c2) { ++ tcg_out_opc_addi_w(s, a0, a1, -a2); ++ } else { ++ tcg_out_opc_sub_w(s, a0, a1, a2); ++ } ++ break; ++ case INDEX_op_sub_i64: ++ if (c2) { ++ tcg_out_opc_addi_d(s, a0, a1, -a2); ++ } else { ++ tcg_out_opc_sub_d(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_mul_i32: ++ tcg_out_opc_mul_w(s, a0, a1, a2); ++ break; ++ case INDEX_op_mul_i64: ++ tcg_out_opc_mul_d(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_mulsh_i32: ++ tcg_out_opc_mulh_w(s, a0, a1, a2); ++ break; ++ case INDEX_op_mulsh_i64: ++ tcg_out_opc_mulh_d(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_muluh_i32: ++ tcg_out_opc_mulh_wu(s, a0, a1, a2); ++ break; ++ case INDEX_op_muluh_i64: ++ tcg_out_opc_mulh_du(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_div_i32: ++ tcg_out_opc_div_w(s, a0, a1, a2); ++ break; ++ case INDEX_op_div_i64: ++ tcg_out_opc_div_d(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_divu_i32: ++ tcg_out_opc_div_wu(s, a0, a1, a2); ++ break; ++ case INDEX_op_divu_i64: ++ tcg_out_opc_div_du(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_rem_i32: ++ tcg_out_opc_mod_w(s, a0, a1, a2); ++ break; ++ case INDEX_op_rem_i64: ++ tcg_out_opc_mod_d(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_remu_i32: ++ tcg_out_opc_mod_wu(s, a0, a1, a2); ++ break; ++ case INDEX_op_remu_i64: ++ tcg_out_opc_mod_du(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_setcond_i32: ++ case INDEX_op_setcond_i64: ++ tcg_out_setcond(s, args[3], a0, a1, a2, c2); ++ break; ++ ++ case INDEX_op_ld8s_i32: ++ case INDEX_op_ld8s_i64: ++ tcg_out_ldst(s, OPC_LD_B, a0, a1, a2); ++ break; ++ case INDEX_op_ld8u_i32: ++ case INDEX_op_ld8u_i64: ++ tcg_out_ldst(s, OPC_LD_BU, a0, a1, a2); ++ break; ++ case INDEX_op_ld16s_i32: ++ case INDEX_op_ld16s_i64: ++ tcg_out_ldst(s, OPC_LD_H, a0, a1, a2); ++ break; ++ case INDEX_op_ld16u_i32: ++ case INDEX_op_ld16u_i64: ++ tcg_out_ldst(s, OPC_LD_HU, a0, a1, a2); ++ break; ++ case INDEX_op_ld_i32: ++ case INDEX_op_ld32s_i64: ++ tcg_out_ldst(s, OPC_LD_W, a0, a1, a2); ++ break; ++ case INDEX_op_ld32u_i64: ++ tcg_out_ldst(s, OPC_LD_WU, a0, a1, a2); ++ break; ++ case INDEX_op_ld_i64: ++ tcg_out_ldst(s, OPC_LD_D, a0, a1, a2); ++ break; ++ ++ case INDEX_op_st8_i32: ++ case INDEX_op_st8_i64: ++ tcg_out_ldst(s, OPC_ST_B, a0, a1, a2); ++ break; ++ case INDEX_op_st16_i32: ++ case INDEX_op_st16_i64: ++ tcg_out_ldst(s, OPC_ST_H, a0, a1, a2); ++ break; ++ case INDEX_op_st_i32: ++ case INDEX_op_st32_i64: ++ tcg_out_ldst(s, OPC_ST_W, a0, a1, a2); ++ break; ++ case INDEX_op_st_i64: ++ tcg_out_ldst(s, OPC_ST_D, a0, a1, a2); ++ break; ++ ++ case INDEX_op_qemu_ld_i32: ++ tcg_out_qemu_ld(s, args, TCG_TYPE_I32); ++ break; ++ case INDEX_op_qemu_ld_i64: ++ tcg_out_qemu_ld(s, args, TCG_TYPE_I64); ++ break; ++ case INDEX_op_qemu_st_i32: ++ tcg_out_qemu_st(s, args); ++ break; ++ case INDEX_op_qemu_st_i64: ++ tcg_out_qemu_st(s, args); ++ break; ++ ++ case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ ++ case INDEX_op_mov_i64: ++ case INDEX_op_call: /* Always emitted via tcg_out_call. */ ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) ++{ ++ switch (op) { ++ case INDEX_op_goto_ptr: ++ return C_O0_I1(r); ++ ++ case INDEX_op_st8_i32: ++ case INDEX_op_st8_i64: ++ case INDEX_op_st16_i32: ++ case INDEX_op_st16_i64: ++ case INDEX_op_st32_i64: ++ case INDEX_op_st_i32: ++ case INDEX_op_st_i64: ++ return C_O0_I2(rZ, r); ++ ++ case INDEX_op_brcond_i32: ++ case INDEX_op_brcond_i64: ++ return C_O0_I2(rZ, rZ); ++ ++ case INDEX_op_qemu_st_i32: ++ case INDEX_op_qemu_st_i64: ++ return C_O0_I2(LZ, L); ++ ++ case INDEX_op_ext8s_i32: ++ case INDEX_op_ext8s_i64: ++ case INDEX_op_ext8u_i32: ++ case INDEX_op_ext8u_i64: ++ case INDEX_op_ext16s_i32: ++ case INDEX_op_ext16s_i64: ++ case INDEX_op_ext16u_i32: ++ case INDEX_op_ext16u_i64: ++ case INDEX_op_ext32s_i64: ++ case INDEX_op_ext32u_i64: ++ case INDEX_op_extu_i32_i64: ++ case INDEX_op_extrl_i64_i32: ++ case INDEX_op_extrh_i64_i32: ++ case INDEX_op_ext_i32_i64: ++ case INDEX_op_not_i32: ++ case INDEX_op_not_i64: ++ case INDEX_op_extract_i32: ++ case INDEX_op_extract_i64: ++ case INDEX_op_bswap16_i32: ++ case INDEX_op_bswap16_i64: ++ case INDEX_op_bswap32_i32: ++ case INDEX_op_bswap32_i64: ++ case INDEX_op_bswap64_i64: ++ case INDEX_op_ld8s_i32: ++ case INDEX_op_ld8s_i64: ++ case INDEX_op_ld8u_i32: ++ case INDEX_op_ld8u_i64: ++ case INDEX_op_ld16s_i32: ++ case INDEX_op_ld16s_i64: ++ case INDEX_op_ld16u_i32: ++ case INDEX_op_ld16u_i64: ++ case INDEX_op_ld32s_i64: ++ case INDEX_op_ld32u_i64: ++ case INDEX_op_ld_i32: ++ case INDEX_op_ld_i64: ++ return C_O1_I1(r, r); ++ ++ case INDEX_op_qemu_ld_i32: ++ case INDEX_op_qemu_ld_i64: ++ return C_O1_I1(r, L); ++ ++ case INDEX_op_andc_i32: ++ case INDEX_op_andc_i64: ++ case INDEX_op_orc_i32: ++ case INDEX_op_orc_i64: ++ /* ++ * LoongArch insns for these ops don't have reg-imm forms, but we ++ * can express using andi/ori if ~constant satisfies ++ * TCG_CT_CONST_U12. ++ */ ++ return C_O1_I2(r, r, rC); ++ ++ case INDEX_op_shl_i32: ++ case INDEX_op_shl_i64: ++ case INDEX_op_shr_i32: ++ case INDEX_op_shr_i64: ++ case INDEX_op_sar_i32: ++ case INDEX_op_sar_i64: ++ case INDEX_op_rotl_i32: ++ case INDEX_op_rotl_i64: ++ case INDEX_op_rotr_i32: ++ case INDEX_op_rotr_i64: ++ return C_O1_I2(r, r, ri); ++ ++ case INDEX_op_add_i32: ++ case INDEX_op_add_i64: ++ return C_O1_I2(r, r, rI); ++ ++ case INDEX_op_and_i32: ++ case INDEX_op_and_i64: ++ case INDEX_op_nor_i32: ++ case INDEX_op_nor_i64: ++ case INDEX_op_or_i32: ++ case INDEX_op_or_i64: ++ case INDEX_op_xor_i32: ++ case INDEX_op_xor_i64: ++ /* LoongArch reg-imm bitops have their imms ZERO-extended */ ++ return C_O1_I2(r, r, rU); ++ ++ case INDEX_op_clz_i32: ++ case INDEX_op_clz_i64: ++ case INDEX_op_ctz_i32: ++ case INDEX_op_ctz_i64: ++ return C_O1_I2(r, r, rW); ++ ++ case INDEX_op_setcond_i32: ++ case INDEX_op_setcond_i64: ++ return C_O1_I2(r, r, rZ); ++ ++ case INDEX_op_deposit_i32: ++ case INDEX_op_deposit_i64: ++ /* Must deposit into the same register as input */ ++ return C_O1_I2(r, 0, rZ); ++ ++ case INDEX_op_sub_i32: ++ case INDEX_op_sub_i64: ++ return C_O1_I2(r, rZ, rN); ++ ++ case INDEX_op_mul_i32: ++ case INDEX_op_mul_i64: ++ case INDEX_op_mulsh_i32: ++ case INDEX_op_mulsh_i64: ++ case INDEX_op_muluh_i32: ++ case INDEX_op_muluh_i64: ++ case INDEX_op_div_i32: ++ case INDEX_op_div_i64: ++ case INDEX_op_divu_i32: ++ case INDEX_op_divu_i64: ++ case INDEX_op_rem_i32: ++ case INDEX_op_rem_i64: ++ case INDEX_op_remu_i32: ++ case INDEX_op_remu_i64: ++ return C_O1_I2(r, rZ, rZ); ++ ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static const int tcg_target_callee_save_regs[] = { ++ TCG_REG_S0, /* used for the global env (TCG_AREG0) */ ++ TCG_REG_S1, ++ TCG_REG_S2, ++ TCG_REG_S3, ++ TCG_REG_S4, ++ TCG_REG_S5, ++ TCG_REG_S6, ++ TCG_REG_S7, ++ TCG_REG_S8, ++ TCG_REG_S9, ++ TCG_REG_RA, /* should be last for ABI compliance */ ++}; ++ ++/* Stack frame parameters. */ ++#define REG_SIZE (TCG_TARGET_REG_BITS / 8) ++#define SAVE_SIZE ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE) ++#define TEMP_SIZE (CPU_TEMP_BUF_NLONGS * (int)sizeof(long)) ++#define FRAME_SIZE ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE \ ++ + TCG_TARGET_STACK_ALIGN - 1) \ ++ & -TCG_TARGET_STACK_ALIGN) ++#define SAVE_OFS (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE) ++ ++/* We're expecting to be able to use an immediate for frame allocation. */ ++QEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7ff); ++ ++/* Generate global QEMU prologue and epilogue code */ ++static void tcg_target_qemu_prologue(TCGContext *s) ++{ ++ int i; ++ ++ tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE); ++ ++ /* TB prologue */ ++ tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE); ++ for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { ++ tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i], ++ TCG_REG_SP, SAVE_OFS + i * REG_SIZE); ++ } ++ ++#if !defined(CONFIG_SOFTMMU) ++ if (USE_GUEST_BASE) { ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base); ++ tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG); ++ } ++#endif ++ ++ /* Call generated code */ ++ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); ++ tcg_out_opc_jirl(s, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0); ++ ++ /* Return path for goto_ptr. Set return value to 0 */ ++ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr); ++ tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO); ++ ++ /* TB epilogue */ ++ tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr); ++ for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { ++ tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i], ++ TCG_REG_SP, SAVE_OFS + i * REG_SIZE); ++ } ++ ++ tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE); ++ tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_RA, 0); ++} ++ ++static void tcg_target_init(TCGContext *s) ++{ ++ tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS; ++ tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS; ++ ++ tcg_target_call_clobber_regs = ALL_GENERAL_REGS; ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S3); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S4); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S5); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S6); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S7); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S8); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S9); ++ ++ s->reserved_regs = 0; ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP0); ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2); ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP); ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_RESERVED); ++} ++ ++typedef struct { ++ DebugFrameHeader h; ++ uint8_t fde_def_cfa[4]; ++ uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2]; ++} DebugFrame; ++ ++#define ELF_HOST_MACHINE EM_LOONGARCH ++ ++static const DebugFrame debug_frame = { ++ .h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */ ++ .h.cie.id = -1, ++ .h.cie.version = 1, ++ .h.cie.code_align = 1, ++ .h.cie.data_align = -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */ ++ .h.cie.return_column = TCG_REG_RA, ++ ++ /* Total FDE size does not include the "len" member. */ ++ .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset), ++ ++ .fde_def_cfa = { ++ 12, TCG_REG_SP, /* DW_CFA_def_cfa sp, ... */ ++ (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */ ++ (FRAME_SIZE >> 7) ++ }, ++ .fde_reg_ofs = { ++ 0x80 + 23, 11, /* DW_CFA_offset, s0, -88 */ ++ 0x80 + 24, 10, /* DW_CFA_offset, s1, -80 */ ++ 0x80 + 25, 9, /* DW_CFA_offset, s2, -72 */ ++ 0x80 + 26, 8, /* DW_CFA_offset, s3, -64 */ ++ 0x80 + 27, 7, /* DW_CFA_offset, s4, -56 */ ++ 0x80 + 28, 6, /* DW_CFA_offset, s5, -48 */ ++ 0x80 + 29, 5, /* DW_CFA_offset, s6, -40 */ ++ 0x80 + 30, 4, /* DW_CFA_offset, s7, -32 */ ++ 0x80 + 31, 3, /* DW_CFA_offset, s8, -24 */ ++ 0x80 + 22, 2, /* DW_CFA_offset, s9, -16 */ ++ 0x80 + 1 , 1, /* DW_CFA_offset, ra, -8 */ ++ } ++}; ++ ++void tcg_register_jit(const void *buf, size_t buf_size) ++{ ++ tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); ++} +diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h +new file mode 100644 +index 0000000000..d58a6162f2 +--- /dev/null ++++ b/tcg/loongarch64/tcg-target.h +@@ -0,0 +1,178 @@ ++/* ++ * Tiny Code Generator for QEMU ++ * ++ * Copyright (c) 2021 WANG Xuerui ++ * ++ * Based on tcg/riscv/tcg-target.h ++ * ++ * Copyright (c) 2018 SiFive, Inc ++ * ++ * 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. ++ */ ++ ++#ifndef LOONGARCH_TCG_TARGET_H ++#define LOONGARCH_TCG_TARGET_H ++ ++/* ++ * Loongson removed the (incomplete) 32-bit support from kernel and toolchain ++ * for the initial upstreaming of this architecture, so don't bother and just ++ * support the LP64* ABI for now. ++ */ ++#if defined(__loongarch64) ++# define TCG_TARGET_REG_BITS 64 ++#else ++# error unsupported LoongArch register size ++#endif ++ ++#define TCG_TARGET_INSN_UNIT_SIZE 4 ++#define TCG_TARGET_NB_REGS 32 ++#define MAX_CODE_GEN_BUFFER_SIZE SIZE_MAX ++ ++typedef enum { ++ TCG_REG_ZERO, ++ TCG_REG_RA, ++ TCG_REG_TP, ++ TCG_REG_SP, ++ TCG_REG_A0, ++ TCG_REG_A1, ++ TCG_REG_A2, ++ TCG_REG_A3, ++ TCG_REG_A4, ++ TCG_REG_A5, ++ TCG_REG_A6, ++ TCG_REG_A7, ++ TCG_REG_T0, ++ TCG_REG_T1, ++ TCG_REG_T2, ++ TCG_REG_T3, ++ TCG_REG_T4, ++ TCG_REG_T5, ++ TCG_REG_T6, ++ TCG_REG_T7, ++ TCG_REG_T8, ++ TCG_REG_RESERVED, ++ TCG_REG_S9, ++ TCG_REG_S0, ++ TCG_REG_S1, ++ TCG_REG_S2, ++ TCG_REG_S3, ++ TCG_REG_S4, ++ TCG_REG_S5, ++ TCG_REG_S6, ++ TCG_REG_S7, ++ TCG_REG_S8, ++ ++ /* aliases */ ++ TCG_AREG0 = TCG_REG_S0, ++ TCG_REG_TMP0 = TCG_REG_T8, ++ TCG_REG_TMP1 = TCG_REG_T7, ++ TCG_REG_TMP2 = TCG_REG_T6, ++} TCGReg; ++ ++/* used for function call generation */ ++#define TCG_REG_CALL_STACK TCG_REG_SP ++#define TCG_TARGET_STACK_ALIGN 16 ++#define TCG_TARGET_CALL_ALIGN_ARGS 1 ++#define TCG_TARGET_CALL_STACK_OFFSET 0 ++ ++/* optional instructions */ ++#define TCG_TARGET_HAS_movcond_i32 0 ++#define TCG_TARGET_HAS_div_i32 1 ++#define TCG_TARGET_HAS_rem_i32 1 ++#define TCG_TARGET_HAS_div2_i32 0 ++#define TCG_TARGET_HAS_rot_i32 1 ++#define TCG_TARGET_HAS_deposit_i32 1 ++#define TCG_TARGET_HAS_extract_i32 1 ++#define TCG_TARGET_HAS_sextract_i32 0 ++#define TCG_TARGET_HAS_extract2_i32 0 ++#define TCG_TARGET_HAS_add2_i32 0 ++#define TCG_TARGET_HAS_sub2_i32 0 ++#define TCG_TARGET_HAS_mulu2_i32 0 ++#define TCG_TARGET_HAS_muls2_i32 0 ++#define TCG_TARGET_HAS_muluh_i32 1 ++#define TCG_TARGET_HAS_mulsh_i32 1 ++#define TCG_TARGET_HAS_ext8s_i32 1 ++#define TCG_TARGET_HAS_ext16s_i32 1 ++#define TCG_TARGET_HAS_ext8u_i32 1 ++#define TCG_TARGET_HAS_ext16u_i32 1 ++#define TCG_TARGET_HAS_bswap16_i32 1 ++#define TCG_TARGET_HAS_bswap32_i32 1 ++#define TCG_TARGET_HAS_not_i32 1 ++#define TCG_TARGET_HAS_neg_i32 0 ++#define TCG_TARGET_HAS_andc_i32 1 ++#define TCG_TARGET_HAS_orc_i32 1 ++#define TCG_TARGET_HAS_eqv_i32 0 ++#define TCG_TARGET_HAS_nand_i32 0 ++#define TCG_TARGET_HAS_nor_i32 1 ++#define TCG_TARGET_HAS_clz_i32 1 ++#define TCG_TARGET_HAS_ctz_i32 1 ++#define TCG_TARGET_HAS_ctpop_i32 0 ++#define TCG_TARGET_HAS_direct_jump 0 ++#define TCG_TARGET_HAS_brcond2 0 ++#define TCG_TARGET_HAS_setcond2 0 ++#define TCG_TARGET_HAS_qemu_st8_i32 0 ++ ++/* 64-bit operations */ ++#define TCG_TARGET_HAS_movcond_i64 0 ++#define TCG_TARGET_HAS_div_i64 1 ++#define TCG_TARGET_HAS_rem_i64 1 ++#define TCG_TARGET_HAS_div2_i64 0 ++#define TCG_TARGET_HAS_rot_i64 1 ++#define TCG_TARGET_HAS_deposit_i64 1 ++#define TCG_TARGET_HAS_extract_i64 1 ++#define TCG_TARGET_HAS_sextract_i64 0 ++#define TCG_TARGET_HAS_extract2_i64 0 ++#define TCG_TARGET_HAS_extrl_i64_i32 1 ++#define TCG_TARGET_HAS_extrh_i64_i32 1 ++#define TCG_TARGET_HAS_ext8s_i64 1 ++#define TCG_TARGET_HAS_ext16s_i64 1 ++#define TCG_TARGET_HAS_ext32s_i64 1 ++#define TCG_TARGET_HAS_ext8u_i64 1 ++#define TCG_TARGET_HAS_ext16u_i64 1 ++#define TCG_TARGET_HAS_ext32u_i64 1 ++#define TCG_TARGET_HAS_bswap16_i64 1 ++#define TCG_TARGET_HAS_bswap32_i64 1 ++#define TCG_TARGET_HAS_bswap64_i64 1 ++#define TCG_TARGET_HAS_not_i64 1 ++#define TCG_TARGET_HAS_neg_i64 0 ++#define TCG_TARGET_HAS_andc_i64 1 ++#define TCG_TARGET_HAS_orc_i64 1 ++#define TCG_TARGET_HAS_eqv_i64 0 ++#define TCG_TARGET_HAS_nand_i64 0 ++#define TCG_TARGET_HAS_nor_i64 1 ++#define TCG_TARGET_HAS_clz_i64 1 ++#define TCG_TARGET_HAS_ctz_i64 1 ++#define TCG_TARGET_HAS_ctpop_i64 0 ++#define TCG_TARGET_HAS_add2_i64 0 ++#define TCG_TARGET_HAS_sub2_i64 0 ++#define TCG_TARGET_HAS_mulu2_i64 0 ++#define TCG_TARGET_HAS_muls2_i64 0 ++#define TCG_TARGET_HAS_muluh_i64 1 ++#define TCG_TARGET_HAS_mulsh_i64 1 ++ ++/* not defined -- call should be eliminated at compile time */ ++void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t); ++ ++#define TCG_TARGET_DEFAULT_MO (0) ++ ++#define TCG_TARGET_NEED_LDST_LABELS ++ ++#define TCG_TARGET_HAS_MEMORY_BSWAP 0 ++ ++#endif /* LOONGARCH_TCG_TARGET_H */ +-- +2.27.0 + diff --git a/loongarch_bios.bin b/loongarch_bios.bin new file mode 100644 index 0000000000000000000000000000000000000000..3aa4f36a853b0d605d6a6dd61d933fa43084c580 GIT binary patch literal 4190208 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�`g?nIrVio3c^K4|e-Jn(WOFsaNIT$_= zW-qDO1~_?lKCp=}0qY8~nOPdbMK=Mrn`d2?HM zp56d1dQR0yL@>Jn&vIGC(eQ->%fd%bg2LoQPI$8Y#S9v)wOYj)3Y-%v8$YAmdtOL+ zeqD<9oJ7MhIQwp*u|CNr{ZxWA+RwQ9Z&ex)`}yr7cgi5U>iK#T!XYsnf_8T1A*@o* z$@Z*Gm{w;91;eg_lasJlD zRb`<51X4-}Us}TN3mfDkj;asf&Fji_x;XhJKg$qn{jUvFA!{{0{zIbqfhuOT5akR7 zVv=(*2**69mK>7j{Ivk|exb^-h{RvyW$GQa)!S6V^{l=9d^6>*Gc;(>_JxtjnnNp= zOX86=wj-HM8O1LC4v5!?C!?p*oUK z3;m7ox1l}xbC?3}K)x$gNjP|2X20;!TvQ%`=G}R&7Yi02JDJ=!A#t*Tj_rC4TF^}Ma+2PPXB`qkDDZ#@WhUZotwS1Do0lZH@mEMjCbR(!s5 zu$$vE9~3;C`A{o&x>cELOAf%uj}685HT$3Du&-IU&x^;r5<5z-k@w+jl~vfevMhLB zfp6~VhQm4nVoj2bOa_qqUueO0nP(vLoymW)fkvbdrqX#Pphu{b+u}sk5y;e9=aI-F zV7TkrhhBa$Vn`mVj;6jY$4cXgR;OEc-8~$pXq?qlmMMTsvt$0^6&4CUkk_6VK+$cd zD8P@7N)5#m_Es8C?EWVuOhTq}d5~g0lq@YX03~A?AUPFZ(F!{2=Tp%@euMoi5Yr)% z?;;OjV@xqG@W<1=i!%T4XqvTgf=Rz0pIHpD8t-jJ5c&re%GE zK^6+v3fXuJ8zMeVlqd6-eWz0TN#axv*F?w=lTL{N6tG(aUN`cSa(_!|$_u862<;t* z`422p_R`}W&_uyTbo9Td&fu9il2W0|C4K@nMHL}s*;WnXzc+17UubOuocmdlrz9{* z9F`7`t347GXQU`~RHcsv=SyOWHMmP)Qn_wn#s{!PIoCF;gROT>-ojOW5^^p5-uNbQ z#viLmQIz%z?Ka#-chxfF2wfI&qq>cql4O62c$LT(wMM`+dmPa!uTiG(aFaXgi_L@k zr>i$3ke-We0P#(I&!mD#APQ6~2#&LZ*^mo=6wy=NxbDUkjQ7AAYl8W}ae80-QPV>A zWLRTt#%S-l7*viIx9j-@o3RJ}JY!?F`^24GxhLDK2HREUjPlT#amQLyfAhmQ;~THT z75a%dGZYD4?lWrfVxAbo*XbSc1!4UF#a)X8ce2eGVOov03Pi@_(lh-NX`2cX_KcK5 zK0YmbVkd1{9cXQSn#l~kNxlwqJpQQ!Y5in@Cqutj_7b%eRqA}hQSSC(t=g_z!Yh3r zu2aJvO6aCN+d-R@djG^7QO4;)_RGb&O~E`SCNRpv!^xq;Ck5gz@~wWQj-w0jHA3S-lL$;)$drS>n{U2BM} zl$6(^h*MKN7$y1YU80*r&9nyRdeK29k$F33MwFx$o0V9L=^#Kh#JNSL>w2utJB8A2 z&vk2$jLt=L?N-028!{neDu(op)H{Qn#~w#Xti`9L;;%FO#=*?-Ilurc3Y)dp60tsv z|JLv#k|(@M@fjOwzZl3?B-d;kC7WpCua)2 z7O6bbueH=WCB6>aoN>W9XHIpg+w26ARY^#b=Q~U%QBcAt#D=)ZNOV*K%_49bA8V6l z_H2_LqjQ=C4oCl0K*pyO+5VOpX1Tt`$P0Em-KRlBt5w+wY(emBjXT0@k1|7l&E8Sg zig~+HEKZ3TNk|wSE`mEF9&G#1(37!S!!$BI!@-AV|MJhEv{@5J$Cv{ax>b|iO1)K2 zd9fL-waIu-Bm4K;44<}`aIKwiq|I?Jp@PIK5|T0stak1}B7OGj25#O{;aThB5D}Y- zCg7RB(afHlsCz|ukp-*MErWs!d8CuhnH7+yKZJVO);hc8^J8)vd0lTWi)+A^Kk zrTfdjyiyTgG{-2IVGGcd#($o8{1pbl;wsg%g3&{Ig>;zP=Ex8ve7+#_AWA#}-G##} z@SLja@IxOuj5BK_AxTNlt}+rUCG!NpUPO+6DBdJ0xWGZFg~ z!6z$#%Ll|p$}nQ7Mn7}f+?8xi!&cxmr2|=|>ytx3Ijiud-(0_hqApI205Xi3yvS`} z!cI~0$p}#F(ztbFxahWedyvC}Q6#BMmTprKL-~#_)_hK1LnsK!M(x9Kk_fEQr_2bM zq`Jl$?|mN6Jq}~Kyyhm+ELQ67RW5f30q^c;%hW`lm}ew$HzcqO^qogQgIIvFbzb*8 zo0Wp;OjVd_@Wev`N3(MF#Y%yy&J%9l-G5#$^{vE>-7?QfFAosei1!C)`mzI1Jy^I0 z?XWt&9VUuiq-bv&W?&C4ix^>CQC|tpOo2J|IQKK7p+Bzhxn_xlGQHcUIy1m`kZgxoT2a4XT$@YbF z&`2S&LiN@PlGRBOm2xlPi;I2m(B-7RljyV>l~(4%;P>bmW<3)-5n_^2fAGuT={bp= zl+%`Bg?rKBhzL3$jnJQXhsyDT%vePBF3a1_6nXl>Ynd^ZCWCzt+r-*bOU`rA?u#<4zD=^{BgD$w^~xr2qmd_W>uDp_vg{)pE* zg1*fop0sPZYwGd=yBbT=kc(>A@aSXW7&EImu=n1&Te8u!sLKu?9vk%CJ*OZov^f!C zKbTr~NqrhM)v(a!+LynT# z;HNXI#}C|ak(5gz+rQpE*HiXk1podZ)lDp_aascSAP}b1|1?vdALIE#4YMHjk@5N{ ziZSjDIbazbY$QgbKeJIRQC9f1vQO!y#^o1Zh#533=Dbo8g`Jt>G6c{oo3=Y05D3=a zB*M4TJQ{oD5wuU@HQW>UMz50K?4ZUev1W$FBABnB!-kAOLs)mHE*XkQo(F%-D6|by zYW{KL0=XNMay&ap{kOSYXQ^vSSQ4Ovdr=sJH4kx#mNJ~ITWBsRX2@>IHFz~?{rt@R zXqp6gCOUK5bijDYHqs7X$0)lNH7R2Cau3v)-7BEv%wH4g>jzwswel7xNJ)%#gi33w zVkWVyh~8^Z>x^swe30bf@S(nCgc|ZrLHO&$+IV10I!dz7E<7;Wl;O&Fz^q8 z%^?GWN3*;??5AGuB{{b9)xxbkH)br}w%EJ{)(!peqj)FkGW|-AV!QHXm;gIm!a(smIwC{9| zRxfji&w!mw@H&-{DrOJzD*oOm3pHxLtH|7Lp;%x+=kDgF%kKH$4`st3NCubxw)ZoI z{cwLhe|W}|jij*ar>|Yn`O{fdw#h0X&luCB&W$(*c+m^=szWfE2D70n=-nydQzF0G ziolz-+U4*r=~Iz!LSM zrpm?!=<<25w@@->*iF?Y$*+RJ+)O+e`$_PcF40sWXrn6nK6JrH0)VK7CWokfPWLa; zs*st!Vfv=c*!`4Ytx$0RBVH8Y6A zc2RfWCk!t)yp^Z(~YR*poo3N_&ykbsid=mz1x+3VcfM( zP@JqML>DmPBpEIyv|HZ|%sm*+{cA-{(Ei{VI3!pYt-t8E&hhy)O2>FM^oA+Ile7!~0K*hBrK)nlp zIhkQ&(7SuG(VsO}s^~oHcsUBM$*6903KQjxBVMyOU;o#SUG_{q=@DVVjRZm~^AUVN zkA5gx2j+3~Y5ZlselVM_#*>96=)@Pr&}I2(;Lr;;aDD!S-UULup>rRL{k`?xnO5cAA1 zOAPmE8CQP^MSM;Z5xnuax66cmv2zVYTU@qR`$s2XuEYhVB6)#%6(UkVO;iE?CRA!# zJ-SVK4DoJJ(LcFm-%~7|nso>WVT;Bw&*P>C5Q`Bb8n5j^0+;0*atY4xH>*P09CQ*f z;S#j!aJ>{NtQg0#XN%dHh8#99g^;V`c0A&|c@f%Eb)@*fFE*J^2n^~T4*3r;TJcVq zrQ#YkD@TIXj+Zz3tu-|oj-uyS)}k#Yw&?zcGYFUj{Ltjdy!NDy9Q*#8KyFH;KdSq0 zFYltYjs^;}6v)28Kr<-9LIYBk+GEYIV!#k??JtZqw)3TB;0pxWk!!W525Oa-*vx9b z4PH5HHNM?bd(g|_7f?|Ot*AW35XL6lzE?o934$`1R9|hQj%2%|hKc-|8`I5;X zN7qFP1A>OG3<=7w168G*=)2HUw^tjWPYx{cVzDg49L?6#`=9z^3>63v{8!OCo+tc&lU{*$HfPO zB|6y#OsEJsV$cGOZ+TXCPJ&q{2R=58w{a1$LP#821||&a-OsKQ!PCJQL5Wlr@*;Io z<<$R3hVW6N=7~!nJkbP&NkeZB)%3k0y~J(UANxy}P!6B2X5SaTqx2E3qW_wngstuh zT2WYL`M65d;fkAKyEg(b7a_4`>LYOPehf*Rdl~$5zL$ev6fCKs19y z#hgbei$E7NE~qo9*@szdzTuaDo{iU+Gc_4pHYj#9duSUVIBQGd7q95`Z5AcaA*FFI z8cT_9S~NZ1!==sA1S*U_T$Xbit`As2R}hV*dVmrW~ufrEyVaHgXd4- z$tvD4$(MX`k|jg6Ja8gqyhx7$WZ-+yH2r?Y=dx>SmbaFaM#+nnvjVfyCSC|NtL#u} zlk(`WnjCo4^M`_>pBLd$^J8q9y&tr7e|9`+b9Wvg2-(EUp-MV(F)mGggvf69gLZmVHU7E;7!^toouyMRB;H)9ZC6;(mZWOo0(;BrWs;`0pVq8;(>3BYx zT@^a=g!w@PEJBz5KY1#@?6z9L=YSGO0KPXXza_h$tI8j&cI}~5*n~aUx+ntvq3U3Y zM!1HKo>>F8Q7SlI?}DU672TolZ&0k^)c}6Op^WG{}de{nas3Wx(+a5 z#5xgP?BJguY_m6Z+X|4(Cwf^`imCldRg02lmfa77Ex~Xi@4(j^(b6+hX5k1nAfL2| zbU^RE<>>M;PLGr@OvxDLpl+K##JAWj<4L$~)CFMq&YuG^a&}YMzG%7arsQ39{PqZJT4r zyu!SYdUHhDzuLvY+meGVhX5%y!q&H(4RtJCN3e8FK`=Px<@ljU4H7q}jJNzQaS&)R zz=ked{yC(#t5Asb8xgZ&#MHQ+cFI7dd#hjT8~2Zldlw| zFkiWRy4$5ayz~6uKXnT=2G=7D^)(s~bpI*aX?JP?@gM7NKZX99!?)4{eoQ@0_B=LM z8dPx@GLd^ww-jF?7bn5fubO?+iCJn`BiXRLt7{oWu71pP5$Y>Y!Dc<*fCOrF0#5j2 z>P(}J3{c2xRtJ<0)OLI)VzL^-0SY3@Nb5OGuxE!mU|z;YuOg|3(hSdYqJUK8SvKg- z&MBu{q{YI31H|BZR|T@5 znI=t2&}JBtZBOvjr5eY^LKo?!xs>53vT;vj70UCdNw)zIgHXnMxpoNkks%tm>E3hG z`AJOonZv#mA4w=)_K??CtUS;bafk6pZ|NnQD1B>GOclY4geLurFrcOw+Y*|b)4NX! zQTa96+mc<$Ow$fjoYP%+W5~C<0%%`SMW%MpZ$qquKSBT^z{}q{)}ej6y@}B!&4*bJ zvl`zKp}-gEJdV_W0z7CBuq>aH+mPepO#9onm=er+=A+%cdvZ7dF*CdSZML2*MX|b| zax%saZPsp_QkBdxLsAX_+1qBiOchTEAIRovbT;Kpyfbhw_|nonBK#~Ku7y`xA=XI& z>MWn@Y|54_S6+DZ_VLyLLQmO~K50_M*VbUOmFaD!0`A|y?ZJMZ*x-1wPTq=j`{A$} zQOLtw@=T^o%!sF#a6o!$wJ$bgzjU7qTLWIDGr)Q)_H#4^S55ZabjHMD>!u>yAIi4G zBqIg6=EDfHYJ;KPp;sM$m{~Vpk-v9V<)_B<$*|tH_dZ#FiCeW+!w1kAzQJ#=7tS&Tn5JdY{=%Z+ppHx zpsC9qrF~3jI>vj+;LIH;Fx!6`I3ECMJ(l0bOuS+Okdzo80EO%7!E(zOrRUNXpb+m_ zjJ2&Xd{BRLG;|GNpYL>d(~?K)nbCk7EyDfz`#jU@SWW@ZW-*T+D$}_1T>}34`YG#*?3E-$t_q*ifX#rZQJsbs~jy-@^;k zG^I{2dScFfK?SM5x6phnc`2Gl&CcZOWGl`dkuP6X#0)~JbGPN~F&40#Xtw#ddVe2K z4nQ7dDOs-nN9xgRj}J)lvnit73x@*n_Nl7S&BTIR?-)01%lF6idTp zI)%cb#g%-fYOJbR@Yb7NnVahf7wHA~^-hTy__+Os$3QBxkOy!nRqLBQtv817QUQ3e zi8Y|z;)GrFx9e2-yH(g}iD2=6dDd~8GWRGCt2_=eENSF!cbp320Wfh! z?EiEni)grqoiXrJ9bi7<4D7aMXPb0)!u4mhNHQmXvJ4K>%#5gloFEx2m!`N$fTmJQ zy;1j_$kI-AFT&O>kp-A!7AI6MgIV|*m%PM$F})=EPGI<(DB87x<+$xytIWettEe@p zbb~}3#U((z;5VB$s@lEENV(cc_t?4}gF9wd1v>VYnPCo$f|fCtAE;>ieZWPh0%0Q{ z6!O_+)DfWVPOkM*ePzK3%_iQECra!b zVZ}E1`dGSVIxhjI;TNqmEi!cBLH4Wr8QJ9QNZhSKt#i4#&OovD*(INdcyovTI*R_R zC@GIF%>^jw#egO;noRcaND=&h?Nk;FX$`ahq4T;dTzdFE=yVrb#wTI^Ri)NXgtE6U z{yEV!29HExz|~JNAk--80lzn@g*;-H5C9cvwV&v+d1zV68i7G`gw0P{K?3fpydPjR zWI$?lw_D!8)Sqohb9A?4Y35y@-Ca= zs_@U0-o)`t|s^36om(C&@8GhiDUDPA=+Y*YkWg5z5=h<;y*e29Q9i9{Ren0 z5KHH$HzMAf{TGPtByubR`n7z_PrK!D6WlN9k-O59Jnoefkw(`6gEcfLW?+)pVq;ja zzWjc#5s#qpzW}g`XQqA$s&RKA8m{$Rr`$)-F_1Q&B$Q^#;+BxHDo87LPl&pm5(#M- zUSO#Z?b@!FXM6TIetjZA;JQ=vvxVMcU*1^m+sb*|tY4Jt=*r+1AUnNhk;bcSlrcENR=h~tvb zvSjPf*+3dlmV}t2%*^Pir#Fli@a{jX2eW5}pr%SLePf6Igxu9}lrXV@rmpG;a*)z? zlZn(e7oyr|RLLjMhu=mobZpr9PE*H;I#U0aiP)k>RJA)pI2|K!jVF_TjmhJCXC91i z2QXzaf5~uD5Ci!7+X`qQ19%E9q%o8Z`AqW#r|f*iP!Idi)ClUrtdB`KrPXVlmM;SE z5`p5lPX*-Ovti#do&|7GLYdD-y&|1*%Wc4TUPL}PdpKQ0tQ0l7gtjZy=Fe44tF!x4 z#eDBQ_5|3$8Mw6&6k(}?`eDFG z4DIfj4q(=z+qr459l6FGEfO(l(}V~xVw*qz$rc`r4uHmd z^hvLt@BXgYew_2bJb}V{jdz_Xr{TjMnw;}o*}ewT6QR9U*r}Tf!EQFq`(_fs-M~{Y z(q^UBp{FW^G*>y0Nn>|!f6MBHJ_S!~~AkMV&V1o5AR$^h_yq z7}d&k3*?Mfc~&a;@zB9nU$KI44mIFFRPYB-Olb=1fonSmBNzOb8`MoDd*(vJjin#Ii%QIvg6K?bdyXpy zdfjeovL+d2^<_4NS1F_0Q|B|l3;Fw1liMAH z?Nrpe3OI{Ea~K&tzagZxTsDk4qNrO9sXCqL-|{>?Z@r~4OlS3t0TC@@)j5sXZ2upX z>ttj@exgI*@@da3Zir;&*J%CM-Ia-hDCWiKTaL>o2s6?>sl*w$`Cii^I%#X(;W<>e zY}Rgori?yP(7td=gotoH6_5rLL7svmjUryeI0}r)K$j1?TozngE-8jmkT}`6`Bfye zNO2#P95Y8-&_5cw2`@k49TSVttqss2Yp9*;XR7BHqi-%^yWEUIpX+}qF~{2G1%xPU z`>}u>_S`IfG(}R-C4*OY#Vk;**75sKs%ZTZ54sJ3Ma+*x?g2R)7T4D)H?FgzUA7DE4?KFK3{hGdOGTk?Jy_mi3SE`0@aqL}zVR7*`X-BDcJ*agIZ8zE+;^VA-3dC_heF6W= z-6fx-X4L6`DiEzs{tZE{Ht5d32yfF1Muz4rO}8WOw~Mj(&hI%PO!0+z6bq$>BCU~f zq`ANx!<7WFJ1~iUIAx>Cyn=9eQDWR{xJNJ_Al5V%u+3gw&ZOgG)wq1&)g^ueC+V{q z_YK8ALnziCm33as?f57qlrTCFs)4AW7qc~X80Y3l1WMlFY6bEVz+$-Lfz`mAGQj;!m6eqibW;QmZkH?F*Qb-I3lCfBHM@RvvlQ<*_?+4+`U zREE!w;uM%5!}vrnZ{F;$4X$#IQJq1A!wU;96LA=|8-WqreW;*(EDn%qF(f?!EVJ4c zXckwK*2b;DU3ttiVnEXz_x?3CneV>l^0O#_Z{ZmgNYqf0x*A-?@E1I^>}NYcP~@>TYl(S07q2p! zGO7*|Jy!5=B2JN^E)~pRHk6m)ScrtjxNMVS7r3YH_4Klp4^2DZ|c zBPaVGYras*)Du&i1$vp!5|bxEMzi~sKdhi`YNF6&RE&5E@|Y|n4apw1pe59KlyY8? zdzV_J7=>-BrG)G)gjFKA3#$ZfskbLy^9CnNGko2Ks(t(Bo8lF=rQ9#}^w%z5y~mo- zwRRBk_KWN-*}y%tz^}$;F2=(x*IJ>`ESk>((sYK)k<= zBDGQafD zn*z}m(Bf@J)v$_`q{tPs89|U9;quV_+vS0Mk?nb>-C4@#_7n@g-pO8=>z6>SeA~=j z?f~bdFagM21u3{3qLv#@r3(-9r`^oXqd2xFveoq7H-R*TXAC^&n)P5+$Hw9d*qgm= zi^V2omWV!1o5S1!)Z2US>&%%}gJcGrm@=;t$Ku@Z}?2qlBP zG7Qu-Ok`L(35<0V%Md0w%~ifn)feK=`-->P%p%dxyzvP&2o-b}+MP;{%ESVGtbKv& z5+h(IuAruN#9GeY5sh^{QSmxpev?amGa~o>JwGMqAVrcK9&t`tPx;ac?zSV3IdwZ` zmLT!~Oa&;M8e5S7$y~>mcU6iQRGQJUPWEp`?BuHfnL6my_8R&n0_&AoAK*sXe9SI~ zM;x-of`A9guo=?i*)=YgR!o5`6nR&SEiEv)?_GkIkMaQe4~6d5FIDv$y0!Pqmp0-g@~>e z2}O_L!w|b5cvP&cU0kX<`Pw<1-XOahbt%U2qtq^lK^$3oWB)G!7bIn;r*gRxL zQiVU7p>db1e#yPd zhdk?b;%b8@TamGQqh@yrKG4h@gYPu%TVS$%faX)w!`@@yc;(yJuc=#!4mE|21Kpx8 zm-Aor8%y}o$ulxeDv9rKQAF0^ad*jyTd3&WVEr@p7uj$pU? zKau1)WDYHtKH+Ta=tCva&!6}WyH9h!|2J6j$|SOjV6wS|j5N1mf2;POo92!p;dW}| zmOTEZiqenj)e{4=WD@txolS;EZ(>@FdwaIJ>s|}&`^{r2u$j2z|c4xrT zJ#P5elK+nwp}zMR?s3)4AY+JI9XQ6?OIMFV)QTIQrijxR3dI8UN}Yf-pk9f!Q@Vz3&Qt}(bl zN^^qhg0s+6r<+mDv^6W-<#dIh*P@*{D^0KlDH4_?}v!ip<}t zb)IYP`z(DQZNX~*8FJJspmS6A!Tz?ie>jniQ^QwPG=e%SV6Z|c2-`f zG!_()rG@LrEC)3D#D@47lEzAVAG>^SMa$MDOOKKJ#Z(ukTNTRH30m=I;8lm9BtQvETK%Dy&}r>HZ8`iqYC`GgEdx zAu!rjuKRlE>~c`QNV!I*>Iw6@amZMR0X_tWmbds4wVhNb`@AXxq7HO~N(KS-A&{8= z%kC9QeA;E#HgVH1=iW&36^IYZJEk!y6Bq_JYi?u9cEduY8t4)B646_c0Oidlm4F=I zDWzMlmPe=y;Aqa|*q3sB+(Y0^U<)T!mb@ky^8iXh6vRSMy$Q6jCQ+myK7>a>wDoks z9?)TL#$sEcj%*E|5L&u0^-ECss$WmrCdOE=oAqtx5S+qnD}dAb4H)?jU8>qd`=#yH@z}C89C&j2+Ejb=^s_b+yfGp^i2FU z$Ow}Sy0s{wXkIw#=_j~|Oe`hM;!dK&Ljd_}1o-by@*RMSns`H{md#l0F-!Y^*tO=! zXM`C@@6miSrV?_e@3Zxi5p${Ac1xY|!vLe;JKv}=gO*>am{i>p)eXJ85`69Mem4;b ztG`k=pC+ilQD@a_5YJ$A_vEzVOpwqs@M$-05vku2@Ug~rBFt?M6VWp>FroBkPUUQb z+^O_yqoOSS!SWU1GkjBAgKsbOPV)JEtHD!CwSzXX&ldJGRA+kB$xxLqt zR^(9)X;_R~Btu2(RSCiH;POM_IN_a<`0@r$%p5|v*g%{y#VHyRDroDV8>UOaL{(=% zObnTu>MdV?MVzcpQzRg>x$1--QlrUhu{12Z!P@x)Ggi;PtvP3du{@H)ZcgifkJvnl`3hqzu z-N)JAr5`V-s4m&g&Ns{NnH8?X2NCtIdnk2g-5Ut7n0o#e{sx+~UyYqIC%acwl~wh!jjEu%di9e%A`aSV zDFa+@o|3Z@(Iq&x%F-YjBvC3Tw>tPU6G?Sr^>(8ocisIF_rGMI_AD7&3|0w6v=ln2 z6j`J=V=WG1!{8Et)@OV?4~s1EgTfxs)6AmgdWcE(CfU7W4ZE^uoz;;_b7Axm`<>@Lu%{|RvU#5_K_wKrdG1ra&U&oWSR zYnM4F+_j!mBRL={(|zb1n6;e>&CYs>nuMrkS~HK^`D9&*r(YKRm2~SBYP@gmu(H8S zqySY>l8;AXm)Gw-VE^e8Kr5=%%ZdRV(A+&76Z*t*Bf^$mXU&r;ph*mKyFMj#L+V*e z-l=2&X{bVuzM0_u5!`R%yXzBL>yMm@()_;_?`J640QL|dlJsugvz~gsOAbQZT(`cG z1Uu;`xKc@_sxeUc%DHzBcC251Vgk4@)&a^%g+mBEgHn3l&uJ{ZzF4tE`snd@@3L zi^|msOK(7Z86r!a?Amt|k6p>Yt~aKVAbt2Q8PkUvEx5Aa8TL=&*Jcd%L#rHOh-^x; zJ7W}~4jI7%DK9aH)_`%~0^vZBI;M)wE+1o?ksPb|#KZcOXS_0Sk^cHc3Ddqa5r7-Z znimYyIXOBV=f;4P#q^zYcKe&}w12m?Kr(%(EXvr#+nm3NW9xr-=q_T@<}uM$7-v$} zh}LbT`I8>`83s{T0(?up==Be@m z9|g&6$HGq1q#DRYL(go3Pxl}jqtggEpd?4=UGf<KGhX|`Tc-bqij0$NF8750$(_XFS{d5A`E9dT zhxibEcw(SwM+i8cMSkQ}y$AQ)E(4#DHQH}MP(a37(XTmxkJpKdY?d0`m%65IW1)I@ zi^LfO+ChAe6v|~G&@x^+Q8{gJ)Q9S9E3CuxpR`F6aE@-TL6kzauDM|Hczy*E;f_g; z@KJq{I6AYUOWz#ew5PtU*bOo#GFPm6%%iG2=jRO6XG0}@U0WK`U)$z2U&GgKCK{!L!s~z1c5CvS$f{$y#y{H^hKfcROCh3` zKBh8*qGb0*qrDPv!ihxy>&!%E>vYVU?C=laYt9DmXj7Hgm?pmf>g8q=WQfM(tphgX zrOGmmdO5D0>dMbakwQnE1opSL$dSC4=)c*|A`spS+mT)Jm}hU~^h__Fi8jC)Gjpds zCl6)rnw?F6A57d|eBDa@ce;vju%FfbdWkS<0P%3B&l&a9lq3nB5`bsRVmWC937Ej1 zH}0W^gdYFH_0=c+dHJAMSItWGgjx^kdkju=e?Ljr&SiQT7ZiT|5XBT|(ChPi@ern( zr6Et2wN2Bj{>aU!LBh(>qm{795D1M?JE2W3?(kNa%j;>im|A|L*6|SGk!z$u29psEr7sPq4fr=5$kmoWH3rxk@57f52188TX}rNd6Ck z7B9%JF%Yx53zxQn5e(FwrbdSO2VMz^wyN4<%_Yr#0EHM5(3&wcS0)Udi|QY`FQJ^f z=~@`kree{FCRx7qyhS;xeQU*NU2OsH6uN)Cmu=!Zj4n8?tkN>{gHyHRyCtji>N`2Q zI}+o8v5-l6k==eA-8v^ZYBZQOl_bpj_kT<4P??pKVOiZ3a=~bTM?S(9EfUNH2GKJ* zlpI-QbX9j(n38{$&^_0=0Rt&-JC*@|&<PmEBrNPi^j#ZKvx*I^s;35%bK&WvOCqan6sgL=L)f0jwZPU^9BY%to#aIDIevUc;j#S zt19Q`mR*~s=h^N2V3v-msc9MMLr{JFk(x|}J zfXQfC3)qjZ2XzNV%6uOA`QJAVHVT*jvHyQy z3gkRW#U>pp=WBE+(uMGfy3$CyMST2^eUzo3*px5} zf>_NzReSm}x#6tJF^E^!A~LxycZv1eaNO?^RRex^c%A>fS%MtIh73yW`}b+W?gLhL z5-42Tz)Bth2uPnlQRI%k8ecz8wNL7mB+7nyxTOx4$i2r zvi)%bVKqZkSLA^%Dv&A>ZVvO#ev@(~Q5VwbhQi%por0XJnVJ2*uhGl0p;_)9%SngK zrCAf!X`X7K7VMxJW_y4AgS>L%@*)D~v?`Gc0Hzh8eP7gi@<)J|^_ah(Ji{3s6YT{0 zNu3kC+G2?YlKHtT4H*D%98|?~(Twm8`^PlF8U|6_mz!f=vRu>h&|ccT z`*~>C>lsqo=^uv=D=o53{sHeRf}iDZavNogt+<4dI7xH=z}hq>GeB|RR| zS(J;bBv|%cke5=pi_tsDDMCoFGt0H5} z&j^t#gn2DrlFeP0s&exHKVTeg1A1--jOVXmb4F{F zXNGHIGgnhF3(6*2%qqijVaDsL$(efNkW?g$-k4aZH~d*wi5ZzH%CnB`21`4 ztn^e7egR5DnXI7@10(#Z2;N$W73y3r`2L%*Z@%)cx=*wJ%K+sjJw6?=J#WXRyZz^Z zZ@_+}y`Lfi6EGcq3RQ=X_&^0WziMCzHEGAd+qrzb@?;(5s5JC&H<`DKRnUTN)3bJQ z@Mom+%V*7A#ff39}BY ztM5|7a^Y)ud+3rn;Oe+&8L-THa$g_=aGPMEV!rZqAXA(UDVy2lg539o3wuN&AU+$X zIz3RUA}0ZcB@D{-5BlySRgTw1X;I9v9YO|xecq^j zxB67^s%oI!zFFygKuG2qWJ1f-=H7=-NUiG;npRH&sB^&I zfCI<)F?1NEmn0AXt^Fe^4HKciP8A#hQBd2SXs717TkCec2+tw58~A!LXyiqDfJ^;k z$xrSkz2KDa7ub`@NK2ZVJ5DPc!{j3N?cDN6ZMYqA;3 z$p^nTz`iq#<>69)R=Pio_Gh}M|b`_c?|axdk583VI04?^CZ)vSeh^cCOtZR64e7FB9FP2VREYCWIjj zk{dI9*p%f4@+Xjs!%=rz#4Az>O=kla5s|w4XWWN1k{mZRX$}nLU?0)=`4m2VUZwFE z>CW*u6*}&tejochcP?#m{)F1TFCzIqcj>C>;w$irK*%jeH}&-7sz=%7W4p+>Ao#-vl?;~^TFrP3c`V?v{hVAE zD|`;YuDqz#&kV`*GbBiR@k~?p(AnotVq1Z1l_CFP&PQ>9-WvCPi#&0&zW;uCp*I`P z&!OI+;P!bu;gm70L?pWLxukI`mTQl<dK|Y1_5~Mp-Y2bQtJ)fImF4QrB}4I|ZHdcw!Bxjnt=J=b zwN`JgGqGCepT26wJt*cZRBGtR&40SgaB^;!>FB*F*|>jWJ}hWDazPzVH(djN@Sukv z0+34F5zuU%T^t;prQ)wxeqdC*ANwY~Nf=FQ=>mKVW{Y0(FIzwbVF#NowglLY@bYw= zzTTn1@TC((PLESZD7yoHp%Mkm>#DEJL8X>rMVo?YaBMGTZKKHJ+KX6d{4WKcE z^D>~j`^eCiS%p5%kZ}z*INbM7ArXUBvJz1Nmcmo+QOJz=Oha6(Zv>i}Y6PV=l|0EbUY$t?v{Ce2q0{RZz_M+%_oE*F#$SF;467i{$XR zC@G7uXqKjws+a^O-DDu8zHEq7GSIf8n#fee7a}4O4zv1M;;o1J-J(0~{M{$#;0`qh zmRgD|iAtG2i;IsMlA|z3a=$TVz6brAEFwjOX8Qh`5E8OkUOz0On$4p}s&Mexf%YN! z9|53QYE(-h2L|Y(IoTUqCE30xt9XvmQ0(?GXm-LM5Dy#i7FlD2!oO{EA@0%Zq&Sd( zbJhb0e2Y(7WMQ_QT`nL&cYV2}5o1{A+tL;iH&s`>mb1(MqxVHKbiGapgWGb=Dee%xTL>fi%+wVE0ysD9 zV3gJx^G5wdn?Rl7)fOY;NRzdelxl3N8|oSEeZNi?0Y}HN0LQloZvV1GL|nk5DQoy6 zp-SH(Pkaft*_~dyqzURP+w0o?97!omw8#0i7LXu5``d@UJ%|V3?!!=Gmxcpc{JC(t zhE@x3IxaJuLNCE+gvy;^S{i);|O+JJM>C4VrV|q6QvsHk>gG)u>!!5WN&_3`i)UT?I@2mTb&t867tRIE0fL_427pek7mDG< zMv5Y7oAdP)2BH@a`N3r*gA^YV)x((UW;e}dO23H@(n;-M2+aq3F|$$FfFEqaKL-^7GXUPH334uR8vBy8?zgt8N_qo%jBmFtn78U)8 z84;z6+6MNo6}f$*c%V3m0dshZNVtK_1M#2ws-%Sqh^?nW=y0M!0Fnn)=CSqWln^E^ z!yeLRPc(E$7p*;}1MR`O`p2JQ`WA=~CXcDlPF^hRSX}>o9mjW*7A^j$cI$r=HHrKW zCAxI-U&F-1)mhrtsdO?k1+fs_Np3UY9{usm&e?**=U(f zG}j7%ZA7Gx-ZU7+^<#Pu_N#8-HAcM4t+tAWcWAv6uLK{Tva zmn#tY+SYssar%~&E{C)%yPYP-Dd4P#nscoaZ&s7T+sY zT~-IW%$_`gZf6$<_qLz9d`%R)0RQ)+wh!)HpykUKTTxL`p6SlCBzR&noWLgicK(s~ z{2{YY9(}IP`*`B&3)hbv2#AP~G!8#?NsWD=)l1-yqe|P9 z=gb_1sS_X*PB2<~8uvM{O-sFGk}m`#%9OM|rT3{~2=gIWQE?zF%PSeKW_X#c@UgP4 zV8q;z8WfNScm30%J(Y+->GKViZpuidRx8sB2NmWLvh};;C*zUx{9iGd81Racc^V*h zpL@f-bpgg>`^x6->8{^=PC^{+Bsh@ry|}3JhU9})e`zKPcmP23A|z!}zI==%hM}r$ zv2(MvI5L3v(s7x&Z4Z$sqw#6O_Sm$2XG{fC%P1jvwflsp9MMn+q8-^%;>`OIijHPE z>~cGPMZHxLRcRyz|MXh)ZTIQt9-$d5R=7(Y|0{*$hgxA&BII@M?D5#rEZA6Tcn2z2 ze;$?RF+Osyr2#KB6k`nuu)>wkppDD9U^xkn%A?}#NL>U^pz*tN>ZJEqHwqzQCu$Xv zZ=~BlchlQJMq6pHP|h>g{}fc7B48x$0`eD~UerIr{!_DAR)a+#W5o^&j+w$U@WWvw zrhqAK!^!48Q+R$O{OMCGwZISn%s`#*;xs*FgpWCK-}4^9I29pKL!Ef#aGyC~KdA+w zACG9dvmalO*uOK0^;Hb0XpGu&3X1FNPmpV5r5#D!N0f4&q>u}Hiq6E1y)d`;*(i#< z=B2r)z={GlPe3!!hJyDuttZH%=DHxH0x`TOQQ?-nt|!vnOg(-tLsJyy`6m-IT^YyKos`)ne z*gH}7kuYhBIQW+K!>GNFOj*wqbV%J)S1S{k{gC@!y^|!Ag1kp_%vXsZGQm6El=FW{ zo>gL_mJma;e3cDW02r!G1v33zP**JOZ?0m^X4$=|l1)zRtA=;-<;l3`4K3*s2ZXmN z4EC-iwaa(ww~b^lTR@8&#@9-ybf- zrfhbQg9XIE`MRe~&%9J)kPD>&r%<<(p6rAwqV5~LnGFry=3bo_^=sYLOad#}6Iw`o zJ8>hI0S6Nog=?6EECLy+n81-@(mF`syB5M{rdZ#! z3p9G-0uAQGL0QN04G1LmRC z*owQhyEBKX$DFt^NZef1=y(N{KrwOgF^xmlk~t69G~)H02WW576Z;)+t%vQ+9uYP; z?p%a?ocvv#MNGX}IN;xAoeu$zV){ifw?e`@>Iyl$n!5zbdb>`hAI=%gN{wd7o$jL` z!4UXSzr!U%OWSD=eQjaOT}eHB>L2TCG0n$#pfZWM`gESs)#y?$#84XP!nMG7iRaa` zqAE4jOcC|hBiR%0g~#fJuv`UfCTJ$|4sXqEik+J#H`GW*`6x5?O7_F+yH#5*Zk6mE zm3^~g$(bUa-~+^4@o1i^G%!sd!AmHtsIn0z6DRMk-M(T6YIEU%;PEXsCeJ!x($ia;&C{koZGux+Lt~+wc3Qh9rvT z<&nP{5uYWlC@%LfD?2y5Y^pZe9E#kz@`!y;i1w3{WkV#yRlBd94+(JK1xb6at0pMn z;dHD-$vQxen^WgKzsF44fbWqnfGl9ACvKdT>g3Voh}-~sb!f|?fAXGI)~7by``?q8 zjb{aUr|GN`e$qRu8?ooGoXe`ZG{M#_KpC6o0F2r25peDQJ8Z&xFrjQ1!-io`8UZgq zvkT(_+F?VG1OpfRD=~r+_?)mmc*cIM=CS}O?O%SK1GRm;5tW>g5uM-6=>Pc-XQP0X zOJHC^Qzov>Fkr^a>zLF?JEk3)1GZKDjDr0 zCGt0&Y`w*mL?p&0!VT62baijth5X_@rCj}=13N=+f8C-BdD3oiP-~yPyLxtE@ZyO; zi@rmhHP{PH47=rA7P&&x4z_`k-C-$P@ zKg8wPXQ7BrOQ6buQ)dhqN{`@0zfxv>BXY7rB}(>JQ&M(s?%~nB3y&D9D5CE+?Yxr+ zC0RK1+5(%hvWEP|5pudVg603vLDDHn)iP3*z5lp(0mR53!D&TwE%*0u9cL9bSPKOm zV|;HsQ+xl^!mq;z2wHttldve45Qhh5nd-d*breM38eb-{CQ48)k# z5d5Q$cQmsKBcfaV90EwcGjQPvI;)D&v{A}BnuNMuft?<^p9%ah$l$!UQ!7i-?GE4; zOM_(n7~s;uE~acrh>=iV|4w$9DKgIk3%2p26j(3J>d58IAbniIb4Kh<8UWeZiTnbM zkc}WI95kU*#*OL3WK^#z+Y+fI;g zQh`wHR!m$SFELLuj7R#P5-u+7Exk-W`ZO#f@~ja$P&i>NUg+AhpGAGF63ZGBYB_rQ zR;jC{*$69`Q`@g0U~m1JG@2oElnzT_@T_T;!2Z*R$d*13kE&U%Eqb+u6`%tRL9?&8 zIiV>LSZopW49n1cZSXvO@KPijy{a8W9rVX_eElJv$3ER(4Rsh%E*f(^jx4y|BdXq* zL75Ev4;?Q$8>pKdE-$(wijSA0{Z5g~e8|KhpVuKjPg+%9m9tc6AU~;V#M#>1I}4me+hl#Ow*FR>x(JSi&piH646{l3w^Eu& z)Dh;|*=auqBz1JxTTN2Z%2!P>Ap8yzatUKMOoH5|v2z6|Ya%Kg%d3ZPA3TS4etSiy zy0oMD)X3Hjo9$_Ci&J#T$wOI>>0np(bK)UNJ$Ufa{Q8FdQQ2qr{X}G>D`5TTsO64jt?HOB(tcmcl_E| zIDHD2kC*$$Y5rn}H74UCoN5S-V-ao~20c+c^}$GHlez_-y@FGb#i&IS#uewloEECc zYvS_QlOsGoY<12YK%T{feh*Tlfw>CJ#5rG-l*eyt(Vt#+KkL(=&69dd*xF=kLoIHU zEZ2u--a`{>NugU+K3*g{RQ3W#nBdb;vNRJ{kcaZ~o0;W6stXH-nR|czrxIg5P5^S( zK$T2&wvK0FNzs)Vk&%XV=7619bcM!D@3sL|pYd?L_p%^cuFztWXo#2R7Kz&N1P;~d zi^W8LaRV>NAvJsPOOH-KKu)ZkPfw4(FrD zemwNU;eT}O`y_Q&p>i(MtE96Zi24hq+%|D?ObW}Bae-l@j8`Kaen&1B=NCHOs8lbG zAxOOg*ASxdk+GHgJCRg>%12h6@j0nx7qwccW9`}X6$$HOKRU1uNuHQ?Wh_s5@EBZV z1}T=98}EN_N}P=EDCHKkJ^z`75p-V@W)ST-ZDD0`7yY)Vbc|3LS_cFHeCVIP#4r&X zutwjo6ueOOqhm?MR81qMd3CYo*sVQe{RFWxMZ>D0h>3JwkUHSHfy zQ~oNs3B5>&e@e9Loid@XR*x@uqbDG^<(d$jquXKj!!oui2yzC!7o-j_iRPjn6N-q?V7ly|3?|wnLE@^^JRv^`osUlYX9YUfyVx=OY=CH5v!6|vN&b0V(-}1eNXBst-Omsji~E( zv1xZa*&R@}(e%A6dBcr^_jh5I+^aO{WNq>=BGmE&dI2gu#w++g*06t%qxL|82z3W) ze`(=_^xt|+DF9ni1+sFo%+C+X%QIsmSFDovL?pT>nD*hlXhP zf^Jb9CI@eGMTA^Av&@7q5x)a0H;GNvf+~?k{M8Zwk?;a*I zGVEyba9#d52G2WOuBBr{mt?wq9@thYil_~}j>91jTN6-8M`hS=b`0MeWsG%Oo7Xs}K_1N@aZ+?pLt#kr+-jwLhIVO}K}UJDdI znMRE<^L66>1n6)i4X!-`-sW7`-L_b!J&P0~E$|n1>+R;N8DvA0Vt-PkL=>mMl`$Zt z6>i7IP4F!TE$B`CYj{=H1$#L-baXO1(e#*-d6*30|c4)#BYY+WUe0eM*w&aS_|Fx<`>T z7WZdDKm|9Lo0(+NuGX_|8Cr1E=XU^UV>y(ZdEB+axvCsPOs`Xdi*&HxyV z-BakU7LQTbua4np5CTJ`Ls&7|(X5$^(T2pFw2pLY0WNW*@00#XP?4mIx@UsKx+eDa zjMsAk;L1uoi|cv_o1NzKw)Azwn=0_^dNWA6d8Q(7ZU*_z7#^_|KZ)}*2+Du*c&THE zKdD5eDBPKK{Bx$XIti{PkM+LmN`#eIuwCa5l{>qSm3yKuRcr&y=3tgVS5I@lK{KS} z+=QYyJ6wRKyc73kFgUMNZ;r>dI0?{_D`~Hic*70PJ|8)?AT##%caFEXhhjHC+j0q? zIpEN6Y5_GuHCiHgWTEhc!dxZjo!2oc%_89lFFM_rSj=g-Uw68p`Lk){iMS4j3;aZk zu|#Mht#AH-N7V~snzLC-SO}%{M=5wra)7Kia1yh3DsZdM7RHsov07JJ0$q^wNN8+- zS|GNuAFa%eJz5~Ie{X$Yc1jW)kXOD@bnK)UUD`_?kHvIQ<7CocZn&CKCOqv%k(B}> zl3ju62u#`>QKaN{W!T|rg}nbHpC?V=Uz*d?A_Ch5m$ByUp)Yi~@F{~^exB3xFhq@# zXKn(NAg+0ytK!f!iY6RuC>wR^z89XZ#8;{Vu8)NOKBfivDnJE-aLmojJcId>_-LaB zn>N`9>Tdi%84X>i_+d0tG(**Y&t52vx67Y@Mc5+bRlz`Ew|e#u*swB(SpcaZL)F;emAl)F9RxzsoGf83s=Y7LO zokW|PEiskrx;PShQ3#yAmzKFk>%Bp1q1W$P4Y$Nc{xQlR++e+DP*Heg~Pn>yVxKa;gU92=dbLEaZT^gzixzfL2uNcp7@CEJ>*hg>+v!$Fe(b_5Q}gr zIAW+}L=2Zx>=kLOse;^!v0etL!pMa%VV6{K<`J;=Mb_#4^G_g6(n-c^N1$v$hqj7_r?wDRqCsu3-Ty~iy&-9BSF;8^pBEP~o5_|q zTbPEnTBxmKpW+RR4oYA<<#4|Sf-uxBwy;ZYdl};=Zhz( z9O15q1v-aO@N*)tq#<3&c*n1)p1};V4v00si%W`IOT<+x)o}oTsn|30Y&U^Rh(m5=jY&R+s=Lmn|Tp=W0j+V_c?q zN8150FR0D}b73(2^d z&(q`jad^S_6rtEJD#w>_zNuD z`aD-Rb1zb)b%3-qGY#2ID}R6Y;I!6}rNaQ%Yl+`tzAz&9KDy3IDE$%} z=GO81=5#@xix$t7PmiIV-9Ig(K)faNY61n!JO#BJC8iY(MVur7dzfi@&`|k5^(w+B zGzL{-*D+v8%nhnH$;>E|8&@zY1jb%;_#^d3WAft>8>YVnmNz`o9k91OFosm>6wku zR39E}koFnzQ`meBgR^P^F+3A|QcQIVe0I2%4|5V%gXZ$1495d&jqIw*nYmOrgveu2 z_e1yqq~tkCWRK1y&JS@(m=gny=XS$e&J7$+CK7p4PAvHDs}18%yv&&h#WiA_slwm6 z0wLg{qAg-X*k$P&=dieAch{W0RfowyW_xH(RGvWakjUo7kngTsxXi*nVEc#{_zSQL zu|@*?xIzkdWC@Z)Hl&|3Qi56Hp=rh}6EOnPR)Y3O&oI<=zM}jPfs^E`5})yTHz;)N z)a3lAUd^mx9rn0Eta~188~G;nFF4{DhOx}a#09SM6dwO@c{ee(Ew_6$xcS^7i&_<9 zfqZDlJpSCtbvJ>m&}#6@`hi6g=+r1A=FGf6FBOV6#_3q-@xYZ62ZYu6_1cze=lnvliH*0}u{`yZZy;|Yxcce@VBMpL{S!i|cU*9_skOaMnWv107HNp#R-a?I1bBKtRYG#$Jb2H)m| zK8vPU5oZPqk6sTN+_TX&<2}fh+~kA@h#0@ZUr9Do!9StSoqb@OE^oJ9J87T^b4SQk zM(g~~lt^tbEK?b)Ywos7QnHsvS)gF)AqPSpA1T$MlJ_3TZdY2SxilgPsMnu5A;LBz z;S-%22i*4wlHAEg(6dLgwfaooEOc~goA;NsQcN&~5uUc>Xj?|*Kg#9YPC7d=fPxgjFAYb)!`d>xJ~+&@Ox zS-GXF!GhgZd_OAghh6OY$@ISx&{k*O@>-NZzp81n&gdKr~l@(-~o>yFpHKR zUMaT52ePj_^-uQjBY@e+*G@thUeR~jSty&;wE6gV{FKCn7#wi*ZHq=M<#Gi0QcG;| zcsH{~RzV)%$|-g4jOl-t5s@*!8B*f4c@fGq`W%I*|2`AUf8Bcay_-~d{k3hU_LRoa zNm2H{81$5~wsiNT=0jpG*2^T$8~7NAhp^?eDh$Qyzbv1@C!F-;Sln=;I`fVfu;Kg- zRfCjw2P6POK)t`KgT$IH?=@@_fEL2}q6n=8QyHm{)BMWF`stw9;tC)Q&P`C5ubZrr z=Gyg6d4P6&FOGFPLpWokPVD>qK1r8m4$FtY6brt+IGc9$kp6>!$K_l`1dbt;6Oa^` z1ZT>aICJz0BPaBwlSU|Cu}w6?ja_7>A;;tGbyghJeJAdf)BTV(k&U4<`cCw^Ai$c(-Kh)076vm0i5re@!}9U zJCs25g+xhF7BWGO6wFq9Fw0R4B?>6=aooWPH91R01iVJoepqBDqBCiY_Z;|pnyWSf}67$O>T5V>tv>=!qXggcI2So=TH-Bl;bk0+zT$ zUSa$;UWnCQ4!qj~l(qt%A|{m%zg8$g0=>u}s~q$}i5DzWy53S6^Ngp-6DKDDiBVn| zgenz(S>|4ein<&{-a0BjrU82NOz!ta4HJz1ZgrCj=n)aB6`!m<#)8(gS-0$|#C7k{JiHxRySS z{M(h_ow`YV7M{AEM%*XdmjiQ=!-Uwjl83snK`7OlOcD-gZtx$Mv8UBW^b((5SBu&> z>nOur1R<$>dI~Is;8iZ&7_qH960#!-O5_b7QV~d_gU&~13`c~Tg4UzCmM+$4n33Ws zkp-a;gW)1*6-i`<1kjU7$#vGYHB_4i41}6yzA_nlO>{qnxmm0aPk*?#6|COMha!GZ zy_v0Esq(wQM?K#Ib7bL+B_5`ICEzUQy3z8ySKs`z359hb8FoUz5V$) z?|on>kr>Ei4v(;z{sGxY!Xrh-4a^pZg45RRyj-+&TaRDoO*|{7QaBA};*ne^8I&E} z4KI1>kTxRRq?l;GLGT zBe}1Cr}+~l)#HjSelUF!98$e#oa)@!N^rOM$q-~l8R_8_WpeC(`Tn^tI!f zb?#!YLKHnQJMa@)aKkKAAy;>&**|yB2G13WWmA!t+4C>0We5XXxUn1=K*8>$u*&J| zKULidsjLvLhdsixT}6Fa28l-68+Xgw2efCg8di>168D2c;YS{27tkY5?W*5spk#W= zbxk5MMuZYHi@edbM2&Q)$77$W8H%A=cApo&JK^w%86cOhhp z`OX+FS6~1L5nOY8kL{8fQL$0y5TSKS;KrK#yH_&-+!;Ih0$6TBGgwAQ_{It7AdjLv zb2sEom;fGjjA`pB5Bl=7GCg$?G@hrCF>|yUC*jXI>|w;bryr4uWHV=@J1jxvHkzlT*ORe$V%sUKcN6oO-IQ>aq=uvvTj_DUo~(NW z^H#Ml_Q~_BVkT#hfaI&c`sq3l?U~`W93ucBR+-g5El5^JY3rj#eHm+d7wbF!JgD6@0p+p^;=T(0B6A7tu7AC#&Jn@M zMj3jIrig1PCeI2__;~C%w55dhufs+?vsd(aYh{wPvHIUe*VOZ(*NcfG#1@<5eVZw8)aSr+?W zD`c>r1%o112?ogd1bs$-s=fiMb? zUWs=wuY|mg=xTe*4uNhjb1qK`f}*AerUPrJ^FVkfQ`&=9ga1;Ti0K5OXC3&j!^iRd z5jT^ZTg~OVB{P@8=~%l_W-}XYhx&M%U>u_ogs>%jv-QRiFg`y^MgSG8CurE(#(rQg2+! zJCydZlzFO)=>6uWR8kOO0!huhWEi|bbCMnRLzKudyFf;eKr76G_V;+E@omIgb#_XX z>MY8^@m)^vTv-J^ab)JT$L|U~0M6mKWwE!xJxawV z!m5L9deISV@0s@BqdT_c0REsu^V|I!mcSB!X~VDX+VQa^Qz#>zV3891EDl8H zUihOXKqvy)t|1uN8&5z%vaD-qsi0_xxf@WswxS*=14ZkE5#L7SbiNNnt_t6#S+SjNar)00p)JEt%`&ccYK%#TLY=UttZ@txr|j` zCnod{1-oWah3Z}>9a~?td75A$QQf&FOunbe6aZw6MNi@4jd(bNtP=GNYK|*f1k>&y z95K^MM&-;}GhECFrbZ?X#4;H`qXCQR`o1L_#!}!m!~&H;F)a@k_@`UZZGRn(9mQ&RFNmAx5@N3K=5*rR zJgmSeM7+)oCDkiKIRsm5#an3GUrQLpV%_5Iq@8>xc~~KeH%RKB@R$$i5z=(wNuB{U zXcUU%|9FN>>~l)=2?2%{Nv?XdaqWq@JV$D3)h=!E<88g1g^UF4z&LvURCVy>9=OU) z^05#A?SJWfydxZV>mL*mi4e{i-Jx(#IxdaLF=|(FcE9Ztk0Nnq78=8Th1)_g@0G81 z@&NOP#$lxlna9K|@$rhpgC7D!gBs(di02^{QSK@7Ag~$e8mv#145S%;_`%A3Wfq|z z=^^Rb8MK)xwGUFOYIx_a5Y6EgUY*p#*u|JB>N2S`zg#^BHr%r^|@TWsL`>$5mvBfrzOX0KF!_X?TXTD zw;(u~Hs9R}rvf7R_j`ySvVlxhv3Y|!?xY=HQ~E8Lgx`s)p{`iNiGis@^T`2Zx5L8Kz+Gcj0F zabxsHMPjX#WM%sD24g4`<1bL#dLQKkGks(P-^}lo**#-!USH(HvGSsRU{41sxL!?mIf=$9$DEazv|=SoKdrABA_AHl#4 z(fe)5douDKxi`_6C;(?@wg)zDxC<-?n4#;ii%gWW3o~vvTV0)zeI^|_PiQMxiU$1w zcdLy*jx!wj+63sNzxpI8EmP?=Fn?EsA_KcFw_V4rfqa=57sWEQg>34x_%m{}2ji5q zz3Sq6a7GH5&U|OWl;4SH`h^`Yxfu;NzwPHTD-N#HcDLG?GI0|RvR>Cx`Pw1skzl51$+NeCe z-r72de<52V3R&6{t5`sdt;u-I&W6@&b!)Oo?LqH7ar-w9^HM_F&Y(WZ8G{(Vtuma( zNvL)HE=+uisJNW>MIb0a?;~n^E^#wGD{NOBqW6PQ@D=VFp#YTP5$}<-+&*N>9{%~= zxhQ-?t!ub=6$`K=Wu%@%$c(0b*CaX6AQOnef|02XrmJZT^G50pJfO-~t7Y@A5Wyi3 z`Yx>K>K|c29nbo?=^%}gXfrck8w;Xik&;rZ>49b)H;k`3dlKNPJ-f?-V-ybOk{L$+ zn-%p_>4#jNav%WeN4f9D#c_rkRCYR_YMWWoe#gpbHLo!a^1O7H@i$3ZG4}c+*l%UM zKOKw_2uStR2is$m30u_@p2v>oS>BT#ATkoc=%=4_*gmNbd zb#}`0&}4)vkuc%cFp#Jrz6v1rdpJi0V$sj_(Bxp!=gR>JZ{sozIL~xEb3>mnFBETQ zr=~UcSNI^US_a>*v z2#0C0W;^9{u4q+s)_M0Gprgq)1+|9GQ5X4v!iRvz_(9CsPYcebASjjl)l&DQT6AZa zRtUa@sPM5)Ou`+IaL-{H(R31>%@vw5N z?zeY^MZf{H7~_a!chO|&K80@$L*~p&EYD+=_f!W$Ohh>M+UQZb*kN%nFv!fTQEcpV z0?d8`FnD@W;+YIkJW4|tWDNY#Ny+_5A8MM6rUYh9LyiL%FD>|=ndFs$RpSwCsfn1H z#F*Ai_qJ1F@lU8LTtH|CM2}$~lNxp6x43!snxdDmaA8Wu=&wjH?VVqh%SWPTI(Q1_ zPvMI)>h(Xlj0+w+GiAI17;qhTW!faK4Dr$kukUIzl*x#kx?fR1C!h~-rW8u@3xR*$xrD9ll|e(Uei!M3xLyAK zvCI*AAJo3(>k53R5?8VP^S`ZN+RB}d)A(;IUa?`T$FVB37(b*^(=^d`E7ZdbUL{&p z^rrv!^$35pznPa03nGiyz(1qLABHhKf(X^bwj&z#Eoi!?K~P+%qFg&rdr_ogj>KAC zz_7n=vRps2U*dV^A{Av*75|b?A(MinCOch8uVM1v(X5@7w)py#Mq7!t*kkQs*ezHn zSHIYz-#mtXwB1Ib)FS};DDM=eG_z31{5=en(6_g(hHvQceR=zXyQ#Y4F~`jb>#k59Mht0Qt~kL4=T0q zH6l^c>+hAE4&Q{}pUQ3Dc+IW zxx0Q1BXiV=q`Jp@5|ruIvMN>0$VA7{)iRVj+)hMIl<1l-M#n#;hU>}!`LvQ}1WR{QL$59u z@ZD5(enNj!Tl{EqZbtP8WE8e%zY=m&^qEgCcxN(Yz3JCi%h4ii$zT0Mre7oht7H}% zBOf{I30ihyPU7YxaTyw0b>^lw5QLe%SqaT)x-e3Te6lO-cxLiLwD|J)t<`*}9TY4l zDF2iP$*zIYt(9O;@95l+E31pY9J*sFw}Xy()jLri$G3wQD3v@g>fe;}R@e1rJf*@O zpLG+rKMe6lCCC0TijPIdwdPB zr1*ONKkB|}HUhg=Kb^FXE%h&Rl+X+1^2KOv=d1tzt+rgk@|!Zlo9+aUdk zofw2;=UVB+#tz((M8HtW=iW67MNz)+td@wMq!@KJqi8Wcuv$xY-T{PGg{1#DIui*I zUTu3>)Dl^7c@|HM&MQ2V(xbAN&S~d@0FN0G<<;@`lF`})=Rt`?f?mT|*nN-S!tP}- zo*zTYXd(XlbkkKwL-NYWsgC4CSm)q4gr5a~u3J~JyZMqsa$6bCW71A!RXW^;A0(r` zM|$zK{_?QqDb3M}Wafn*V2^o*)}dmZrkR~V&4?12o}0=K88O>hE{*`R!#?S2MLt8j?;0h}#XDq2ZJ*?uYo3t%~{6dUpr`7mxn50ZJZ7jbtXJ_{Ohs#$xlA`I_Oo8?ZKB9s3#$_-t&GMhDnk01 z-Uiv)A$0GP)r;XoLI7B$bp6JwV#m!xD9fr{rVrjoS(XWom(9UOXS z=F>@fW!9L7p#Z&YzKga<%Kvm+hA?`{aB9F4ln@I2`R^44ABxU`MPy$yr|K(E2kJTx)7tXc zWk^Aia>SaL``SiR+$|a(_t3|zxbwHc45zOY5sbNV{HNt>PSoX4!k9w+$QcDfuUg5b zElP5Py#9gTfw!=Wp4D?^+HJbt^Qb1f$QqHhi2?T%D3;oOh{=jkM)L-&z?ECgRtjq1 zenRRm6B_5yhSS>dAR6%DxblvoN)lZOD3{W&_Vy*2$9Z*7In4Ds*$@jM&i%AUo73V zz!}vODj=_+i72!X4nxX*$|$5G;k+XA$2`%D37UYq|NCvqE$rN|euQhfh0J7DYCuR& z5=;pi>KGE3`w|iKR}oc&EQJBr7q^w2G`Z~NS5+&{{X?vC-`OIuV^nji;ZWa?OeW{ArqxjsVwjzXI83ojI zU;k~o-|u%rA?tN4R;U<3TY0{~RPGkYUd(JL{^_UySxfTYJGCky0Y?PhD!5lli)1G` ze$^(Z7u1WDzTxJe1F*GwfoW3^{QGL94FiwMpJixer(IEi!1b()Ie{)Naoz&cicsV` zjQeS`gF|{QsF36F%LKlo7aQk1aD%3_$hwx9>}XCrwx-Crc0U6+uGkv9{m!Mkq43Oz z$mwM%)0;hjP<}LLN$}hiACcUNTLbiL_)ycqSh?Tak?DAH+IaTNbkDj(u-VT?V$}GY zd#x$8ohby>Yl@)=q}M5*L>X3y)Q6#v81{Hbr!wMqdqHp6AN(Z7k|B0c+rk-0%(+WT zA{|XQEP@~+ouVAP^@`Jbrti~)2>yAkb^wf#C8=(*0%t_6oGI{O>mhmRb3LQNek)&r zTaR=wvg~G=W1U`oXgopE2Sr~yTr!Zu^gUznM{L@DM0kRV9Bzu%S>2p{)& z{1~CRXqOQM3UByU7qo_j>2~aI$xQN9sl_=%G!Hd6BKlDL2GKYb5R|NXtwD;Ee|rai zxbz!P;Eje6@4M}9G29<5u`neP0auI?(ra83Mvg>>ureeV8tY1=vl$^yNPc=!b7?1w z@a?ffJgQYH{`PjVDd9+~;khy>Pz;HC?T(<_*C-BDR znuqH)t;QB_@ozHl*+^ZC|6M@aQCJ@WGaCA4%C4SGhbW@`v~V@s;cwMN-OkP7ObX@J z9M%ECAV9x-8vysA|3jLM`9#n;V@nz>|H$6)HxR8GHl;NPNR(Xd=v*sT+6}%HoV6FV zLAEc^ zWHlT!pxLNECb4O{U4PNt^zpBA>CI7pJ+fIG)14nL(l z705)hhdRG1c=I-xvt1WK$A@4#z|;6a?TS@=Ic6*;h|~q_SdEZ;Lu`|a1og~0z}6ksq(9Wvpr;*FCXvNVdnROz+)%QX*WrF>qQ-yyzTeN9GX(|C=-jHj zDOdGR0WbP~)Dc*je41h1R*Dz#)X#X&iDSM?r zIS+^$qMqw3np=@^p|n*iOz~^k@vGf3-FPN{kHsWQMr*nJ^v_|_lJ%habMzyxg)#*$ z;mvM=3QCk;Pi81FNJ_pPivoDATWYGHNP|_1P7-(GeE`4_^BuBJSL-i*j+`62>Z4Kr z5(Xx+iD+<*nB+JgtunrD;$uQvuRy6J#?rnl-iw8jTla5E)*nbd=%N1Cnh(MF6(J=_ z9$$02W_zqgKf<=6ZMNPL@ZfWitzf!&m>#a#5WNOs0B5qn<~@|fXKZip@KK)fL6h-szCrw5=Cr* z=iFCVK_!X^|4Ba%HnxR4f8((|HhO`N<-eWW)I z=gXcchy(npFt`!2B0@pD7#~VFYs}{I)WPd0E#%r_Hg>_;Ti3<^`>0X4$%2BOBwJFW z98&5dO#bVfU0P3L!eNImR-l~t7;T|cSltJVyOkXrpKsI0aTgV=)k}GU#-Uz){$=Z{ z@sv&3-Bn3zV&xCDVjC%J%k!$bgc_^KOHjELr0L-rwe=Kcy4xGiSH>|Rl5n(q;u1|` zG)Jkw0%U!gNE@c|GeJFes-z<(KWVT4#)S9r<|-T*o_8l4oUWh2b?%mHzXU*_`2x>O z*H7h^Q$*{QiZm~mvT>Zjh2;)aXaT)qkF!NshN|pGB}`tQQ4?V#@2#18l{M)&JAG{;%elkAG{>Ep3ivG2xlK55Q% zG3Fs!$I)D^_)HERl4DLFVSI!F5#xfq7Y3|7&8|$dt}WY68oN+YNnQOnHgyIWSOA0> z^gh-0%5h+P%u@MhKhWg!-t8ZhJI%WTkZ$nHa6zfGAJ{7SJ4hkjc=ONN_k8bvk|b9v zywIsNZc0E!9{NmVDL6A)rLY_x{+`>xHjl`i$l%nG7`wg;68PjV#vZuE)zeoLY3+Bqag3*SVZrz)c0 z60}eMfUs@4ly+{P4{G%Lf%8n`wa55INr8ib)c}^ZOo*yy&OEFO7x&|+_VH#A$^6Rr zspo_L1C3^qZXFlz)0<$BN@z3j?0YVi)hYnfbKGWamT<{8tx@9^_X4Vua9}Jh*4BBO z1Z-iJYSYf@WZKC0G@~Sp3}>esqZT6*c*`&oC`Ca>WnYgny*$BINcqc6H$`N^Mw^%D zYgR+Fj<0pH=Kv7SkE)=3^RW8uf3n*}xloHH0y_v+m-jyxRSb*aIe+}Bgvd*eS9|u7 zZ26NQ?Pxss`vGuEP)1O*m%jBCSi`B%XYI=euP%;Utc)Or>;BD`#mpb%!@nxir^Q@0 z<-bI4@0}~zMEPmcMtP0<4St*+my295_SQtzx6_bh%|@$F%}zm1C$;NS&+7~vH4QcwK8;pIc#c`P|BXUOi0rh@W5d%P$3ivGipGxyZ4h}xG0L? zqk{)_-7`G+76he8&pKnD>rw zMdj4TkP56iCEb26wW{&%bx7EGmv|$_oOn#keJy9N3~m;e|Ay z2LMfGBDYb!YAPW-D=eNIfq?HFA!D~hjNZ1Cs8}(TUlCbG(OdPHO@;H_7yHr45t0&T zdg|`!9l#!~9Tdmi>}cJ-yw&8@L(6^1<$qKI{s*zl`lyhw>3f#)VyTmLX=h$Puvyab zYHwjU;xe@e1QjM1RzFDY>w;yaEvDR)lrFnV-!{=_L}x%J&M2b&;wjspjjL?sH%B*G z4wZK(1i#?bajDz@{c2IK%^E9rKx3l-#C?<)tfJyV1^zTYD#LD5hpsxPDf4@Gmx(Sf ztsrPfdm>6IhZc7+UK3b2{}KPLUy4-^S1QOweu(fH;6qG8cY%Yz2uvIkn=v6VI}S|H zdp(ETwrI%@;((7%ez3YdIFY2TBo)^@l14mMShMM-Cn2ZM`7JU}AUp#{9(9#0($+F| z1xP+yw&xrI$RMJ>Q#3P=d@lUsx@fx?K875kImH~*5Dm5nKTpoi>EyuZ?L$QLe!p;5 z>g08S`Lg~uQZV9qwqq<6MZ|nX9oemMgx78R@89gEYU*2Um%x5iyb2Xo#9vGvuAkR~ z(2FecPAq=@+M1Epn$N!(f1TrnG67uzXEEh*h650Ax`CfO-{ zbS-W+{r)BPN?H4!`t1QT{OqD9tSZJ~#0f$-t;3f96=tDkY)E6WffZ?FD(Z=E)n}>| z4#TU3Kc8REsNkH3QUdZ_q4E?#>mk2~(ZkLm85&%B_WN_Ocy|vITQ1`Vjql1{!c%08 zidJ`u0}aHuo=)K?FD9->m(rez2_Ap!1PWc{EO=+`stkr0KEfEfZDb7Pc>~KUkHd+U#oGrN-PX+N2heUl%Yrn`2R%t zXfe6tO2)f*0VS8DMW+|F1uKY&uk*d|jxPI9!1?-1Co++tiXw8o-Y8H5tJ$t;@LWJJ z@JYC18%-MpR>G2s%Uzs*UNsLQHS<<#HVv3j*T!q{kWKtjaUUscl!G|1c3*1!n04^X zNTMXSlaid?sf=HVlfwvCqg2ZgG8{#{xV^Pa1EfvK`>KDY&g|De3=|UY&r7TL0*D5R z^J+S(Uv?x;&-UiUk_zhPzDfg)j)=FSvGAAS!@kRWM0b$K45Xss>)kM*y-XgtwAXSri+ z55_c=;FOU`EQj(1krK2z-(F?|82yQHcW-|-7>^-D8b=IVGZvT#Oqom{<@S$F` zW8=@vIra@cTRH>bJ$Bxpi#;7wIay$s#+DwpOM5LCzgoxe*Di`jnPP>a;YRN#cfcd@ z1C#o|NQn$_SHRx~UfXkZX$F@ox_&HT#F(FE-=jn=vk4?&I6eO_i7Iu?zIM*;&Yyy_ z%e={U)5J@pF;?EYswl9c1`qvIG1QkGS$LU@pw{7DomD+*?BLi;Y9IK^r-mKP7AQ8J zf`kW-t12*xYL|ZRelBVf>5Bv5h<~5`b$VH!`44CH4EHXq4&j%wp)Ripk{m4cB?3}- z_Bo4!JpkryO8Bnab#W!Le!fo)ex-Z-0Uz;6pP;W2SUz*ize6393hl&|vL+Owd}??W zetYVeu8puP&Sqo3_OxoL*~@x;g_`{j$PPSWG%U1Mm~CEddA%(R*FXhVBD455oJ00b zAec#SJ!<rIA`4Dz-HFmwzf_cw%{# zqF0VrWrj~L<=`*!t3Pq+pRk_Xom4rQ$sE5>7)5EDvE4T|)<%GE>UHY=Ww4K>ZAGa> zgcDJ6!I4&C7?r_ybKj*NK?Hak3R6bHn4tL&o&>26k7Z3#xAGX z)Yj`P)!~l&o-j*iA=EUhG5)q$4?~=!2kEO9_xY4c^E{H4y1%*ge#(j`f{G?>lSc?h z)d(z;j6GbaN7uJqs(bX=PC&a@tx$6!plHr#HZ05V;K{o1MMu_=Y$RSQvkHCJ)G1L&bl znW%3tn6N>KFv#;uJEMoR*}x1$fv1x(Zuo4SYOAIpotAQzxOsn{M-eTzHuV;euBb8H zTFLO^0{EvCx(jtp<3PqjV-ew>Bm@ApSsOy((bO`00`IFPv3J<`9=%Jsm$eD1NznqC zhlk#T_&;nUWe+&S+v*|Q&9jNMkRkoJIm2Qq7dFk=X5Zbs4u3OB4mUgDwusA!8p&t* zCV;EgjO}lXMNmcd^U7j(G-6-Jzk}B`9nbcHn&>>3;I!=v7MKQ^dAM9Bg(oOK)yJUb zjfFod7NjFv*S)!d!+8XSQHgpvl6bSYn2-I2EpIRM9VcZT_NJ274ciMpeRU%<+^HrC zw49qkxwNVi1EurXHnmjgcb^mtsg1L!d+K4+6+ET6rm!qSY90{4og|jjS72Ch2mu+}r*OlWRq@t#6gM z$ov3>fUYpxnFO!B%5YLAsj5)*(oYlImrKPcn5_L!)8FlHl?!sgv^#LYeu~f;%Eq3B8yBUhTViR$Nr~|QT2D98I zLr40&C=CBu&z}Oa+a~y>JE~mstW14{@ta}58{v>O{xKPyuA>cZDz50S^fD=>{#$YK zNGl-;dGq~g&{J!swVL^8(s!C-k3X-e=A;?4AES+I96DD}pA-P1!A(o2>+R=o*U(}z zdQB8OZviK6yEk6=_j7i-R$N*VU?SFSsB93HNWNw|H_vBArcFilRu{y|22ytw2PUd-MfK~OR?-<4dzg?L z{v{NoHgJka+*OL?Ye<@i>`sdQlSa%0qZ?IbKmbV2^NE*TnsEXRZvKFh_z)0*lnQ2( zq?C1D(%&!kNPTKTKooPFG|#dC2hofJ_BFw0$W81@Q;jG8_fLdK%Y6vfjASr zZ0Se_|DAOa^5hI!8^Pdj1|DGCxQa0~*W7M$IR*IqY`A%|)lFsO;+2^GUj#lW1{bXD zUa61&vcbbt83xLw_6FY|cev!ZsYTZ5N0upuAGn2341RIYC{5$>0ZT1@Lt6uz>;y^Q zEU({a8E{<&WxPoyC8-{Wm8;FLku1<5*mVdW8a@(GBLlk5IxKtW*DH8jk+*fColM(o zj1K0}ylwer3B>fXYv4NbvtnQPByy9ClzoG&^~l<^+kD$k>he!UD9)(Dx)7Io`_u7% z4m#`E~6n!_@nyR$0raa@#@*XF=Eb|nYQv1{d}8~gWYS^cZs_iHunVX3*eNcw7E zgrZ6|=lD+`r7ZpnJ6#d@BnEP6^u^tXXz9%DFzldL^;La&<#lu}5pOdKlc8!^Cpd}p z)NOXFDkc2RtK1txI6Wp#stl*Lz&6d~7Q5v40}rr-Vfy5D0Q+B6aPSBh0Q!t7eX(Dy zXp>ZksWMbTSD$axZe2z}c(9eTY$ucGXnWfjsRy!TmyEa^JWS^MWx7`VNmpje*y!z9 zx(w*m5RBG8r=+3k(~~H_^yI%QAy;9p{+kI~awc0!=OWz6B-?dvucD%t+BcL`p9qQj zK^s&ttEo(1LM~+nwsOb`&sGHm*K{EI3N6XKSj~#}zM5ge3N^24<)CK0rF(QOaRLly z3XXUZ4bgV*=oEs(=v+rN}-k^h2K%E{e*!*HB zMCC(pu3Avw4rt`T{DOw#5@3+5rYQToDq;cOhV%-*sl+X=^fs@mo{!PL_5)Tb`M$>r z)%5tEvwqv(yu4YT9TQ7>-{gSAvg`Ol=b7wtthy zbU@JPp}#`GS2X8HajM-XHTaUM;>& z6lQ^oN&t9;?k7BpfaPuQ@(JT{!zkl+?xPQ<5I8KSkTJ%p{uTMTX%VzzFO|PS0`1uu zlb8+MR6HSk4#Ar@Wf$^j&aXah^cE_m5-bSzW7$LHA