From 3a7878205e75bcf87eece21714766898e26f4cf1 Mon Sep 17 00:00:00 2001 From: FeiXu Date: Tue, 28 Mar 2023 20:53:54 +0800 Subject: [PATCH] QEMU update to viersion 6.2.0-61(master) -bugfix: fix qmp command migrate-set-parameters -some bugfixs about ARM hot-plugged CPUs -hw/core/machine:Fix the missing consideration of cluster-id -test/tcg:Fix target-specific Makefile variable path for user-mode -tests:add (riscv virt) machine mapping to testenv -Make a litte improvement in curl and hw/riscv -qemu support for loongarch -hw/pvrdma: Protect against buggy or malious guest driver -hw/audio/intel-hda:fix stream reset -dsoundaudio:fix crackling audio recordings -add notify-vm-exit support for i386 -blok-backend: prevent dangling BDS pointers across aio_poll() -net:Fix uninitialized data usage -net/eth:Don't consider ESP to be an IPv6 option header -hw/net/vmxnet3:Log guest-triggerable errors using LOG_GUEST_ERROR -spec: Add multiboot_dma.bin Signed-off-by: FeiXu --- Add-PowerManager-support.patch | 758 + Add-RTC-support.patch | 402 + Add-bios.patch | 28 + Add-command-line.patch | 104 + Add-compile-script.patch | 255 + Add-disas-gdb.patch | 2882 +++ Add-linux-headers-and-linux-user.patch | 1999 ++ Add-loongarch-machine.patch | 6181 ++++++ Add-target-loongarch64.patch | 15466 ++++++++++++++++ Add-tcg.patch | 3009 +++ BinDir.tar.gz | Bin 1602438 -> 2434612 bytes ...-timing-of-executing-cpu_synchronize.patch | 52 + ...-timing-of-pause-all-vcpus-for-hot-p.patch | 58 + ...event-dangling-BDS-pointers-across-a.patch | 124 + curl-Fix-error-path-in-curl_open.patch | 48 + ...audio-fix-crackling-audio-recordings.patch | 62 + fix-qmp-command-migrate-set-parameters.patch | 31 + ..._status-hook-implementation-for-acpi.patch | 60 + ...rt-acpi-ged-to-report-CPU-s-OST-info.patch | 28 + hw-audio-intel-hda-fix-stream-reset.patch | 47 + ...Fix-the-missing-consideration-of-clu.patch | 85 + ...og-guest-triggerable-errors-using-LO.patch | 64 + hw-pci-Fix-a-typo.patch | 32 + ...ci-Trace-IRQ-routing-on-PCI-topology.patch | 65 + ...t-against-buggy-or-malicious-guest-d.patch | 42 + ...-virt-Simplify-virt_-get-set-_aclint.patch | 39 + i386-add-notify-VM-exit-support.patch | 270 + ...kvm_-get-put-_vcpu_events-to-support.patch | 156 + ...rget-specific-accelerator-properties.patch | 129 + kvm-expose-struct-KVMState.patch | 218 + ...ers-include-missing-changes-from-6.0.patch | 80 + net-Fix-uninitialized-data-usage.patch | 92 + ...nsider-ESP-to-be-an-IPv6-option-head.patch | 60 + qemu.spec | 109 +- ...iscv-virt-machine-mapping-to-testenv.patch | 39 + ...rget-specific-Makefile-variables-pat.patch | 40 + 36 files changed, 33108 insertions(+), 6 deletions(-) create mode 100644 Add-PowerManager-support.patch create mode 100644 Add-RTC-support.patch create mode 100644 Add-bios.patch create mode 100644 Add-command-line.patch create mode 100644 Add-compile-script.patch create mode 100644 Add-disas-gdb.patch create mode 100644 Add-linux-headers-and-linux-user.patch create mode 100644 Add-loongarch-machine.patch create mode 100644 Add-target-loongarch64.patch create mode 100644 Add-tcg.patch create mode 100644 arm-virt-Correct-timing-of-executing-cpu_synchronize.patch create mode 100644 arm-virt-Correct-timing-of-pause-all-vcpus-for-hot-p.patch create mode 100644 block-backend-prevent-dangling-BDS-pointers-across-a.patch create mode 100644 curl-Fix-error-path-in-curl_open.patch create mode 100644 dsoundaudio-fix-crackling-audio-recordings.patch create mode 100644 fix-qmp-command-migrate-set-parameters.patch create mode 100644 hw-acpi-Add-ospm_status-hook-implementation-for-acpi.patch create mode 100644 hw-acpi-Support-acpi-ged-to-report-CPU-s-OST-info.patch create mode 100644 hw-audio-intel-hda-fix-stream-reset.patch create mode 100644 hw-core-machine-Fix-the-missing-consideration-of-clu.patch create mode 100644 hw-net-vmxnet3-Log-guest-triggerable-errors-using-LO.patch create mode 100644 hw-pci-Fix-a-typo.patch create mode 100644 hw-pci-Trace-IRQ-routing-on-PCI-topology.patch create mode 100644 hw-pvrdma-Protect-against-buggy-or-malicious-guest-d.patch create mode 100644 hw-riscv-virt-Simplify-virt_-get-set-_aclint.patch create mode 100644 i386-add-notify-VM-exit-support.patch create mode 100644 i386-kvm-extend-kvm_-get-put-_vcpu_events-to-support.patch create mode 100644 kvm-allow-target-specific-accelerator-properties.patch create mode 100644 kvm-expose-struct-KVMState.patch create mode 100644 linux-headers-include-missing-changes-from-6.0.patch create mode 100644 net-Fix-uninitialized-data-usage.patch create mode 100644 net-eth-Don-t-consider-ESP-to-be-an-IPv6-option-head.patch create mode 100644 tests-add-riscv-virt-machine-mapping-to-testenv.patch create mode 100644 tests-tcg-Fix-target-specific-Makefile-variables-pat.patch diff --git a/Add-PowerManager-support.patch b/Add-PowerManager-support.patch new file mode 100644 index 0000000..0ed7b2b --- /dev/null +++ b/Add-PowerManager-support.patch @@ -0,0 +1,758 @@ +From 1fc8fa6cd621c17988b043c1b3abe9ccb189a1d7 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Tue, 7 Feb 2023 06:34:32 -0500 +Subject: [PATCH] Add PowerManager support. + +Add Loongarch ACPI power management device simulation. + +Signed-off-by: lixianglai +--- + hw/acpi/Kconfig | 8 + + hw/acpi/larch_7a.c | 616 +++++++++++++++++++++++++++++++++++++++++ + hw/acpi/meson.build | 1 + + include/hw/acpi/ls7a.h | 79 ++++++ + 4 files changed, 704 insertions(+) + create mode 100644 hw/acpi/larch_7a.c + create mode 100644 include/hw/acpi/ls7a.h + +diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig +index 622b0b50b7..245c5554df 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..59b43170ff +--- /dev/null ++++ b/hw/acpi/larch_7a.c +@@ -0,0 +1,616 @@ ++/* ++ * Loongarch acpi emulation ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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); ++ } ++} ++ ++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; ++ default: ++ 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/meson.build b/hw/acpi/meson.build +index 448ea6afb4..4718d143fc 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..295baa4b5a +--- /dev/null ++++ b/include/hw/acpi/ls7a.h +@@ -0,0 +1,79 @@ ++/* ++ * QEMU GMCH/LS7A PCI PM Emulation ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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_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/Add-RTC-support.patch b/Add-RTC-support.patch new file mode 100644 index 0000000..06e50c0 --- /dev/null +++ b/Add-RTC-support.patch @@ -0,0 +1,402 @@ +From 1b831c95e652d185c20efe74457927f5d7e35153 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Tue, 7 Feb 2023 06:35:16 -0500 +Subject: [PATCH] Add RTC support. + +Add Loongarch real-time clock device simulation. + +Signed-off-by: lixianglai +--- + hw/meson.build | 1 + + hw/timer/Kconfig | 2 + + hw/timer/ls7a_rtc.c | 343 +++++++++++++++++++++++++++++++++++++++++++ + hw/timer/meson.build | 1 + + 4 files changed, 347 insertions(+) + create mode 100644 hw/timer/ls7a_rtc.c + +diff --git a/hw/meson.build b/hw/meson.build +index f39c1f7e70..a9a078ec33 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/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..56c2695654 +--- /dev/null ++++ b/hw/timer/ls7a_rtc.c +@@ -0,0 +1,343 @@ ++/* ++ * Loongarch rtc emulation ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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 = 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: ++ 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/Add-bios.patch b/Add-bios.patch new file mode 100644 index 0000000..0064729 --- /dev/null +++ b/Add-bios.patch @@ -0,0 +1,28 @@ +From 6921fc74a9a58445e453eeb3c2ee74cead690ee4 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Tue, 7 Feb 2023 07:22:18 -0500 +Subject: [PATCH] Add bios. + +Add loongarch bios. + +Signed-off-by: lixianglai +--- + pc-bios/meson.build | 2 ++ + 1 files changed, 2 insertions(+) + +diff --git a/pc-bios/meson.build b/pc-bios/meson.build +index 05e9065ad6..f2a1d111a1 100644 +--- a/pc-bios/meson.build ++++ b/pc-bios/meson.build +@@ -86,6 +86,8 @@ blobs = files( + 'opensbi-riscv32-generic-fw_dynamic.elf', + 'opensbi-riscv64-generic-fw_dynamic.elf', + 'npcm7xx_bootrom.bin', ++ 'loongarch_bios.bin', ++ 'loongarch_vars.bin', + ) + + if get_option('install_blobs') +-- +2.27.0 + diff --git a/Add-command-line.patch b/Add-command-line.patch new file mode 100644 index 0000000..ee9af2d --- /dev/null +++ b/Add-command-line.patch @@ -0,0 +1,104 @@ +From a88f2d12afb6a6b5b3d97983cea95d6088f0bf04 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Tue, 7 Feb 2023 07:21:17 -0500 +Subject: [PATCH] Add command line. + +Add loongarch command support. + +Signed-off-by: lixianglai +--- + include/sysemu/arch_init.h | 1 + + qapi/machine-target.json | 6 ++++-- + qapi/machine.json | 2 +- + qapi/misc-target.json | 1 + + qemu-options.hx | 2 +- + softmmu/qdev-monitor.c | 2 +- + 6 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h +index 1cf27baa7c..0907b92cd1 100644 +--- a/include/sysemu/arch_init.h ++++ b/include/sysemu/arch_init.h +@@ -25,6 +25,7 @@ enum { + QEMU_ARCH_AVR = (1 << 21), + QEMU_ARCH_HEXAGON = (1 << 22), + QEMU_ARCH_SW64 = (1 << 23), ++ QEMU_ARCH_LOONGARCH64 = (1 << 24), + }; + + extern const uint32_t arch_type; +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 03cfb268a4..31b0350b99 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' ] } } + + ## +diff --git a/qemu-options.hx b/qemu-options.hx +index 047d28a357..e62bb6bebd 100644 +--- a/qemu-options.hx ++++ b/qemu-options.hx +@@ -2533,7 +2533,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. +diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c +index 142352b24e..4ca4e92ce2 100644 +--- a/softmmu/qdev-monitor.c ++++ b/softmmu/qdev-monitor.c +@@ -62,7 +62,7 @@ typedef struct QDevAlias + QEMU_ARCH_MIPS | QEMU_ARCH_PPC | \ + QEMU_ARCH_RISCV | QEMU_ARCH_SH4 | \ + QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA | \ +- QEMU_ARCH_SW64) ++ QEMU_ARCH_SW64 | QEMU_ARCH_LOONGARCH64) + #define QEMU_ARCH_VIRTIO_CCW (QEMU_ARCH_S390X) + #define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K) + +-- +2.27.0 + diff --git a/Add-compile-script.patch b/Add-compile-script.patch new file mode 100644 index 0000000..f897aa7 --- /dev/null +++ b/Add-compile-script.patch @@ -0,0 +1,255 @@ +From 6668690dee884342e29103b5df1ab751bb236bba Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Tue, 7 Feb 2023 07:22:58 -0500 +Subject: [PATCH] Add compile script. + +Modify the compile script for loongarch. + +Signed-off-by: lixianglai +--- + .../devices/loongarch64-softmmu/default.mak | 158 ++++++++++++++++++ + configs/targets/loongarch64-softmmu.mak | 3 + + configure | 5 + + meson.build | 7 +- + 4 files changed, 172 insertions(+), 1 deletion(-) + create mode 100644 configs/devices/loongarch64-softmmu/default.mak + create mode 100644 configs/targets/loongarch64-softmmu.mak + +diff --git a/configs/devices/loongarch64-softmmu/default.mak b/configs/devices/loongarch64-softmmu/default.mak +new file mode 100644 +index 0000000000..c4cc246833 +--- /dev/null ++++ b/configs/devices/loongarch64-softmmu/default.mak +@@ -0,0 +1,158 @@ ++# 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=y ++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_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 ++ ++#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/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak +new file mode 100644 +index 0000000000..c42dfbbd9c +--- /dev/null ++++ b/configs/targets/loongarch64-softmmu.mak +@@ -0,0 +1,3 @@ ++TARGET_ARCH=loongarch64 ++TARGET_SUPPORTS_MTTCG=y ++TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml +diff --git a/configure b/configure +index 2576d1c693..a84dc891cc 100755 +--- a/configure ++++ b/configure +@@ -579,6 +579,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 +@@ -604,6 +606,9 @@ case "$cpu" in + aarch64) + cpu="aarch64" + ;; ++ loongarch64) ++ cpu="loongarch64" ++ ;; + mips*) + cpu="mips" + ;; +diff --git a/meson.build b/meson.build +index d0bbceffe1..d80426b3e8 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', 'sw64'] ++ 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64', 'sw64', 'loongarch64'] + + cpu = host_machine.cpu_family() + +@@ -83,6 +83,8 @@ elif cpu in ['mips', 'mips64'] + kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu'] + elif cpu == 'sw64' + kvm_targets = ['sw64-softmmu'] ++elif cpu == 'loongarch64' ++ kvm_targets = ['loongarch64-softmmu'] + else + kvm_targets = [] + endif +@@ -367,6 +369,8 @@ if not get_option('tcg').disabled() + tcg_arch = 'ppc' + elif config_host['ARCH'] in ['sw64'] + tcg_arch = 'sw64' ++ elif config_host['ARCH'] == 'loongarch64' ++ tcg_arch = 'loongarch64' + endif + add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch, + language: ['c', 'cpp', 'objc']) +@@ -1822,6 +1826,7 @@ disassemblers = { + 'sh4' : ['CONFIG_SH4_DIS'], + 'sparc' : ['CONFIG_SPARC_DIS'], + 'xtensa' : ['CONFIG_XTENSA_DIS'], ++ 'loongarch64' : ['CONFIG_LOONGARCH_DIS'], + 'sw64' : ['CONFIG_SW64_DIS'], + } + if link_language == 'cpp' +-- +2.27.0 + diff --git a/Add-disas-gdb.patch b/Add-disas-gdb.patch new file mode 100644 index 0000000..3ccf907 --- /dev/null +++ b/Add-disas-gdb.patch @@ -0,0 +1,2882 @@ +From e66da47c4fc44bf2e861fbe58a84e08b11fd3f3b Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Tue, 7 Feb 2023 07:17:12 -0500 +Subject: [PATCH] Add disas gdb. + +Add disas gdb xml. + +Signed-off-by: lixianglai +--- + disas/loongarch.c | 2736 ++++++++++++++++++++++++++++++++++ + disas/meson.build | 1 + + gdb-xml/loongarch-base64.xml | 45 + + gdb-xml/loongarch-fpu.xml | 50 + + 4 files changed, 2832 insertions(+) + create mode 100644 disas/loongarch.c + create mode 100644 gdb-xml/loongarch-base64.xml + create mode 100644 gdb-xml/loongarch-fpu.xml + +diff --git a/disas/loongarch.c b/disas/loongarch.c +new file mode 100644 +index 0000000000..b3f38e99ab +--- /dev/null ++++ b/disas/loongarch.c +@@ -0,0 +1,2736 @@ ++/* ++ * QEMU Loongarch Disassembler ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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_la[] = { ++ { "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_la[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_la[dec->op].format; ++ while (*fmt) { ++ switch (*fmt) { ++ case 'n': /* name */ ++ append(buf, opcode_la[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 5c5daa69a7..c337369cb1 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-base64.xml b/gdb-xml/loongarch-base64.xml +new file mode 100644 +index 0000000000..2e515e0e36 +--- /dev/null ++++ b/gdb-xml/loongarch-base64.xml +@@ -0,0 +1,45 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb-xml/loongarch-fpu.xml b/gdb-xml/loongarch-fpu.xml +new file mode 100644 +index 0000000000..d398fe3650 +--- /dev/null ++++ b/gdb-xml/loongarch-fpu.xml +@@ -0,0 +1,50 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.27.0 + diff --git a/Add-linux-headers-and-linux-user.patch b/Add-linux-headers-and-linux-user.patch new file mode 100644 index 0000000..795206c --- /dev/null +++ b/Add-linux-headers-and-linux-user.patch @@ -0,0 +1,1999 @@ +From 5930ad6d2fa6071dbec9a790724ac2ec364fb28f Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Tue, 7 Feb 2023 07:16:26 -0500 +Subject: [PATCH] Add linux-headers and linux-user. + +Add linux-headers and linux-user files. + +Signed-off-by: lixianglai +--- + linux-headers/asm-loongarch64/bitsperlong.h | 25 ++ + linux-headers/asm-loongarch64/kvm.h | 351 ++++++++++++++++++++ + linux-headers/asm-loongarch64/sgidefs.h | 31 ++ + linux-headers/asm-loongarch64/unistd.h | 22 ++ + linux-headers/linux/kvm.h | 25 ++ + linux-user/elfload.c | 64 ++++ + linux-user/loongarch64/cpu_loop.c | 179 ++++++++++ + linux-user/loongarch64/meson.build | 6 + + linux-user/loongarch64/signal.c | 218 ++++++++++++ + linux-user/loongarch64/sockbits.h | 18 + + linux-user/loongarch64/syscall_nr.h | 304 +++++++++++++++++ + linux-user/loongarch64/target_cpu.h | 47 +++ + linux-user/loongarch64/target_elf.h | 24 ++ + linux-user/loongarch64/target_fcntl.h | 23 ++ + linux-user/loongarch64/target_signal.h | 40 +++ + linux-user/loongarch64/target_structs.h | 63 ++++ + linux-user/loongarch64/target_syscall.h | 63 ++++ + linux-user/loongarch64/termbits.h | 241 ++++++++++++++ + linux-user/meson.build | 1 + + linux-user/qemu.h | 2 +- + linux-user/syscall.c | 3 + + linux-user/syscall_defs.h | 10 +- + 22 files changed, 1755 insertions(+), 5 deletions(-) + 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..a7981540d2 +--- /dev/null ++++ b/linux-headers/asm-loongarch64/bitsperlong.h +@@ -0,0 +1,25 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 __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..a473916d50 +--- /dev/null ++++ b/linux-headers/asm-loongarch64/kvm.h +@@ -0,0 +1,351 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 __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: CSR registers. ++ * ++ * 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..89e8be582e +--- /dev/null ++++ b/linux-headers/asm-loongarch64/sgidefs.h +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 __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..ef710673a3 +--- /dev/null ++++ b/linux-headers/asm-loongarch64/unistd.h +@@ -0,0 +1,22 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 . ++ * ++ */ ++ ++#ifdef __LP64__ ++#define __ARCH_WANT_NEW_STAT ++#endif /* __LP64__ */ ++ ++#include +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 7870cd0280..c9986c1966 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -2008,6 +2008,31 @@ 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 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) ++#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..2625af99dd 100644 +--- a/linux-user/elfload.c ++++ b/linux-user/elfload.c +@@ -1041,6 +1041,70 @@ 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; ++ ++ (*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/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c +new file mode 100644 +index 0000000000..eb455465ab +--- /dev/null ++++ b/linux-user/loongarch64/cpu_loop.c +@@ -0,0 +1,179 @@ ++/* ++ * qemu user cpu loop ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "qemu.h" ++#include "cpu_loop-common.h" ++#include "elf.h" ++ ++/* Break codes */ ++enum { BRK_OVERFLOW = 6, BRK_DIVZERO = 7 }; ++ ++void force_sig_fault(CPULOONGARCHState *env, target_siginfo_t *info, ++ unsigned int code) ++{ ++ ++ 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; ++ } ++} ++ ++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; ++ force_sig_fault(env, &info, code); ++ } 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)); ++ } ++ force_sig_fault(env, &info, code); ++ } break; ++ case EXCP_ATOMIC: ++ cpu_exec_step_atomic(cs); ++ break; ++ default: ++ error: ++ 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..2f336035c9 +--- /dev/null ++++ b/linux-user/loongarch64/signal.c +@@ -0,0 +1,218 @@ ++/* ++ * Emulation of Linux signals ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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..8bcbfcb060 +--- /dev/null ++++ b/linux-user/loongarch64/sockbits.h +@@ -0,0 +1,18 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "../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..0217ad77f9 +--- /dev/null ++++ b/linux-user/loongarch64/syscall_nr.h +@@ -0,0 +1,304 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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..c4bdb4648b +--- /dev/null ++++ b/linux-user/loongarch64/target_cpu.h +@@ -0,0 +1,47 @@ ++/* ++ * loongarch specific CPU ABI and functions for linux-user ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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..2290a9a6d1 +--- /dev/null ++++ b/linux-user/loongarch64/target_elf.h +@@ -0,0 +1,24 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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..9a2bc1cef5 +--- /dev/null ++++ b/linux-user/loongarch64/target_fcntl.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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..be98151723 +--- /dev/null ++++ b/linux-user/loongarch64/target_signal.h +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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..53e7b3e0e2 +--- /dev/null ++++ b/linux-user/loongarch64/target_structs.h +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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..6acc015b85 +--- /dev/null ++++ b/linux-user/loongarch64/target_syscall.h +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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..dd251e14b3 +--- /dev/null ++++ b/linux-user/loongarch64/termbits.h +@@ -0,0 +1,241 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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 */ ++/* Get Pty Number (of pty-mux device) */ ++#define TARGET_TIOCGPTN TARGET_IOR('T', 0x30, unsigned int) ++/* Lock/unlock Pty */ ++#define TARGET_TIOCSPTLCK TARGET_IOW('T', 0x31, int) ++/* Safely open the slave */ ++#define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41) ++ ++#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 */ ++ ++/* wait for a change on serial input line(s) */ ++#define TARGET_TIOCMIWAIT 0x545C ++/* read serial port inline interrupt counts */ ++#define TARGET_TIOCGICOUNT 0x545D ++#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 +diff --git a/linux-user/meson.build b/linux-user/meson.build +index 4f4196ed13..8b8edefa6e 100644 +--- a/linux-user/meson.build ++++ b/linux-user/meson.build +@@ -40,3 +40,4 @@ subdir('sparc') + subdir('sw64') + 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 fce2c03259..a544d04524 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..04ca5fe7a0 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,8 @@ 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 +2162,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 +2332,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; +-- +2.27.0 + diff --git a/Add-loongarch-machine.patch b/Add-loongarch-machine.patch new file mode 100644 index 0000000..10380b7 --- /dev/null +++ b/Add-loongarch-machine.patch @@ -0,0 +1,6181 @@ +From 810369434538d64a4118c3ec70d4c3daf479bd52 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Tue, 7 Feb 2023 07:14:21 -0500 +Subject: [PATCH] Add loongarch machine. + +1.Add loongarch ACPI table support. +2.Add loongarch apic support. +3.Add loongarch ipi support. +4.Add loongarch hotplug support. +5.Add loongarch board simulation. +6.Add loongarch interrupt support. +7.Add loongarch north bridge simulation. +8.Add loongarch iocsr device simulation. +9.Add loongarch system bus support. + +Signed-off-by: lixianglai +--- + hw/loongarch/Kconfig | 17 + + hw/loongarch/acpi-build.c | 827 ++++++++++++ + hw/loongarch/acpi-build.h | 32 + + hw/loongarch/apic.c | 689 ++++++++++ + hw/loongarch/ioapic.c | 419 ++++++ + hw/loongarch/iocsr.c | 227 ++++ + hw/loongarch/ipi.c | 284 ++++ + hw/loongarch/larch_3a.c | 2063 +++++++++++++++++++++++++++++ + hw/loongarch/larch_hotplug.c | 377 ++++++ + hw/loongarch/larch_int.c | 87 ++ + hw/loongarch/ls7a_nb.c | 289 ++++ + hw/loongarch/meson.build | 15 + + hw/loongarch/sysbus-fdt.c | 178 +++ + include/disas/dis-asm.h | 3 +- + include/elf.h | 2 + + include/hw/loongarch/bios.h | 24 + + include/hw/loongarch/cpudevs.h | 71 + + include/hw/loongarch/larch.h | 164 +++ + include/hw/loongarch/ls7a.h | 167 +++ + include/hw/loongarch/sysbus-fdt.h | 33 + + include/qemu/osdep.h | 4 + + 21 files changed, 5971 insertions(+), 1 deletion(-) + 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 hw/loongarch/sysbus-fdt.c + 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 + create mode 100644 include/hw/loongarch/sysbus-fdt.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..4dd128a05e +--- /dev/null ++++ b/hw/loongarch/acpi-build.c +@@ -0,0 +1,827 @@ ++/* ++ * Support for generating ACPI tables and passing them to Guests ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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/platform-bus.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), ++ /* C2 state not supported */ ++ .plvl2_lat = 0xfff, ++ /* C3 state not supported */ ++ .plvl3_lat = 0xfff, ++ .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 : 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, 1); /* all processors */ ++ build_append_int_noprefix(table_data, 0, 2); /* Flags */ ++ /* Local APIC INTI# */ ++ build_append_int_noprefix(table_data, 1, 1); /* ACPI_LINT1 */ ++ ++ /* 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, 1); /* all processors */ ++ build_append_int_noprefix(table_data, 0, 2); /* Flags */ ++ /* Local APIC INTI# */ ++ build_append_int_noprefix(table_data, 1, 1); /* ACPI_LINT1 */ ++ ++ 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); ++} ++ ++#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) ++{ ++ 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); ++ ++#ifdef CONFIG_TPM ++ acpi_dsdt_add_tpm(sb_scope, lsms); ++#endif ++ 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", AML_SYSTEM_MEMORY); ++ ++ 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, sizeof(uint32_t)); /* clear */ ++ ACPI_BUILD_DPRINTF("init ACPI tables\n"); ++ ++ bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE, ++ tables_blob, 64, 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); ++ } ++ ++ 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); ++ { ++ 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..97d53a9258 +--- /dev/null ++++ b/hw/loongarch/acpi-build.h +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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_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..9e762cf0fe +--- /dev/null ++++ b/hw/loongarch/apic.c +@@ -0,0 +1,689 @@ ++/* ++ * Loongarch 3A5000 interrupt controller emulation ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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_enabled()) || (!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_enabled()) || (!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..102102781f +--- /dev/null ++++ b/hw/loongarch/ioapic.c +@@ -0,0 +1,419 @@ ++/* ++ * LS7A1000 Northbridge IOAPIC support ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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 */ ++ /* ++ * 0x3e0 interrupt level polarity ++ * selection register 0 for high level tirgger ++ */ ++ uint64_t int_polarity; ++ 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_enabled()) || (!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_enabled()) || (!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..a1eb54bdd2 +--- /dev/null ++++ b/hw/loongarch/iocsr.c +@@ -0,0 +1,227 @@ ++/* ++ * LOONGARCH IOCSR support ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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 ++}; ++ ++#ifdef CONFIG_KVM ++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, ++}; ++#endif ++ ++#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; ++ ++ 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); ++ 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; ++ 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], ++ 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..affa97392e +--- /dev/null ++++ b/hw/loongarch/ipi.c +@@ -0,0 +1,284 @@ ++/* ++ * LOONGARCH IPI support ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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_enabled()) || (!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_enabled()) || (!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..fe786008ac +--- /dev/null ++++ b/hw/loongarch/larch_3a.c +@@ -0,0 +1,2063 @@ ++/* ++ * QEMU loongarch 3a develop board emulation ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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/platform-bus.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 "sysemu/tpm.h" ++#include "hw/loongarch/sysbus-fdt.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 ++#else ++#define LS_ISA_IO_SIZE 0x00010000 ++#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 */ ++ /* ++ * see arch/loongarch/include/ ++ * asm/mach-loongarch/loongarch_hwmon.h ++ */ ++ uint32_t fan_policy; ++ 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"); ++ 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++; ++ } ++ 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 = 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; ++ } ++ 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 / MiB); ++ /*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; ++#ifdef CONFIG_KVM ++ int i; ++#endif ++ ++ 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"; ++ } ++ ++ smbios_set_defaults("Loongson", product, lsmc->cpu_name, false, true, ++ 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); ++ ++ 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); ++} ++ ++#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(); ++ } ++ } ++ } ++ ++ 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 = 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; ++ 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); ++} ++ ++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) ++{ ++ 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("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 - 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 - 256 * MiB; ++ if (ram_size > GiB) { ++ memmap_size = ram_size - GiB; ++ 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", 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; ++ 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); ++ ++ create_platform_bus(lsms, ls7a_apic); ++ ++#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); ++} ++ ++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->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"; ++ ++#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; ++ 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..52f13af7b3 +--- /dev/null ++++ b/hw/loongarch/larch_hotplug.c +@@ -0,0 +1,377 @@ ++/* ++ * Hotplug emulation on Loongarch system. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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" ++#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, ++ 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) || ++ object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) { ++ 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) ++{ ++ 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)) { ++ 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..ff3750e982 +--- /dev/null ++++ b/hw/loongarch/larch_int.c +@@ -0,0 +1,87 @@ ++/* ++ * QEMU LOONGARCH interrupt support ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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..933b3f2869 +--- /dev/null ++++ b/hw/loongarch/ls7a_nb.c +@@ -0,0 +1,289 @@ ++/* ++ * Loongarch 7A1000 north bridge support ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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_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 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 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; ++ PCIHostState *phb; ++ ++ e = PCIE_HOST_BRIDGE(dev); ++ 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); ++ ++ 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..ca4d5567b5 +--- /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', ++ '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 0000000000..05b4dda33a +--- /dev/null ++++ b/hw/loongarch/sysbus-fdt.c +@@ -0,0 +1,178 @@ ++/* ++ * Loongarch Platform Bus device tree generation helpers ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 */ ++}; ++ ++/** ++ * 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/disas/dis-asm.h b/include/disas/dis-asm.h +index 4590bcc968..b165453fa1 100644 +--- a/include/disas/dis-asm.h ++++ b/include/disas/dis-asm.h +@@ -336,7 +336,7 @@ typedef struct disassemble_info { + Returns an errno value or 0 for success. */ + int (*read_memory_func) + (bfd_vma memaddr, bfd_byte *myaddr, int length, +- struct disassemble_info *info); ++ struct disassemble_info *info); + + /* Function which should be called if we get an error that we can't + recover from. STATUS is the errno value from read_memory_func and +@@ -465,6 +465,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 79c188b62f..cd7808f37a 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/bios.h b/include/hw/loongarch/bios.h +new file mode 100644 +index 0000000000..8e0f6c7d64 +--- /dev/null ++++ b/include/hw/loongarch/bios.h +@@ -0,0 +1,24 @@ ++/* ++ * bios on Loongarch system. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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/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..ea4007f8fa +--- /dev/null ++++ b/include/hw/loongarch/cpudevs.h +@@ -0,0 +1,71 @@ ++/* ++ * cpu device emulation on Loongarch system. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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_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..a9f8dea9f5 +--- /dev/null ++++ b/include/hw/loongarch/larch.h +@@ -0,0 +1,164 @@ ++/* ++ * Hotplug emulation on Loongarch system. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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_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 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; ++ DeviceState *platform_bus_dev; ++ 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); ++#endif +diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h +new file mode 100644 +index 0000000000..e1f3c8d032 +--- /dev/null ++++ b/include/hw/loongarch/ls7a.h +@@ -0,0 +1,167 @@ ++/* ++ * Acpi emulation on Loongarch system. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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_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 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 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 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 ++ ++#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 { ++ PCIExpressHost parent_obj; ++ LS7APCIState *pci_dev; ++} LS7APCIEHost; ++ ++struct LS7APCIState { ++ PCIDevice dev; ++ ++ LS7APCIEHost *pciehost; ++ ++ /* 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 */ +diff --git a/include/hw/loongarch/sysbus-fdt.h b/include/hw/loongarch/sysbus-fdt.h +new file mode 100644 +index 0000000000..6bf53097e1 +--- /dev/null ++++ b/include/hw/loongarch/sysbus-fdt.h +@@ -0,0 +1,33 @@ ++/* ++ * Dynamic sysbus device tree node generation API ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 +diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h +index 60718fc342..fd9e53f623 100644 +--- a/include/qemu/osdep.h ++++ b/include/qemu/osdep.h +@@ -533,6 +533,10 @@ 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) +-- +2.27.0 + diff --git a/Add-target-loongarch64.patch b/Add-target-loongarch64.patch new file mode 100644 index 0000000..4d6324c --- /dev/null +++ b/Add-target-loongarch64.patch @@ -0,0 +1,15466 @@ +From 9aefc417ef8c705503b51b844b489598448656d0 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Tue, 7 Feb 2023 07:15:39 -0500 +Subject: [PATCH] Add target/loongarch64. + +1.Add loongarch cpu simulation. +2.Add loongarch csr simulation. +3.Add loongarch fpu support. +4.Add loongarch gdb support. +5.Add loongarhch kvm support. +6.Add loongarch stable timer. +7.Add loongarch tcg related support. + +Signed-off-by: lixianglai +--- + target/Kconfig | 1 + + target/loongarch64/Kconfig | 2 + + target/loongarch64/arch_dump.c | 179 ++ + target/loongarch64/cpu-csr.h | 880 ++++++++ + target/loongarch64/cpu-param.h | 46 + + target/loongarch64/cpu-qom.h | 54 + + target/loongarch64/cpu.c | 575 +++++ + target/loongarch64/cpu.h | 359 +++ + target/loongarch64/csr_helper.c | 697 ++++++ + target/loongarch64/fpu.c | 25 + + target/loongarch64/fpu_helper.c | 891 ++++++++ + target/loongarch64/fpu_helper.h | 127 ++ + target/loongarch64/gdbstub.c | 164 ++ + target/loongarch64/helper.c | 726 +++++++ + target/loongarch64/helper.h | 178 ++ + target/loongarch64/insn.decode | 532 +++++ + target/loongarch64/instmap.h | 217 ++ + target/loongarch64/internal.h | 207 ++ + target/loongarch64/kvm.c | 1366 ++++++++++++ + target/loongarch64/kvm_larch.h | 49 + + target/loongarch64/larch-defs.h | 42 + + target/loongarch64/machine.c | 423 ++++ + target/loongarch64/meson.build | 35 + + target/loongarch64/op_helper.c | 485 +++++ + target/loongarch64/stabletimer.c | 117 + + target/loongarch64/tlb_helper.c | 641 ++++++ + target/loongarch64/trans.inc.c | 3482 ++++++++++++++++++++++++++++++ + target/loongarch64/translate.c | 2705 +++++++++++++++++++++++ + target/meson.build | 1 + + 29 files changed, 15206 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/trans.inc.c + create mode 100644 target/loongarch64/translate.c + +diff --git a/target/Kconfig b/target/Kconfig +index a8d6cb1e97..b2abc7b60b 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..adce817d54 +--- /dev/null ++++ b/target/loongarch64/arch_dump.c +@@ -0,0 +1,179 @@ ++/* ++ * Support for writing ELF notes for RM architectures ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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; ++ /* ++ * 76 == offsetof(struct elf_prstatus, pr_reg) - ++ * offsetof(struct elf_prstatus, pr_ppid) ++ */ ++ char pad2[76]; ++ 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..278a66c395 +--- /dev/null ++++ b/target/loongarch64/cpu-csr.h +@@ -0,0 +1,880 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 _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..b5acb6b91e +--- /dev/null ++++ b/target/loongarch64/cpu-param.h +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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..43541c34e5 +--- /dev/null ++++ b/target/loongarch64/cpu-qom.h +@@ -0,0 +1,54 @@ ++/* ++ * QEMU LOONGARCH CPU ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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..ce04d8064f +--- /dev/null ++++ b/target/loongarch64/cpu.c +@@ -0,0 +1,575 @@ ++/* ++ * QEMU LOONGARCH CPU ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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; ++ ++#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY) ++ mmu_init(env, env->cpu_model); ++#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 gchar *loongarch_gdb_arch_name(CPUState *cs) ++{ ++ return g_strdup("loongarch64"); ++} ++ ++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; ++ cc->gdb_arch_name = loongarch_gdb_arch_name; ++#ifndef CONFIG_USER_ONLY ++ cc->sysemu_ops = &loongarch_sysemu_ops; ++#endif /* !CONFIG_USER_ONLY */ ++ ++ cc->gdb_num_core_regs = 35; ++ 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..bf5b36d404 +--- /dev/null ++++ b/target/loongarch64/cpu.h +@@ -0,0 +1,359 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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_csr_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, ++ 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..093e7e54d8 +--- /dev/null ++++ b/target/loongarch64/csr_helper.c +@@ -0,0 +1,697 @@ ++/* ++ * loongarch tlb emulation helpers for qemu. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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..f063c8bae0 +--- /dev/null ++++ b/target/loongarch64/fpu.c +@@ -0,0 +1,25 @@ ++/* ++ * loongarch float point emulation helpers for qemu. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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..033bf0de84 +--- /dev/null ++++ b/target/loongarch64/fpu_helper.c +@@ -0,0 +1,891 @@ ++/* ++ * loongarch float point emulation helpers for qemu. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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..9efa7e30ca +--- /dev/null ++++ b/target/loongarch64/fpu_helper.h +@@ -0,0 +1,127 @@ ++/* ++ * loongarch internal definitions and helpers ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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); ++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..5ee91dc930 +--- /dev/null ++++ b/target/loongarch64/gdbstub.c +@@ -0,0 +1,164 @@ ++/* ++ * LOONGARCH gdb server stub ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "qemu-common.h" ++#include "cpu.h" ++#include "internal.h" ++#include "exec/gdbstub.h" ++#ifdef CONFIG_TCG ++#include "exec/helper-proto.h" ++#endif ++ ++uint64_t read_fcc(CPULOONGARCHState *env) ++{ ++ uint64_t ret = 0; ++ ++ for (int i = 0; i < 8; ++i) { ++ ret |= (uint64_t)env->active_fpu.cf[i] << (i * 8); ++ } ++ ++ return ret; ++} ++ ++void write_fcc(CPULOONGARCHState *env, uint64_t val) ++{ ++ for (int i = 0; i < 8; ++i) { ++ env->active_fpu.cf[i] = (val >> (i * 8)) & 1; ++ } ++} ++ ++int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ int size = 0; ++ ++ if (0 <= n && n < 32) { ++ return gdb_get_regl(mem_buf, env->active_tc.gpr[n]); ++ } ++ ++ switch (n) { ++ case 32: ++ size = gdb_get_regl(mem_buf, 0); ++ break; ++ case 33: ++ size = gdb_get_regl(mem_buf, env->active_tc.PC); ++ break; ++ case 34: ++ size = gdb_get_regl(mem_buf, env->CSR_BADV); ++ break; ++ default: ++ break; ++ } ++ ++ return size; ++} ++ ++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); ++ int size = 0; ++ ++ if (0 <= n && n < 32) { ++ return env->active_tc.gpr[n] = tmp, sizeof(target_ulong); ++ } ++ ++ size = sizeof(target_ulong); ++ ++ switch (n) { ++ case 33: ++ env->active_tc.PC = tmp; ++ break; ++ case 32: ++ case 34: ++ default: ++ size = 0; ++ break; ++ } ++ ++ return size; ++} ++ ++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 (n == 32) { ++ uint64_t val = read_fcc(env); ++ return gdb_get_reg64(mem_buf, val); ++ } else if (n == 33) { ++ 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) ++{ ++ int length = 0; ++ ++ if (0 <= n && n < 32) { ++ env->active_fpu.fpr[n].d = ldq_p(mem_buf); ++ length = 8; ++ } else if (n == 32) { ++ uint64_t val = ldq_p(mem_buf); ++ write_fcc(env, val); ++ length = 8; ++ } else if (n == 33) { ++ env->active_fpu.fcsr0 = ldl_p(mem_buf); ++ length = 4; ++ } ++ return length; ++} ++ ++void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs) ++{ ++ gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, ++ 34, "loongarch-fpu.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..ec25803c1c +--- /dev/null ++++ b/target/loongarch64/helper.c +@@ -0,0 +1,726 @@ ++/* ++ * LOONGARCH emulation helpers for qemu. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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..868b16da1e +--- /dev/null ++++ b/target/loongarch64/helper.h +@@ -0,0 +1,178 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 . ++ * ++ */ ++ ++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) ++ ++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..2f82441ea7 +--- /dev/null ++++ b/target/loongarch64/insn.decode +@@ -0,0 +1,532 @@ ++# ++# loongarch ISA decode for 64-bit prefixed insns ++# ++# Copyright (c) 2023 Loongarch Technology ++# ++# 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 . ++# ++ ++# 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..5fbb8b5d29 +--- /dev/null ++++ b/target/loongarch64/instmap.h +@@ -0,0 +1,217 @@ ++/* ++ * Loongarch emulation for qemu: instruction opcode ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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..a51b7e6f56 +--- /dev/null ++++ b/target/loongarch64/internal.h +@@ -0,0 +1,207 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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); ++ ++uint64_t read_fcc(CPULOONGARCHState *env); ++void write_fcc(CPULOONGARCHState *env, uint64_t val); ++ ++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..2b0159bb32 +--- /dev/null ++++ b/target/loongarch64/kvm.c +@@ -0,0 +1,1366 @@ ++/* ++ * KVM/LOONGARCH: LOONGARCH specific KVM APIs ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 ++ ++#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 CSR_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; ++} ++ ++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; ++ ++ 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); ++ ++ 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; ++} ++ ++static void kvm_csr_buf_reset(LOONGARCHCPU *cpu) ++{ ++ memset(cpu->kvm_csr_buf, 0, CSR_BUF_SIZE); ++} ++ ++static void kvm_csr_entry_add(LOONGARCHCPU *cpu, uint32_t index, ++ uint64_t value) ++{ ++ 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); ++ ++ 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; ++} ++ ++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_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_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); ++ } ++ ++ /* ++ * 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_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); ++ 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_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); ++ } ++ ++ for (i = 0; i < ret; i++) { ++ uint32_t index = csrs[i].index; ++ if (addr[index]) { ++ *addr[index] = csrs[i].data; ++ } else { ++ printf("Failed to get addr CSR 0x%" PRIx32 "\n", i); ++ } ++ } ++ ++ 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..637dec8106 +--- /dev/null ++++ b/target/loongarch64/kvm_larch.h +@@ -0,0 +1,49 @@ ++/* ++ * KVM/LOONGARCH: LOONGARCH specific KVM APIs ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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..e22a0dc652 +--- /dev/null ++++ b/target/loongarch64/larch-defs.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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..d91c858383 +--- /dev/null ++++ b/target/loongarch64/machine.c +@@ -0,0 +1,423 @@ ++/* ++ * Loongarch 3A5000 machine emulation ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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; ++ ++ if (!kvm_enabled()) { ++ return 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; ++ if (!kvm_enabled()) { ++ return 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..7257e59479 +--- /dev/null ++++ b/target/loongarch64/op_helper.c +@@ -0,0 +1,485 @@ ++/* ++ * LOONGARCH emulation helpers for qemu. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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) \ ++ { \ ++ } ++#endif ++ ++#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) \ ++ { \ ++ } ++#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) \ ++ { \ ++ } ++#endif ++ ++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) \ ++ { \ ++ } ++#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..4f4ccc5d89 +--- /dev/null ++++ b/target/loongarch64/stabletimer.c +@@ -0,0 +1,117 @@ ++/* ++ * QEMU LOONGARCH timer support ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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..b6e924fbec +--- /dev/null ++++ b/target/loongarch64/tlb_helper.c +@@ -0,0 +1,641 @@ ++/* ++ * loongarch tlb emulation helpers for qemu. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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) \ ++ { \ ++ } ++ ++void helper_lddir(CPULOONGARCHState *env, target_ulong base, target_ulong rt, ++ target_ulong level, uint32_t mem_idx) ++{ ++} ++ ++void helper_ldpte(CPULOONGARCHState *env, target_ulong base, target_ulong odd, ++ uint32_t mem_idx) ++{ ++} ++ ++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/trans.inc.c b/target/loongarch64/trans.inc.c +new file mode 100644 +index 0000000000..07bb0bb6e0 +--- /dev/null ++++ b/target/loongarch64/trans.inc.c +@@ -0,0 +1,3482 @@ ++/* ++ * LOONGARCH emulation for QEMU - main translation routines Extension ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 . ++ * ++ */ ++ ++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); \ ++ 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); \ ++ 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..2c65e4826a +--- /dev/null ++++ b/target/loongarch64/translate.c +@@ -0,0 +1,2705 @@ ++/* ++ * LOONGARCH emulation for QEMU - main translation routines ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "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 ++ ++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: ++ 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: ++ 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); ++} ++ ++/* 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, ++ .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 ec6bc97331..a824a390f9 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/Add-tcg.patch b/Add-tcg.patch new file mode 100644 index 0000000..b12f7b5 --- /dev/null +++ b/Add-tcg.patch @@ -0,0 +1,3009 @@ +From 39d543dea10ff4995370e731be08017b6d3af76f Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Tue, 7 Feb 2023 07:21:51 -0500 +Subject: [PATCH] Add tcg. + +Add loongarch tcg related. + +Signed-off-by: lixianglai +--- + tcg/loongarch64/tcg-insn-defs.c.inc | 985 +++++++++++++++ + tcg/loongarch64/tcg-target-con-set.h | 39 + + tcg/loongarch64/tcg-target-con-str.h | 36 + + tcg/loongarch64/tcg-target.c.inc | 1727 ++++++++++++++++++++++++++ + tcg/loongarch64/tcg-target.h | 168 +++ + 5 files changed, 2955 insertions(+) + 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/tcg/loongarch64/tcg-insn-defs.c.inc b/tcg/loongarch64/tcg-insn-defs.c.inc +new file mode 100644 +index 0000000000..2a8fdad626 +--- /dev/null ++++ b/tcg/loongarch64/tcg-insn-defs.c.inc +@@ -0,0 +1,985 @@ ++/* ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 . ++ ++ */ ++ ++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..7b0297034f +--- /dev/null ++++ b/tcg/loongarch64/tcg-target-con-set.h +@@ -0,0 +1,39 @@ ++/* ++ * Define LoongArch target-specific constraint sets. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 . ++ * ++ */ ++ ++/* ++ * 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..b105f5ebd8 +--- /dev/null ++++ b/tcg/loongarch64/tcg-target-con-str.h +@@ -0,0 +1,36 @@ ++/* ++ * Define LoongArch target-specific operand constraints. ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 . ++ * ++ */ ++ ++/* ++ * 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..0b28b30002 +--- /dev/null ++++ b/tcg/loongarch64/tcg-target.c.inc +@@ -0,0 +1,1727 @@ ++/* ++ * Tiny Code Generator for QEMU ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 "../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..20f77b707d +--- /dev/null ++++ b/tcg/loongarch64/tcg-target.h +@@ -0,0 +1,168 @@ ++/* ++ * Tiny Code Generator for QEMU ++ * ++ * Copyright (c) 2023 Loongarch Technology ++ * ++ * 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 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_HAS_MEMORY_BSWAP 0 ++#define TCG_TARGET_NEED_LDST_LABELS ++ ++#endif /* LOONGARCH_TCG_TARGET_H */ +-- +2.27.0 + diff --git a/BinDir.tar.gz b/BinDir.tar.gz index 9d090b54e78449dd0b521b29676dc5021cb7603e..e02ca10a9c9264e4a8289abf7d0d5a420df58183 100644 GIT binary patch delta 962943 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

55uF}wdh4}5az%g6XOC#8kC2ckZ+ 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≈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 c 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�b1uC*7$ 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�gN2vPB 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

QDu?S&RG!?6 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 z zw~l6&`lzUdQeO?L@fr3O8qsZ(e784;Hg$d`$3g#|;+V33rJ!x1d!Ns#TBpSYgDv?x z#T495N&apaC{%nG423qcS^R?Ox;5$BPDxtx9)%Z1>&wtXj5Xp zn+q!?%!Q?ujVS)S9sGVKQt-MmJSA^rXG)%u)V}vachaRVs+HWK!;lp@m({qmvX`9M z)qvma4iDAEqF?DXzlE#$3;GjNe@!M7_9$CIc!+}8B#9`S$6sIKm&;8@&Uvdi-*&1S zka}tVJXF)%I{5sW3%P&AqTFoSRFYTiED4IyI5&QJb-|WTnQK`^9Zwwi3p$?2_ErUX zA|y}5!V|$xBI9qcm7VuD2!d4nqpSdhp+lN1C+~5(PZ$W+aIa#Qg4+zhi#WXMT!0() zK8A)ascH{y9LGN#qGHNB7_IC^Ku;D=h!wEcm1 z>sQ6j+p_Gw-*ZVLm^SHZh`jV}aU^BSruxWbfzLwsrxz4ad>*#vj=m`A?C8*6wX~5; zWo11Qw_OuTnjUM_A8k!Is4_gBY`(p0;l@~S+CkQ#a2)G*wwvCC`^61S2d@iaUX-U@ z52+DtPu7gYE*l!RRBqfb(8N|+v#3{><^Gz(QtD{HOZNf8N7^T~dEljReVRd+{Zg^UQ&*AYM%uOe0XlL-Qo29})bF@7mYBW#HY zDt3vwZK#IzSH@ZL@eUn?2dNr6FT6zG>z>K9q4k9;Cyhf(<#;*m>!;}U*T=Vc%Q^X@oG7Xd}Z94UO(wiN*gzgUR zn(}#kbWuC4EYC6o5X9k%fp;4O3;2f|?au>)TQ{YsoJ>@kAS!i^sfD#pT-N}3WpT_Q zRz)1s*@tM&vB}L6ZLoP;f6mR>XBTutep@yZp!#s7V!t!^Dw|@*N{xA8!)l9pVQq5R z_Ke|c`LCwr_WF0rtDQ`VI?LQO7|q25{egXwL3V+;lv;U@vY&Xtl{A`3kmz17bizGX zJx;1<7hRRLqOrZxu1HnUGaKGXGzBkW4#(q_OXgRiN%(TdboCV%?*5^s`?h4Z11~>3 zcc5S1GwC|sqX~snm|~h4e^Il)AxxgOJ$vA-Vi(Ia+Lsh)586kCMDJE)Yi5oj9~zhq z74PlHwXHFRgijZmF*~(PCb_dyw9S5mWOMRP1(a#b5pNAX9Cfg1l7$yf_~1&vxyGfnNif^?yxQ z-|>;l#pm=?4jk3M(*08t-&Pt+=xxeX%}y_+%xPv`bkA+(MFr{VoVcW7hU-*c_nets zXW^Qx0lT2FCX%#)86T%{zE_$(@Z*B8@bEsKX??uz5i>rV7Y8crEc z7ADU*YGy)ik8mi-F=J31skySwfPAQIRfr2g*f;B%AdeVJ;}Vn)q1R0|W|b!BFH_$c z4)21x_|M!Z28kshv!}mvP;uh65+gF+ylg z35#6=YlBuAVv_7!ChA_$M{G9*B(!~U9dg_L#k#ew(0hiM;C$gyYn#V)_lGm(jPupK=qm{cB>IDh6t06Z`DvI&tM(`|Wz)A(+xuW9Y^kHP^kyP1QH8 zxnHV73Yiz$xtVHTOKOIC$WoH3cCv)d3-xZSAffyg`bRopliJ1;dyoq6maT#;A*#^i zb7Z$QJN6a35Pg>_d8pog1EqOluTr6HGRo%&xe$Gwitmw8)*(53Z!A4kOhJB4CEQcr zv?N=}C~J`C>10>w_5ySk?EuSL$o>MkX-)k~tx6|sP=|Z5uCz~STC$A z6+bHEZcw{;V)LocUPvbX43QL~^_IA|&@>5^c#*zRCt6egp~g0sqYsQ@y-g)=lL>C2 zpIDP^rP~Y9;0e>M z{je8*uN27AtGzZK?M;PkWmA^$PFZFWy44yAZl@hVHdx|g>D0|?G6l&^h4#s~pCiI zVX{oJ1{qI>$WlY4KLRJAsp&Y^s381r$lG*0q}}HU3LoHG%E*61He2J$R2l^tPldtf zFA%8O8b8@C$y5`P(EI7+zpKeVA(R7{+*)F)wtGS(y+M=GB^%VxPe|qgtR)?%x64JL zGHAUT=)2RB{Jjh^QwMut8L8|isPX`RuPinR?MlZJ+o{=V-Yq6khW}j+xzar0F3qi_@;6ymWznrX))n zY|Ym7bPAm(SSwoNsnuQH@dF4ZSq@F4x6Ugl4Bh7Hqr9g=i)oJAbXLr*U2 zz`v2Hu;ryJE$*8}4*N4hpd+tdT{1%ONrSlQYQaskD@&W%Cmk^M9UlWODeqAJ#9(r@ z{4A|LOugN_S2(3_5EF|U49~OBs&v9X)SB>N>d7?x5cr}4ruJZ>ER^6$B1`e09zGu3 zhj@8eNCc#U0z+07bC*n&sB{k-#^XI$G2j9z{|miLV;6wDMkQ zW+4&7CYv1;WbZVbE}YWf$^znoAkmuph4_^T>wt|(cjZBAw%9F~t6pw87wDk}I)_c` z-b0^xP0hsRs|(Tv@`p+f1~V5)I?q}BCuZtUI~Q)PjCVbgCU$<}Og)iChOLa+*GKR| z@%vfmb!+wro(B3%<^!oWypwoZP-Df3=jbq{w1b)oP9+3;=zRu^b6b$;daH1Q5&Udk zBYa<7XTT}KDQ%7m1ZN23C)Z5-=n?`v__o0MdWQg->aC!|U=>CFVZ+Me4*cVJUD&XW zT#*6Wv7^q>!6&Ub{6aLT$)Az5vEtGcRqYU%c zzdIKOl{?rOWz5EzNGI7qjPvO%qohI zSk_>O@wBMLg+Tp?T>+6q8v<-or|rK?JnJ@^qu!6Qf$hTl*R00jPaRHr$;qA;gu~Oj zcFbLwrudy0!yY;yYr$t@pm56Y{$&( z&wo8Wqq<`LKCbm80i&`7L@`@1H9as;ef0K_OG9-Nf#&95@ zW}#1v99VV`nCPY+yWJ%g;w6VA06)AGaEHUxkdJ+?TM9V)`eYydxN}K^$jN~|9(QVK zzXT9llNFwwg-U>LI$R5wFevT{T`%vG+8t#OXVE| zW^+yJ_Q^aVw`Z6D?a3*kv84Yro4Pz@mE#&Dzm zj>C{c9(uf@!-RR<2KcEKuGbi58m0zvm2-W-H1o62VX!PQZJ-K|^T0BV=V@TM$}IGM ze^dceZ*sDDWyPe9m||d7z40UFQsi0U!a)!_TbX zufarO=pOn&;E|qyOM%AYuzE-1^rnmk^`l!kF^F8bL#F!d{hIJ$_*S=H?TB5cAX3b*{?N4#+c&9Ceh=FS3Gu1Ri+tI|l{zbQ*ry z_+9}B{!|*yFur$pPyp709srYhof0Yw6qDJ-7Wgx;#AoZ-#S6MSS?F6Z`9Xi+InJa> z?gI?yB@T-1VQRpUOs@Q-d+CT>5!8_hoF1hPI4YZPbu!>^JGj2U0GuBA7^4Y>Dhdn( zVQPrNK${nHf=fq$E2kP2_gV-D80b2mNLmQUP{#!rfI<8|Z2}CxawS4IMYqCF^nW(+ z5F*RqzYmL@Dl!E6F)vRG3E|8iAnpR@t(yX*wh@Yt^w8UQS%@`C+qoMWR0)JBr%@P0 z5ggF}+4kS`;ZXw=fI#xWa2fxL_}`PGS7Ojm>&EJE3%Q9sNOx;Kscn%_5@QAgbhP^ zRz`0=_09xDT3o`1CT|Ogsk5^z8n1{8qQktR4m%G95#yDH0!zSVfN0S%fRS=5?h*<- zj55g;ZZLf2fZQ^E6CO59^-Y68#6^VsJ@j@U6ap8E#mhJU?Ye;jNPNaGFqA^!YOs1L z6}{l0_YYT#fin0HibCx*4q_D!8KMAu-qm?rk4eotpUN^>X#-)(2#)L zB|NjM9tbt-ivIxn7S-5)sU^$V*+dqG>PXXLK45AgZzP!Ky2#N;C&vr1d2TT5FkfbOrT-RWjZ~!Tn zVBiy8St#D=fFyu{?5+aSDYe2g0b!NXKpRU3#2zrA-J!5y_>q+n{;Ek3s=!`p5-{aB z6^O+W!qtM^P&n|z>aO#Bio+o40lp?E0O*C|fE+en%?F_oH%wjM38L$!xMB6I)~=}I z<2SZtp-`j;1|lf7DYrBfS7bHO4%&bZ*KJBhfDwa)b4ng%Tl}%ri*$i_Y&56`TL6Rz z`i-@4^&G=~%R*bNA-2Ty!`m#aX`d9%RWCdJYSa@Bkz^{mED;1NUKe-~VD9f{j1ld5 z;8U*M0gxBt8NhknlmJ6wVFC~(H5GLzDZs;QE-m?JB7SLH&osEf3M6bQde2&blP7?V z0nsxcA$60wBVDj&IQMBoMiMkVROxBKH7!3g78J6wBi`3TA8F05)d~ARws1FHpsZZE z2;!0DV;-znqo)PIpxh*8OF1#>w?ZSf_kzZ;9=_WnxX-{M3V}7k`DN=DHaYg+kpmzr z?YJ|W#2@JEs1?N;u{B$NzAX!YwUFWmn6e%a5wxv5pl4rh4JreR-DV3Ggdre=8PSgb zB9T*oH43nO090BUxHw!i>}{bNIBU%|dtYaSQ)j>T0N(ff_wym3IXfNbgk@#H%o z)gK!b78pXp)ietF@As_s^jM7mffY zoY-6-X?8%S`hDc$k`A9fX*THB2le#O|6gpv*rNi2W4L-XKtDBi`HxwxdzczfyLd!g z4t^Ef1H%A9x+x&+4fEgwzYq;!w`R55d!>ayNgqM(>VOEmAb@fV5CI!x88jo(CYSH_ zDIEKyBc9_+P6b)o+FmIagyl`k-X8i0FFFQNOhK}|uZmo41w{h7YIOl-f6@b!8PDS- zp-_8qAEGjvg&l~~Z)KsiMnfV2hmQfL_r@E1$aV1>W4U>-qQT`*YXZ35_oMq4B(Dw| zCdB*ES%6@tz+W*c?20=i8Adm~kfnt{$U=Lpft56dw;=#_T=>C~+8e~jNkDR<6hKKNR}jH%0J08=GFqUz z7_7YqF73b_WU5cQ&{l5?aVce`b(Y1=RxdMu22=nZmjSGlS=_-p&LFaz0RjmFQtAOr=={+=3ol0`3f~C8Zh| zhzkoUE9-ekD+vW5a-c-F|8ybPqGWRCG+VwN%r~H-1248RcA(taRG&!fk@r7#^kK^x z*`;$lkp1|j!53nd;#m0?h_uqp;%;lUKn|i2QVM$7L!SVo_fHRO*&bvnx!ile{ht9b z08DZPSe)ns*!U!HnltoJG4*hKSR*b2`Udvt z1SkzS2W5Bw2ydNL147k}wTWKBsYU$Bg`C*F(F#4t)_`YgMs8GkaxT4$@AvJS^34SW zhaBS}0FZe%SQW`T4SH070ZBoXRuIku%H!07Ko7d?fq`N4GtWP!z##cy<5WN^a}Eel zfPg~=?}xHbC15or?%Bh74kF6?z)91bF1v%!b^z4oh~sQgQAg|(qQwp$02VUZoy8)1 zrYVmy1|$jKa!wYS1b8mSB-@JsJ96p<_4v~Kt=QgUVjyo@G(o*{mN?k zNL0TA7XHM*P8S$R@*Kc_`ZP}qm^bAsKc&-8W-&oYMp8TM*@J<~z-|ywo6H#iE&XW) zZOP2Bi@|R-&u#2P2*LfLLe2^_m9YCx{40%jBQIKpm)7 z9KK>W=YataAX$Tlc<8b6J|qtyJ~J0&8+BGjfQ^Ytfpe{}g2IJUy5LbDU6XLNu}nl8 z1sF^Gz5(Gox9@s+=^86*~uY!42 z_*r{#&o$9^F=BUQR0Q$}ZUQ5O6=96JKm_ATd*1~)$foinu?6TuXw8o!1|xPp<+ol#Xu~!A<9~K-Ty&ot@+y?!`xh zB2dK%u_SMUWC<^q?RJfj8|>jn=JL}VMD+Z45#;V9Iw7C3mZ%CuXv}%o5}(UL$Dd>W z%|W0H1#h7%Br06C%96apm@~!;d0zk|*{wrL(oK@kd}}H}t?}eh5ar^A3DaQ*DbIQ?NpT4{nT7Na_Gj|GbQ*pl1S?L5u@(+8cHVG8 zPW5ChD6dT02aO0RD@Q`GC!nFCi@j4*du19w3Bxaa%>LXYSgo)8t*XBR_|51ObC# z@UC8`T|lj(w`+Rh4saZb6Vb+65H7E{jd<1MI}g1SIr|i7RZ8i?F2VX)^te;*3AwhH zgawX4cK4?~gZ591UnWxK$~2F`$*tpu1Jm2q&wdePJep?@3*eE)?`6KrKck&qocS3J zy`~WKg{EXqeMYaaGjty?g2u|@;DiHq!YOz0P#ZUM%ISOJf^oR7 zp-OW~QDrSS#Jp=Q2WO1cFyA;g>4W5+xQ+Dw&?n&BE^e+`bwd8@sSsjs{WoB|OoStg zdue79Lg13Huy8)ouE;hwoS?Q-jyAail0^IQOT82+Ib`Pn$5^~MhE z^0jtr==_r@@*x2E%qhmz5Y8&w@M?%rq)9jSk85*8 z&a`6+>X)-kkAa{x6PJm3B5t9U_XQn$ZZ3{-(aK{B6}S@6ao#-@{E0@ z991|bIop7FIsTKHHTz4l%UnR}F!#$@Gz?5DB*Zwk`@LA#2{{F<*3lC_lM+%?DXR6- zS03QtMqCkRGv9)_e**W0L05}3qv;_NYlkw5kJmh@6m@#)cjt*py+{_bcZ|3h&lrYx z_9Fj;fS%hH0CJoPDn)_C2B$pHzlTU)(QCYkMM2_fdM4pNx~zxpb<`CBE{OVnYq!B4bzZ zPOwU*O|`^g7Cj8we7e#^Jv!x-S1CFRzYW8OPsp9D2`2PIAN8DHY`B>x>IXu&yX=@g z#Rv-FaEc8F^F-aouE@KMUG1%gBwx;sdV#6ufnOwx%LU_|goneR=%Sd5LV+8n70v=S zSawWd_Zj`T2V*1u;=BV;^BNAl%}ej@#+fq$kMPl`eZwH%A`J{|hmpfx4Ya-gOBn@hQS}9@_8|;#tc}7$IH*WHJv86nb z0CY~xLC-ton$r7`3t_lTo(Q)Fjk>l{fJ}3p$HVZ_JW(ak4)w3HBlPE{vHec2z*0=# zjT$iu`vEg!gbXP!h3HN08`j0v;BmfWP`rB1x`^KeOv6%0piWkc*&#z_AuE&K&k)Lh zVe6vBKLL$Y68kor(2u(-rk330Pl#)1L<7)^j6)wksWlsh>gFA*aLsd8oZGDXdBcVY z#6OI{JG>%(E;%7TNjqk^<-BJ6!OB|N&$~SomG>4KNY(6tt(0oIhI@abu=Zf3L%AO&Euruo|Id7=$~P9d{K_+&~*VhD#_pk3p}p%|@|9{_+; zPXvZI40$f$aF9$-R?J1b9Ncv~IbN~2=69^NKs$km^JtOPY#uu| zdszHA`27~4vvRhJavb^jA_Qt+TZ<*CJ-|EZ{Q35;ON&)HnP9TE|MyoX~HpE@T zP0kw@lhc$LQ+TULYtM4+Gf|izOQ*VGZWqz^W{Z zxe(WMT*3RC9%V=KDbm!+6ra;EfCTj1{I%zjO6L(mTwn=d*sjSIOfnN-D`q1Qn2np> zC!PNCs>^nna;*X?E-?6e!L)S-P<-%R{$!j`;5;~;FiNU9>Rx;6Bx zfK*}V9a?>vD8JfYpJ#;nbtBY!tYKRzl&0q0WPT%yy@4haOJZ-RfMuG%XA)n!^eoq2 z?Ps*P_$wrvXNhEE0R(?UZJr0)fqyGM7B5$Fr(xw{nDT)a38}iq}0&p#@S{x>ZY%aGYtA;7~bCNv<-;vrYc_+Ct4$K z?!_DraC9HN`BNj`)Poal9M}fnNrm!28xwhRY&9rz6lv;=q;pobUExZ71X(KGNb7BQ0(yHhAQTK(ug!S|tIrSPiuN5U_WV#>cp1nlapA zJs6gl&vqrmZlNsSH2fM{s0!GW%YC9HKz{?_f^pfqjLWXc*Al* zGL1{IA?g3d3!}!kwZ3-VF<{4H+H=WPj>3dRu_1pgO@a$g%kS^W%?A{_H1LtE&xCPr zu32Y$Tv3_qGJ^Ys;f;9`37{N$)NXKCIHrK?dXbUK5OLz=O~_Udb2NlA@93u>|6}%x zCq|&C9gUnwJ)$6Qnaz2i-WBj)(T7UX0*8I&fAnHHH;$u`a>o6QpaY<}^x~DglV!I? z{_K0aT!g}&By%+bez>w0`88enIr0pogz9Q*=tY8y#-{*XvIKPu>fb=65r;BU!HuX@ zFXi)C*}S8a`V+#i#O0TXmRya0Ia+Q>eV}%QhaM6nT^hqCZD$AIpFz8jLM=2nL>##X zrq!+v2LVyTBGaK7e|$o&18Q)N{pduphL!7p-I`OHzMgIlCBnVF^3Rl!)%etF^tX@U zNh)wfkTYO8U>)7S_-{I7rcWU<5JDeSkT=ev-bUDd%wV`43bMs4GauY^{imENR5kG{ zk4yA^3jEt%ryWKEc%;h*GZ(zPu=Lm1^7kfOT40(w#!dew9o{bW_rxYrl}C^ld6>T! zE6%to1RD$zsC&7EjXO$9dqUSM4q4ej|80 ztjX`jIACW0`Xm*0mJQrQpFd}{OHTDeln{Pp89|*bR3)MP;2hbvAHOR??K)R1aX%+4 z6_4>HOFufgKJb^}E`25lYAh-wdt&K}@e>D)D*!W6-ee{S znMP5Nve#ItHQBKjR9+mD(36g}YOuYj%(!_A>=oMv6v4W*Ni4I5U8JC@&S`YkP@bUW zc?L;3<09D10(RuBBE1ItSonKn;?E)Eh_QT9>WPh~Qtzo%W-b~tqe#dcwaWpFZH>S5 z;2?bCO+B*edO6yeXLxI@w6vuw*CAl%T5~EWyHai#cc%HZgSrN|W(@2X2Kg0 z0Bg{)#}l)&B$H*U(WpVTHJKwG&o2S|R3585rdkFJeV8?_v zQ=a_&Oz4fh7xouKan{&HiU+J0l)g6L#xA>a#N>xc5hZ>%uOlf;J%2|dN)XjVw6?7c z4i4Y9n=n!pvGk#9#lxmBq<>eqo>66xFGboH))<=h8i)-M5q;KX{ngX`G(UdcQjf65 z=T0P%J_at>P~36LA-FR$a+iL5f6cj`qcX7>C2)uYxzt4WJogB_&^lO>c6@B`V)xw& zNw0VC6~pb`nXL1{bN3_t-dxNciJR>0dS5(8iJ~&q1<&4Ogq|v#c4+f1rw;AQtj*1J z52ikgi&&B86?4tZe4+;T)J#f2-j^+8d2`cs)q8i3#0g70f|1Go(E^7#@2Cg-j`E?) zt!r%{$MT~s{*_VPZEC@J8zHwprzvWspenMI8P$4JX60Ld);SP9=doAuMSo;KWu49D z*`MxT`A+b}zcHev{lo4pq2#VZ!zPvYYFZ+mDE63r{J75evCOx4bab2IaNCiQFMoLc zXi8plXzS{>Bl>H5zi)_`O{&>e9}pZdW(~I3uHB?KQ~r4J1Gf3$FxhP6P-XPN!5_`M z`A-}w&l#?iGL^g_r>nw?(dNg-n&0L&Uq?)m zU8Zk2Pv5`NwY6t&ZB_8XU`qXz^K^>xflFTS0)x|>^x{g&g`$}KAYt4*YySF#96ab6 zN&*h6AW!t;T6#*@QF+n*8Ns_ji4GxWT(-@}SEP$(-z=?Aw@4jB9f&-cup@!sb)xY1QTba<^IiwCeEzEWPA! zrmPHzisT=PUQ6X$h+=(ja?L#V4` z`3^7J_d8F4|JBj5ne38J)72FRtd%8cx$8vt&jpT`RsSLx zVCKrP&2Qfb!I+T1HjI6!@o|mm8pI}vS>96+>mIV-Z$n$3W-2OLw^IJY#*6vSUbc67 zd!GVt4%pn?;LY)LxaGaYrt0mPiQY7y)BirN7+-g~_EE-FT2cvkSlaun+n<;J;C(TF zEO_vg!wrwq+Xj1^S8ipLHu}(RMK4|0P0%kxJEY|8iVve_w3@;i9b+b{Zz_o;T1YA^t3S5}lt2+J7B zoAowM=e&($j%Rd0!T$au(X9(-JnLQVpIS)yE~D|Wv5D#bst0#4>-c+aQY{v5HY zD0&V3WOMcK!JEwWK2c!eZ+Rc~*PojhqN zd9`7KUuf$>QBf*w(l~{4v8PV8J4VZ{7By@ruL_GjHUH)-A4N*Z<3~)>CkZ>e+#7D$ zS3fBoK9X2}ZzX)^_bG}j+7;Q%ts0*_ilK`KH}(hiF@G7UVh!D@_=h6-(46V%jpoI6`#q_bo|L@1 z-Ile4*eXl*Ww86Dc_Ougnd9AZznbYM6+cC~9}3UB5!Tr+b9s_bnW?%+H>dg0?``Ni z=nb7R?O-Qwm}>}oa;55fMak2+2wBI5@BE^D?s|`&{-vm){RI79UdcCi{|{wv0uNRD zH~!!E-CZh0C6T>VWvgUg<}RVKRboO+l7x_TEMv}Hp(3QRWSbi?MaVW7%M^{VPl&-7 zlXYxknZX#d{STh!`90tN|Nne{zu)V{IoCPY=h{E#b6sc7IiEN8r0v1eV_h@a2Tu=+ z7E86>GPHk7(8W7cB}V2Q`hLw?_|m6IX_ifHp2Vv@l^40XPNP8)C6@_pWCrx~L_FQ< zYk@@EypJ<{z#oNZSPf1+@8&gAyMk^z;$a+kE_s!|pkPJbp#U%L zW2(1Rjb<3f*M`5Y{_X|XO+z*x#^`yHaPjHj8h71!gi}u)_eo@9@5 z*Bo&>0``*!{KBAY;OF3*fYvE2vcyK|lA!Q@xzh9dxxbgxR8+4S zw9>mYj|khWS$~ByR_hvm$8hoF3Vchc>sn zR+M-B(co{kh>wLP4x07}HlN8lQLmvtAIdlW#4E`{yoaa_T|AXJRWf(_ zosEq#`cPnUy8TbbFD}J_6O>%tRmYG(%UQoP?(?@MmkPf;3V^g>J@Vwwcw$s$^9L}W z3myRY4$48R!E>s__tT>}t0>JrHK{__Pn*RL)(qN5{3H0cX=BIjXo*1aIsL-tRRz}x z9m>V|Gi#raT@QKLMNegOqJ5!RaW^a+DK`B6)vtEdn}v7=z51-QP-Jrs!+2;(xXa7# zS~nh%Dj)r`?18Iqc>i+!=i3+TaUZdF0fJJ0v~lltJ*PTLmBHZd*2Gz*{M_1tTdg%S zpB=iiOR~+C=JUIwYog0B_u+}};E7j5pc&#e#*2C&1kUBN~>4KW8&#N5Bq8IthAku{g(a$pH4XT+N$WS ze884efSuA0cFJVSY~RmY>Gs_=KA?(MbczMPsF?{cw6wtI;15lyZdPU#b5zN4@Vftw z-5b~TE!!A})5@PdAF90Rf0b2@Hi!!Z-&XIan*H9B)O5fRo$+8Wyw5$}C3fE5Qr+ps z4QFHgjMACDSXvq|eYQxJsCil@-#+}K$4VCHXt*m(zsvkNr2x7tM?Bx-Oq!pqmxqr# z)_mdc$?XM}XETKF<>vR8`CnWaIH4Lnkxx|VFt$M_b#5=Y-TN}P`k&d_?xd!pvTlh9 zn1Zutr3lcj#EK89%1?untd~S=IaDTpF8pIDD=TjIL?VF581pd$wfeR*xOBq`UudjC zs?Ry`%JX}z3ha61txKXdall7EuDHWL^iWcqauFq{ZuVARP@SjgA(B_ka7Fk9voogk zAN z`+wH7j>i%{HlY@6>8aOI=?0n=(D_C5DtY*Q(~5)p=O0U_diFQ1=*hX}HTLA&LJB=r zdazK4D=*sG#5M?eih27(yGzET+DS6iDF5~WPYbn|y{XCAa;gOO(06-l;WI%$u1|3-TKL|lBG{U( z@=H7xIig4Dh)(EBE2A7sv+vd@2W_uCZ910$uRlT`oXn{Rdt4qQ8rQe*ZQZYJW>%#@ zr9WhT-dxH1F5$=^uW0g0uejPV8))r2XM$RpUSn7Oml{?UkU#u9Kh#H>8y(O=X|Y4)~L`&3y7|Bp3>Ju4SiL+ChR^r}A6L)Ouy_ zzgJxWN*K7Zir-^HPnd5Ew&5So89S3azda{V7;9Fz(`{`21O;y!QRd5e6I;=%*=I|> zZR5p@nqZ4cTjpz&M)YJR`RME3Q?4<|ZkAsVI*w{@}9 z+$H@l_XeVyT3h|UF24yDpqvgY9Gp0Iu{S&$2)C;>D_4urNTwH0mGW#HF{n~Sub~T= z>30bl(wcSUerZv7-<&ACqsx5lo(iP}DR-LdN9zzU9Cq>ZK{cZc-P=%&CQIEshKzRI zak*bTX8HLlp9(P_FoSQf9@1J~x8Fi|hSMpn(Ozas`4|<7)x-%-VeNffV)9(29}5`J zPzF!UGrj!v_V#*{vj)BN4r07kCh{m7Q|r(eqJ&6zKuRPYbf*mM9I+d zo7*ae%#WeEb=i#RfECxkbDI-d`9gKR(x^#((Tg+@l3Ky-a9(M2??#}`U+EU?r^MLm zQAg-R>@BB6t(ze>!&fG3KqoYbTW3g!PvoWDA!j6GFOtuQqkfOyoPUo84JQR9ev~tz zO%ywZKodLLVC4K{`Qc9vKMXR<|M9zGq+ukLf4KWPtE-}jeW<0mbhSG8qfNz2f}>5^ zOnts6ZPm56La%sdKGOKm#`5KmdwtPvB0gWD>8Y%6O)Fqq`_D(GejCi_cH`ef<48F1O|x&~0Cn(k^r{FUEq+w@p+lI<<0>U(&koEdn0%iF;oGKn=!SjDg86e0e6KaVX6 z=8UdCfgVC3pAOnodEHPR#C)8*_+jkm^O;Bu(WA1-y5EJKjg|xfqQ|YAdu%%C%6w&e0-=O zmNQseKMPXe8>Q$Pe|%EPY zbtJi8<7Zs))kpEVwsYL|A90V$kH&zLN?81!z=edYd4tjqVe!h-!^h09tSfg)#*|FR zIaQ{k(S@hx6RPe31b8&Y)HnV+Sjx3>gXpm1Mg8o(*|K&dxtG$Iv0ct#2U%BG4{L&4 z3CTi5h@u=Ya!=o{|p|SUc1CtJtd-1 zlp=bxs6Tr2`dG9q3^FW-H!9*}p*=s!!gPk^BD0F7rLUgR!vu`G`ACQL9+p5=y3E;-RSO*+I}@JzWA1#JXee|G zyzih|`8cGVux=A>X*$`SRU3;OuQ~HP01KwUqy>ohS2d9#{ zZqFvwLEolGy;574jalBA!mA|CgJOywAMc{4s_zm;uLF=mPU^jZ!^f9HXIk1U z?aS83=SGDY7g0SJzv^oq`)nOB&K-FsK~0ek@bom>0VFb&k|~Pxpg*XoN=`+Y5E;+L z=P)@Ryym+x)#^m;u(>(2&WB)s&A!RP43rV8?$2@6gVF=NP5Wd6D_cQIO&Z0wNyh~s zGs)dI+z7Yb{P;_VPg!rQ$gQeYN~$jC-e7hSY6Oj7w2ft^?CyF#SC? z=aID1BsxB$)^BR=-HMWlZBaAE3o<*W;+E@jwBu3TU1i95w3}*Xs(bA0)6t@eiKns> z_1^i*5R@FKa8@zUJrbdb^9MSPs;k) zqj0hbO){pK*qjRg$t3EsG}vr6!eLs4_k%OTndLnFpsvHok4|IBzDvgJUqP=Nt0uBl z^qLsklQWl6RU~|fs-YC)!bka>$rjxJfPvNUELFj;5mdE-*}l&u-uTkD3?Mm8Q9|OP zilYpTnM_O5tS!G&SMeD;eLcMxrlIM0fHn(_wTOSoTq$VEGaEzj@=K;meCv_D{mWI_ zFr3GuP{gL7!I4fdaxOFnv2P$RhgIH^kKdG6+7i67)qumB4H(P# z!skn+$yI81l8Od<15Rxv0GkDX?IL{NtW)k**8N-Uy0cXk!%fM|eVf^!BsO=+_)YnV ztvVZT3d(MEkn%%y^QTy%rUS5ck|MU2FslX zqFZH$?GJct3@U4X+UB6DdXj(Zz#VX?-X49zdao7vI_XQr@c=_`Y=zXj`%F8AAF8H! zV7#rD`fg3|En;-_ou({P^9e+bi(?})ZQlM09J2Q~OdJ;^um5|uVS9}!oRteR{yLK)E(;0h?@ z5$`m*aOgGo1|MkUGJr6?or{ZJ=TKv zaELY=U)>)NvZYn~H^hUd)2@T98Rf$fFTJ#-IlsmhjWxok;xZ>iR!E!9%p zNC2eC$!|(pZH%j>mVuWMb3xB0(=O&j)+9LaR6;4n(AEYrb3wvfL$5^JuJB`RPo8lW zGeH{$N$C&RP=G+}bd!x@2Dan|d--GaeXKKwy*B41F(+B`kbn`cd`0iqTs3o09nu8B z?}>v!>ARqZa2KTt5j!nnN`cOS&R*$>>>^qTUSP*Dr$yuK>etWx!>k?F?UjHWL@#$5 z8{B!rn}jW@4{G(!2 zDfNMzpJUy($vMHE>_|5s+(+Kaz8S2deF3RbL$6|<-T%ppNbpzyLNi#kdyi@KrV0=0 zst8ogj4L~g2L>F}baSe1-XrueD-TMS=y*}@yP!3a3JdgiqzdOfFZb(dO13p5yQ{n( z{uT08BXPTfS)P)m0k6f>X6S}f*+heID+*nle2Og5p|?86SVQchR!5ijUhRRq;RTH?Q($qoDSzqgYiF=GgNzL$m8=g<0CxY4&wJoxqpcKBcf6A%dP39Se``sB<^MBN8i;l0M~sbYsOeNN zoE%g=fdjY5Rd@PyUbt>l?H}yFvvL1FCJvqEjTq?vv{DSDwno~8oRqCuv!OX6x~j9# zG|*UPqSK002bBvD!|8`2^TGZJS1XzRmw9BY4$c2oUND^xUQ#pp7`^57L}}YXz1+!M zguOQJyC)|}7#7IK2sbgHvXqe|VQiTf8LnJp{v6xGtjwUuI^BLB3%<&l1gNXdIr&XT zx`POEuaD7{cdjQ+I(p0Mc@jbr%`m8n;JMGyT^A(wipPu|q9gJ{yH6_?dn0Wt z8N8Lg($2aX1UPL`$p2+v&Hitu$^U8m$IdwdrL!K`4Xc99AKP|YLLBM_PNZm{ayu$!h=w+aA0S4#XSz~*r2T^o~~pO{#C)#us=Q{yzemh@@($P zwS1-1nC<~~tKGW!r2-_=de>=pM;3(lDUykqc=kTiz>~aPPZ#P<{orm@?$a?UwyV(L z=W13ICNR~VBQiBmhA=cbbz9X|uor6fh84Wrdt&k2q%zP9qcUcM>^=`WLtn7uF2C9t7?=4f@WHL#q~%mfn3LOr^Vy6X z@Nq5pJxp+vt`PXNHalxfH&fw*qP~k;I*eVLwSM{v(~j7GokS~8)q(g_(LWc}deXk{ zC>|)8D3uK?5J!<;#tcGa4kd%mkI7b?0MXC$pXm={_NJngu)weE`FX725$h6TEcguO zP0^u3ubY+kN^W42Dtr=)BJmFfs8a4VKLh$P&RC^NuP4!>!kHPU?9Rb+LHxsH7Os5l z>pkOVanJJoZ+JeOFeRUnDwl=Ycv{NZWeCq2qS>kIRvz_v%#unBAs7*e33`SnR@64QW;6jQ4Ecyw#`| zMGA7KvZ}VnOSa~&10S$?pE`qQJ|Dc7{8MFCSJ*=9qc%Aps2_2??$@Y_xEZnfE;&*> zgmibbLswpegrl6$mCTO5Xhk4;BoMV@BOZ@WA7Er{`hALLiPQZssw35_tKjM#~L zN`(ERqzu1kJW%LJxKS;JHG|&Adr$2iLr(FPJqP!TkA0HrSk`=GfRZKq_EpEUq137# znQ{Q4k(XE0AmfA=`wfPhvhjy-cc?E{fnYZOinuyJ6F;BMw&vl_Nk)HrBl)Q2I7BX5 zXtA%LHlVGi?H`Qj)Fg3?sm`74Zj0D}c?I#WEj}$PD=ATDK40n+iX>nz!1lWmtEU2K z3)*At2<%ux-|`RxJ^7M9vILBCVKBZ==dEt2y4PXRS^0N@G`kz{VNZwYhSw~ccH&1F zJ0%M9ec#Y$(4Dq_*&}azUECZxPhfy@FT_nA<1C;AHOkb`Z_Rzes2bj9Hwm>!RG2OQ zarH9D4ry)dBa9A#z%+9Dq%N8uUpC&K8&j5*YZjHH>f|@%Yxdl-6mMjfEC+c964m-m zzQ{{RxIOvyZLYzKyc#ACe3=l$hc>ppwe6Tnt55E1p5&T%7Oe;#w+g{4=U0R-l!-BN z8wciU1G_we95^WC?k%R+SAj(oM-jU0D!lrD#nNC52-UN)ANllE-mOZY!NNl|xm5Ks z+4%c{*gz%A!*)7V_sDE=WhQ(zsZ5B7p!~`$)`PE=ip5FmtDqb!CfdK9FcW%y2qH+y zCBhJMzoKK)b|fo1onKD>w%0*5gnuqZLcZpHTlY6NRNYF0Y%vgaoUrRR0nD$tzJ(pr ziF(*xFG!2^XHnE~f+Q`?LtZ>f7fUKFindJAN#BbIqLqn&(1dJ<)eA`O&zHq3RKVDu zoxn8gN%3z(>kb;IRB)WS=BElg$Q?v-`1Gejnt1$xR>;&Rj&};=Sj~v(Kp}JccZl|bMAu`nn9??l$BL?!Q+|H;10(Ec?v>~a4ZlqQOp zaM`vE7Q(t+kBSCj)|4i9@aH!*NyJRkd>$c`P)P)0jr{#|V=9l0ft-~mtUY~cfcx@`25?z4!jSYK^C8|k z%AXp!$`M>;vlnO-px2Z5tWK?Gi{pJ;ujC=OtZ~4ANgIM&^0VXaaC+*uq?m`TSy_JL7jp1ZZrOCt%t7BgLW!p~#C58i(l znsYb{Jg6@|sR*lO{oS&iNwTywWPfjwAQIP4Lf;9zJ1QF&R)0zE0G%tY`Y_`a)#$GO z0$DPxqXSm){}Z+gK=%JTs@Ll38lO7GhlB92B@pga4HCUT)YgCE#02yIo!GL$oskC# zPtOeIA+x>$G04=vixu>4mJ9q(II*&S3k)-j|L>%-=l8YdI!faM5&XNvxAKEDQKzMG zL5qffqybhWcqt_QiJczv7~{+Hg+7C-Z*o3cNHWy$DwPX>pIt9CWr+@*#i@lOmuLf9 zw6EcCjP(Bu`=ZS|Ec!zx_0~~$9#8dgVZ}{fs;YRj`>~_-)Eth$t8R$j!KBujWC-6*Ax>D6!JhcNHS zV@!ZU^8sDZ!^g*}y@G;>+sx$QoZ&~mp4G&ZBvQM600J#0&5_qe6XD)vHEK-WBg-fF za7M#+*scmL`jh_?0+vQSz1ZxX)?&KG$>kR>0Jb2MtBcGRN^hoSNi>3oC%dk(419}G6-LoFy|0HEN-NCB z0KHSK>9a;{{)Gbe2Bd%~iOkg2J)|CZ}H5|d%7ABuk%Zo!1_zwY|&Ps+qdui?4TvWnnh3``61p%A~v?HJ$pfT%w zbeBk&6fvKZlUd_;5+{m9X`(|FOsX8S3>S5(o;h38QY_GJ8y0junR|-^*1xWh)C}AZ z^dSTi8PsnoR3;I={BbT(o{}EFLAUWHgLE76*RN2+Bv+%bvbnxG(%zvE@?Sw?$;DKS$GlF~o*@hqbaFiq0xgj( zeZ=o>X;G9YHp_fXb%RZ`@Isy4$&m#FxcaXVI8(-(qXn| zie0#mlq#%JhO=*$zuY7`4EQbFEn6Vr&Mt6LzZKP+%9qsZ#pC!OCCrFPda^C1w8B)m zy-zOHhh!(LC^Zm17JE-7j6ru&CR^9KRX)sKdOQRfk!=cRD_@yUJ2MHg|APu{r?#a|JA4%vv9E^NG1~n%^XHp@e|}pAXR-~VpXkEz^)by za)$&M`~U~Iphbq$muTjnWhJZl81}}rw||2J)VU2kF>vf$y&bc(Vgn9Fzar>p>>!MI zdIKH@A-Ho?321wbB1C?;t9i$8IVWMzaDq;hA4?@G0PSt^1g8M6YFQDgZvEC-y2qp!*5rPS`m%o+k9mrA z60WBU)0F=Mb2(aq4K`PmFNh%kbOsn6a?)RXHY+6L9R}y8g!9}BSU75wpqfw&au0ze z3aSiae!&~^7-3aSk6HLVj*I|^Z>8MB1jA3nP^y(I6(N2={D7F?=NJj(H{yatNTfz4 zz^tb3w{qaDyA%(F{h+ncoP6X}QDGUY*7F2Z?<8miHz10@e^3;Cfq${6X<)g12#U2p zuK5+0TdOaCrlXnAHc<{ceW2OSdFw8aSYzhvel;QLn5DsgZUUvp(`)oO_R-{&YmQ_q3Z8Zsa|u-_ef z-lFouw2k}vlM8j~77G?V1L5wx3y$ye9M=0X2kzi}=sN7>WARR3DyxcR)r*_%1SuB^{5m`){}3tnIEZS~SVp4^NiNj5`S?1TYo6uoueJofkjR^@{kL>W zM8W^6z81%aM;~xq)r@lh~eF zg9k8Q-dv&8>AW&EYVX5d?8<38K$WPgRwLgqhx9}Bh1@Cp>C{48ZdkBDi(#)-9_#Gq z!=ak02;@ALIBN`_>`V|QL%~yx4T8HalPV5OEX>8so)|2C`%u8+JtnUlpoz%9d8<#l zW@-0(aBXVfkN&Z|ZiKE*2xoXyH)}M|!LU3%{;(IpT;F6e!e!h)KJ;NFYtD2^ z@-%;VDLaJvaG46Q3Qc_XcDHlySl3FBk;*b59ho4)!jROTE-yx#WL4AIyh8spgNU)5 z(fZZ96&eCJFML97wDcu+RD4M{;7A z56@vb{il|Bzl_6C1|_xgpLnT@SpSDfb!(=0WX5~IJB(fThp{}KF1NEXtk0;HqGhb2b1sG}y6R-D565!WH#5&n=cneFNA zE%O>u>=4k_5xZ^UcEDRdFGVigf2;%_FxwIPWRf8*EhOHfp`|5DNwZ3zekM`jjb%KvWOR{oGuex(#%-d7hi~)r2fuE%F9%Fu>RU`>Mr-rN`lt& zj5)oFy$pU?9-xf^eYI;crgIq6>j+&4Dl-$Lm1ThdG7v-N&zuII6Ot8{ zr-#aXW2MNL2Ib()=_tfH4}m?0ng=@2Ie2OuWGbJ676ex*aKrF0-x}t$-i9}Ls@>2$0$Wx^VJ~ZK#QUg#@gTh-h}L7ooL;S^uIYT@ zrmXe5tXjxndH-yI(+ZTs^FHzJ+-4P530TGNAL^fgr~%X)>GBJlTRHDLIGu~>lYz@x zTB-5IELiXD0ibtr2>iJwcC<#S^hp|AE&-A>-a~QIlvmOvcV45u?D62x<2#BzLTi2W zXY1Rf%Q~y_Z}eHPC~RYj_Hau}iy3P|FjzLaCf#3om%k{8uk-&sKD+h6<3PA>hQe#h zzkeLR0>GQ4_lo_Y`y%dEaPCvfh`+PT#v*9f?#TM?5D$E}<6BgQc*wio5&M6ae-(d` z{yQn~cx~W=3{l5#v`c&bY@Rx$enxZOP5=2q>#MZuLRSOeLAc^hmblgmsk+je!m6XK zo`7|6O|GXyE;zIUJ@&86mjnY2tUiGcP{f*Eg!=%skUthKaKH5{@1&ytbP@k0w{+`b zDs=mv+%uSx>N8)&yY=@L=~wqJDIt=66{dyf^X>L2vnLlscYOD`{Pc10 zh12%?8V-;67o0e1eoS(97qM+*W*5~~ge2nI)SaO4f%@d_w1q>K7lo9)#>y~<%S!GK z>WE!gG6!sX93|q@$E@Pdv<{`9-J>UO9 zg`tk2|GcYTZv9> z)0x2?&hd-wJ3Xgc$93Iv`u9a4)wqUh?yJv_IKDx9It#)>)9Ck9-wjNAn2y4w7zOC; z`F&KHH*lsm>GZKwO3|4g^y09QFry!)r(?v9?4{(}=l!L-#<9l|hVteI0w!I8k9HCl zBz!Z^%v@(m6s!FmkW!SH1DP|zoI~#gUTzC5? z>yvbq_459x;vfY&WQ1<`w5+uI!B4b z3WO>HJ-amVnSH1%y}C~Ih0EgQn{Ny5+<0S&>(iLN{6^`veaJugmd`@@LdEC9aL%~S zL$KB8M0HN(pTBYzL!NZ_i!LUt>ECDScS&X@I5!r0?$Ni>Yx5t0O&wR)bqZdX!eG_) zWEt52eJIaA1vs(rH^Ux1fcj>GeyLu?<>$U8NeAL_ZmtbcA*tH&1yV)7y?RSrF&Iiz z<%~!T5R3n)G+!lXl;VcAsb1Kwi1+d7@wKqz?x;-W#?~I#hr_Eh211t7hTb!3It
    V$vjf<432&GIAe`0mGiR1 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

    eAinjt?(i;6^FR&iHUN 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 diff --git a/arm-virt-Correct-timing-of-executing-cpu_synchronize.patch b/arm-virt-Correct-timing-of-executing-cpu_synchronize.patch new file mode 100644 index 0000000..b89aadb --- /dev/null +++ b/arm-virt-Correct-timing-of-executing-cpu_synchronize.patch @@ -0,0 +1,52 @@ +From c3f86c199885506cfddde0dfc235c04e0897d591 Mon Sep 17 00:00:00 2001 +From: Kunkun Jiang +Date: Tue, 14 Feb 2023 20:33:40 +0800 +Subject: [PATCH] arm/virt: Correct timing of executing + cpu_synchronize_post_init for hot-plugged cpus + +When the CPU starts normally, cpu_synchronize_post_init is executed +after GICv3 is implemented. This order should be followed when dealing +with hot-plugged CPUs. + +Signed-off-by: Kunkun Jiang +--- + hw/arm/virt.c | 1 + + hw/core/cpu-common.c | 6 ++---- + 2 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 4716f9baaa..7d5b332594 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -2798,6 +2798,7 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev, + } + + /* Register CPU reset and trigger it manually */ ++ cpu_synchronize_post_init(cs); + cpu_synchronize_state(cs); + cpu_hotplug_register_reset(ncpu); + cpu_hotplug_reset_manually(ncpu); +diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c +index b8d1d820cb..2213840260 100644 +--- a/hw/core/cpu-common.c ++++ b/hw/core/cpu-common.c +@@ -206,14 +206,12 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp) + } + } + ++#ifdef __aarch64__ + if (dev->hotplugged) { + cpu_synchronize_post_init(cpu); +- +-#ifdef __aarch64__ +- if (!kvm_enabled()) +-#endif + cpu_resume(cpu); + } ++#endif + + /* NOTE: latest generic point where the cpu is fully realized */ + trace_init_vcpu(cpu); +-- +2.27.0 + diff --git a/arm-virt-Correct-timing-of-pause-all-vcpus-for-hot-p.patch b/arm-virt-Correct-timing-of-pause-all-vcpus-for-hot-p.patch new file mode 100644 index 0000000..817c125 --- /dev/null +++ b/arm-virt-Correct-timing-of-pause-all-vcpus-for-hot-p.patch @@ -0,0 +1,58 @@ +From 41f30679648676d4d62b1ae9026dde77fa9895d5 Mon Sep 17 00:00:00 2001 +From: Kunkun Jiang +Date: Tue, 14 Feb 2023 20:39:07 +0800 +Subject: [PATCH] arm/virt: Correct timing of pause all vcpus for hot-plugged + CPUs + +When dealing with hot-plugging cpus, it may fail when realize cpu. +Such a failure would make paused vcpus unrecoverable. So we only +pause all vcpus when needed. Add removed some unnecessary checks. + +Signed-off-by: Kunkun Jiang +--- + hw/arm/virt.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 7d5b332594..4c876fcf16 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -2747,13 +2747,6 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, + &error_abort); + } + } +- +- /* If we use KVM accel, we should pause all vcpus to +- * allow hot access of vcpu registers. +- */ +- if (dev->hotplugged && kvm_enabled()) { +- pause_all_vcpus(); +- } + } + + static void virt_cpu_plug(HotplugHandler *hotplug_dev, +@@ -2773,6 +2766,10 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev, + + /* For CPU that is cold/hot plugged */ + if (ncpu >= ms->smp.cpus) { ++ if (dev->hotplugged) { ++ pause_all_vcpus(); ++ } ++ + /* Realize GIC related parts of CPU */ + assert(vms->gic_version == 3); + gicv3 = ARM_GICV3_COMMON(vms->gic); +@@ -2803,6 +2800,10 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev, + cpu_hotplug_register_reset(ncpu); + cpu_hotplug_reset_manually(ncpu); + cpu_synchronize_post_reset(cs); ++ ++ if (dev->hotplugged) { ++ resume_all_vcpus(); ++ } + } + + if (dev->hotplugged && kvm_enabled()) { +-- +2.27.0 + diff --git a/block-backend-prevent-dangling-BDS-pointers-across-a.patch b/block-backend-prevent-dangling-BDS-pointers-across-a.patch new file mode 100644 index 0000000..9ffabfd --- /dev/null +++ b/block-backend-prevent-dangling-BDS-pointers-across-a.patch @@ -0,0 +1,124 @@ +From 6363172843fd756c61d6a3725ad5b3a385eddc87 Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Tue, 21 Mar 2023 03:02:58 +0000 +Subject: [PATCH] block-backend: prevent dangling BDS pointers across + aio_poll() mainline inclusion commit 1e3552dbd28359d35967b7c28dc86cde1bc29205 + category: bugfix + +--------------------------------------------------------------- + +The BlockBackend root child can change when aio_poll() is invoked. This +happens when a temporary filter node is removed upon blockjob +completion, for example. + +Functions in block/block-backend.c must be aware of this when using a +blk_bs() pointer across aio_poll() because the BlockDriverState refcnt +may reach 0, resulting in a stale pointer. + +One example is scsi_device_purge_requests(), which calls blk_drain() to +wait for in-flight requests to cancel. If the backup blockjob is active, +then the BlockBackend root child is a temporary filter BDS owned by the +blockjob. The blockjob can complete during bdrv_drained_begin() and the +last reference to the BDS is released when the temporary filter node is +removed. This results in a use-after-free when blk_drain() calls +bdrv_drained_end(bs) on the dangling pointer. + +Explicitly hold a reference to bs across block APIs that invoke +aio_poll(). + +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2021778 +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2036178 +Signed-off-by: Stefan Hajnoczi +Message-Id: <20220111153613.25453-2-stefanha@redhat.com> +Signed-off-by: Kevin Wolf + +Signed-off-by: tangbinzy +--- + block/block-backend.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 49d236b2a4..3a757fb746 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -840,16 +840,22 @@ BlockBackend *blk_by_public(BlockBackendPublic *public) + void blk_remove_bs(BlockBackend *blk) + { + ThrottleGroupMember *tgm = &blk->public.throttle_group_member; +- BlockDriverState *bs; + BdrvChild *root; + + notifier_list_notify(&blk->remove_bs_notifiers, blk); + if (tgm->throttle_state) { +- bs = blk_bs(blk); ++ BlockDriverState *bs = blk_bs(blk); ++ ++ /* ++ * Take a ref in case blk_bs() changes across bdrv_drained_begin(), for ++ * example, if a temporary filter node is removed by a blockjob. ++ */ ++ bdrv_ref(bs); + bdrv_drained_begin(bs); + throttle_group_detach_aio_context(tgm); + throttle_group_attach_aio_context(tgm, qemu_get_aio_context()); + bdrv_drained_end(bs); ++ bdrv_unref(bs); + } + + blk_update_root_state(blk); +@@ -1731,6 +1737,7 @@ void blk_drain(BlockBackend *blk) + BlockDriverState *bs = blk_bs(blk); + + if (bs) { ++ bdrv_ref(bs); + bdrv_drained_begin(bs); + } + +@@ -1740,6 +1747,7 @@ void blk_drain(BlockBackend *blk) + + if (bs) { + bdrv_drained_end(bs); ++ bdrv_unref(bs); + } + } + +@@ -2112,10 +2120,13 @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, + int ret; + + if (bs) { ++ bdrv_ref(bs); ++ + if (update_root_node) { + ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root, + errp); + if (ret < 0) { ++ bdrv_unref(bs); + return ret; + } + } +@@ -2125,6 +2136,8 @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, + throttle_group_attach_aio_context(tgm, new_context); + bdrv_drained_end(bs); + } ++ ++ bdrv_unref(bs); + } + + blk->ctx = new_context; +@@ -2394,11 +2407,13 @@ void blk_io_limits_disable(BlockBackend *blk) + ThrottleGroupMember *tgm = &blk->public.throttle_group_member; + assert(tgm->throttle_state); + if (bs) { ++ bdrv_ref(bs); + bdrv_drained_begin(bs); + } + throttle_group_unregister_tgm(tgm); + if (bs) { + bdrv_drained_end(bs); ++ bdrv_unref(bs); + } + } + +-- +2.27.0 + diff --git a/curl-Fix-error-path-in-curl_open.patch b/curl-Fix-error-path-in-curl_open.patch new file mode 100644 index 0000000..215bd7a --- /dev/null +++ b/curl-Fix-error-path-in-curl_open.patch @@ -0,0 +1,48 @@ +From 745dd52e9a737f2d1e16fdc79b0f701d63df3606 Mon Sep 17 00:00:00 2001 +From: jianchunfu +Date: Thu, 16 Mar 2023 16:20:44 +0800 +Subject: [PATCH] curl: Fix error path in curl_open() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +g_hash_table_destroy() and g_hash_table_foreach_remove() (called by +curl_drop_all_sockets()) both require the table to be non-NULL, or will +print assertion failures (just print, no abort). +There are several paths in curl_open() that can lead to the out_noclean +label without s->sockets being allocated, so clean it only if it has +been allocated. +Example reproducer: +$ qemu-img info -f http '' +qemu-img: GLib: g_hash_table_foreach_remove: assertion 'hash_table != NULL' failed +qemu-img: GLib: g_hash_table_destroy: assertion 'hash_table != NULL' failed +qemu-img: Could not open '': http curl driver cannot handle the URL '' (does not start with 'http://') + +Closes: https://gitlab.com/qemu-project/qemu/-/issues/1475 +Suggested-by: Daniel P. Berrangé +Signed-off-by: Hanna Czenczek +Signed-off-by: jianchunfu +--- + block/curl.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/block/curl.c b/block/curl.c +index 4a8ae2b269..5aebb08002 100644 +--- a/block/curl.c ++++ b/block/curl.c +@@ -821,8 +821,10 @@ out_noclean: + g_free(s->username); + g_free(s->proxyusername); + g_free(s->proxypassword); +- curl_drop_all_sockets(s->sockets); +- g_hash_table_destroy(s->sockets); ++ if (s->sockets) { ++ curl_drop_all_sockets(s->sockets); ++ g_hash_table_destroy(s->sockets); ++ } + qemu_opts_del(opts); + return -EINVAL; + } +-- +2.27.0 + diff --git a/dsoundaudio-fix-crackling-audio-recordings.patch b/dsoundaudio-fix-crackling-audio-recordings.patch new file mode 100644 index 0000000..a697ca8 --- /dev/null +++ b/dsoundaudio-fix-crackling-audio-recordings.patch @@ -0,0 +1,62 @@ +From b1985a8f51ce0496aa4e8802c42a64b90f1f891d Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Tue, 21 Mar 2023 02:50:07 +0000 +Subject: [PATCH] dsoundaudio: fix crackling audio recordings mainline + inclusion commit 9d90ceb27461d7d0d172fd941b812d511794a6c6 category: bugfix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--------------------------------------------------------------- + +Audio recordings with the DirectSound backend don't sound right. +A look a the Microsoft online documentation tells us why. + +From the DirectSound Programming Guide, Capture Buffer Information: +'You can safely copy data from the buffer only up to the read +cursor.' + +Change the code to read up to the read cursor instead of the +capture cursor. + +Signed-off-by: Volker Rümelin +Message-Id: <20211226154017.6067-2-vr_qemu@t-online.de> +Signed-off-by: Gerd Hoffmann + +Signed-off-by: tangbinzy +--- + audio/dsoundaudio.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c +index cfc79c129e..3dd2c4d4a6 100644 +--- a/audio/dsoundaudio.c ++++ b/audio/dsoundaudio.c +@@ -536,13 +536,12 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size) + DSoundVoiceIn *ds = (DSoundVoiceIn *) hw; + LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer; + HRESULT hr; +- DWORD cpos, rpos, act_size; ++ DWORD rpos, act_size; + size_t req_size; + int err; + void *ret; + +- hr = IDirectSoundCaptureBuffer_GetCurrentPosition( +- dscb, &cpos, ds->first_time ? &rpos : NULL); ++ hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dscb, NULL, &rpos); + if (FAILED(hr)) { + dsound_logerr(hr, "Could not get capture buffer position\n"); + *size = 0; +@@ -554,7 +553,7 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size) + ds->first_time = false; + } + +- req_size = audio_ring_dist(cpos, hw->pos_emul, hw->size_emul); ++ req_size = audio_ring_dist(rpos, hw->pos_emul, hw->size_emul); + req_size = MIN(*size, MIN(req_size, hw->size_emul - hw->pos_emul)); + + if (req_size == 0) { +-- +2.27.0 + diff --git a/fix-qmp-command-migrate-set-parameters.patch b/fix-qmp-command-migrate-set-parameters.patch new file mode 100644 index 0000000..ab7fb31 --- /dev/null +++ b/fix-qmp-command-migrate-set-parameters.patch @@ -0,0 +1,31 @@ +From 05526b64c8201bb7395927a81ceef3723c1ce57e Mon Sep 17 00:00:00 2001 +From: mayunlong +Date: Fri, 23 Dec 2022 10:43:46 +0800 +Subject: [PATCH] fix qmp command migrate-set-parameters + +params didn't apply after excute qmp command migrate-set-parameters, +this resulted in another qmp command(query-migrate-parameters) error. + +Signed-off-by:mayunlong +--- + migration/migration.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/migration/migration.c b/migration/migration.c +index 33d5832e47..2ec116f901 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1621,6 +1621,10 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp) + s->parameters.decompress_threads = params->decompress_threads; + } + ++ if (params->has_compress_method) { ++ s->parameters.compress_method = params->compress_method; ++ } ++ + if (params->has_throttle_trigger_threshold) { + s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold; + } +-- +2.27.0 + diff --git a/hw-acpi-Add-ospm_status-hook-implementation-for-acpi.patch b/hw-acpi-Add-ospm_status-hook-implementation-for-acpi.patch new file mode 100644 index 0000000..8d917c6 --- /dev/null +++ b/hw-acpi-Add-ospm_status-hook-implementation-for-acpi.patch @@ -0,0 +1,60 @@ +From fa15ed1690bbfd95e2df6efafcb034198e9b637a Mon Sep 17 00:00:00 2001 +From: Keqian Zhu +Date: Tue, 16 Aug 2022 17:49:57 +0800 +Subject: [PATCH] hw/acpi: Add ospm_status hook implementation for acpi-ged + +Setup an ARM virtual machine of machine virt and execute qmp "query-acpi-ospm-status" +causes segmentation fault with following dumpstack: + #1 0x0000aaaaab64235c in qmp_query_acpi_ospm_status (errp=errp@entry=0xfffffffff030) at ../monitor/qmp-cmds.c:312 + #2 0x0000aaaaabfc4e20 in qmp_marshal_query_acpi_ospm_status (args=, ret=0xffffea4ffe90, errp=0xffffea4ffe88) at qapi/qapi-commands-acpi.c:63 + #3 0x0000aaaaabff8ba0 in do_qmp_dispatch_bh (opaque=0xffffea4ffe98) at ../qapi/qmp-dispatch.c:128 + #4 0x0000aaaaac02e594 in aio_bh_call (bh=0xffffe0004d80) at ../util/async.c:150 + #5 aio_bh_poll (ctx=ctx@entry=0xaaaaad0f6040) at ../util/async.c:178 + #6 0x0000aaaaac00bd40 in aio_dispatch (ctx=ctx@entry=0xaaaaad0f6040) at ../util/aio-posix.c:421 + #7 0x0000aaaaac02e010 in aio_ctx_dispatch (source=0xaaaaad0f6040, callback=, user_data=) at ../util/async.c:320 + #8 0x0000fffff76f6884 in g_main_context_dispatch () at /usr/lib64/libglib-2.0.so.0 + #9 0x0000aaaaac0452d4 in glib_pollfds_poll () at ../util/main-loop.c:297 + #10 os_host_main_loop_wait (timeout=0) at ../util/main-loop.c:320 + #11 main_loop_wait (nonblocking=nonblocking@entry=0) at ../util/main-loop.c:596 + #12 0x0000aaaaab5c9e50 in qemu_main_loop () at ../softmmu/runstate.c:734 + #13 0x0000aaaaab185370 in qemu_main (argc=argc@entry=47, argv=argv@entry=0xfffffffff518, envp=envp@entry=0x0) at ../softmmu/main.c:38 + #14 0x0000aaaaab16f99c in main (argc=47, argv=0xfffffffff518) at ../softmmu/main.c:47 + +Fixes: ebb62075021a ("hw/acpi: Add ACPI Generic Event Device Support") +Signed-off-by: Keqian Zhu +Reviewed-by: Igor Mammedov +Message-id: 20220816094957.31700-1-zhukeqian1@huawei.com +Signed-off-by: Peter Maydell +--- + hw/acpi/generic_event_device.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c +index 042a8ef8a5..53e9112d9f 100644 +--- a/hw/acpi/generic_event_device.c ++++ b/hw/acpi/generic_event_device.c +@@ -273,6 +273,13 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev, + } + } + ++static void acpi_ged_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) ++{ ++ AcpiGedState *s = ACPI_GED(adev); ++ ++ acpi_memory_ospm_status(&s->memhp_state, list); ++} ++ + static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev) + { + AcpiGedState *s = ACPI_GED(adev); +@@ -444,6 +451,7 @@ static void acpi_ged_class_init(ObjectClass *class, void *data) + hc->unplug_request = acpi_ged_unplug_request_cb; + hc->unplug = acpi_ged_unplug_cb; + ++ adevc->ospm_status = acpi_ged_ospm_status; + adevc->send_event = acpi_ged_send_event; + } + +-- +2.27.0 + diff --git a/hw-acpi-Support-acpi-ged-to-report-CPU-s-OST-info.patch b/hw-acpi-Support-acpi-ged-to-report-CPU-s-OST-info.patch new file mode 100644 index 0000000..4b48446 --- /dev/null +++ b/hw-acpi-Support-acpi-ged-to-report-CPU-s-OST-info.patch @@ -0,0 +1,28 @@ +From 9e8ccc2a868e719233a34946106859461c057ade Mon Sep 17 00:00:00 2001 +From: Kunkun Jiang +Date: Tue, 14 Feb 2023 20:28:11 +0800 +Subject: [PATCH] hw/acpi: Support acpi-ged to report CPU's OST info + +Setup an ARM virtual machine of machine virt and execute qmp +"query-acpi-ospm-status" but can not get the CPU's OST info. + +Signed-off-by: Kunkun Jiang +--- + hw/acpi/generic_event_device.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c +index 53e9112d9f..9118681662 100644 +--- a/hw/acpi/generic_event_device.c ++++ b/hw/acpi/generic_event_device.c +@@ -278,6 +278,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) + AcpiGedState *s = ACPI_GED(adev); + + acpi_memory_ospm_status(&s->memhp_state, list); ++ acpi_cpu_ospm_status(&s->cpuhp_state, list); + } + + static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev) +-- +2.27.0 + diff --git a/hw-audio-intel-hda-fix-stream-reset.patch b/hw-audio-intel-hda-fix-stream-reset.patch new file mode 100644 index 0000000..ef80b5d --- /dev/null +++ b/hw-audio-intel-hda-fix-stream-reset.patch @@ -0,0 +1,47 @@ +From b42ad03f9e1fcdd7cac13789038621173f754294 Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Tue, 21 Mar 2023 02:38:36 +0000 +Subject: [PATCH] hw/audio/intel-hda: fix stream reset mainline inclusion + commit ecd5f2882fdd10f798984eb52abd00ffc78c2ef7 category: bugfix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--------------------------------------------------------------- + +Quote from: +High Definition Audio Specification 1.0a, section 3.3.35 + +Offset 80: {IOB}SDnCTL Stream Reset (SRST): Writing a 1 causes +the corresponding stream to be reset. The Stream Descriptor +registers (except the SRST bit itself) ... are reset. + +Change the code to reset the Stream Descriptor Control and Status +registers except the SRST bit. + +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/757 +Signed-off-by: Volker Rümelin +Message-Id: <20211226154017.6067-3-vr_qemu@t-online.de> +Signed-off-by: Gerd Hoffmann + +Signed-off-by: tangbinzy +--- + hw/audio/intel-hda.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c +index 3aa57d274e..78a47bc08c 100644 +--- a/hw/audio/intel-hda.c ++++ b/hw/audio/intel-hda.c +@@ -586,7 +586,7 @@ static void intel_hda_set_st_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint3 + if (st->ctl & 0x01) { + /* reset */ + dprint(d, 1, "st #%d: reset\n", reg->stream); +- st->ctl = SD_STS_FIFO_READY << 24; ++ st->ctl = SD_STS_FIFO_READY << 24 | SD_CTL_STREAM_RESET; + } + if ((st->ctl & 0x02) != (old & 0x02)) { + uint32_t stnr = (st->ctl >> 20) & 0x0f; +-- +2.27.0 + diff --git a/hw-core-machine-Fix-the-missing-consideration-of-clu.patch b/hw-core-machine-Fix-the-missing-consideration-of-clu.patch new file mode 100644 index 0000000..5adcd2b --- /dev/null +++ b/hw-core-machine-Fix-the-missing-consideration-of-clu.patch @@ -0,0 +1,85 @@ +From bbf1fc67fb642833a23793081e812c36691c4df6 Mon Sep 17 00:00:00 2001 +From: Yanan Wang +Date: Mon, 6 Mar 2023 20:50:33 +0800 +Subject: [PATCH] hw/core/machine:Fix the missing consideration of cluster-id + +Commit 5454c00908236 introduced the cluster-id for CPU +topology parameter "cluster", but has not fully considered +all the areas where we need to check cluster-id, e.g, when +assigning CPUs to numa nodes. + +If we have multiple clusters and multiple numa nodes for +a guest like below: +-smp cpus=8,maxcpus=8,sockets=1,dies=1,clusters=2,cores=4,threads=1 +-numa node nodeid=0,cpus=0-3 +-numa node nodeid=1,cpus=4-7 +QEMU will wrongly assign all the CPUs to numa0, because there +is no check about cluster_id of each CPU in function +machine_set_cpu_numa_node. Fix it. + +Also, fix some other areas which missed to verified cluster-id. + +Fixes: 5454c00908236 ("arm/virt: Add CPU topology support") +Signed-off-by: Yanan Wang +--- + hw/core/machine-hmp-cmds.c | 3 +++ + hw/core/machine.c | 15 +++++++++++++++ + 2 files changed, 18 insertions(+) + +diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c +index 4e2f319aeb..c4f63b1d63 100644 +--- a/hw/core/machine-hmp-cmds.c ++++ b/hw/core/machine-hmp-cmds.c +@@ -77,6 +77,9 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict) + if (c->has_die_id) { + monitor_printf(mon, " die-id: \"%" PRIu64 "\"\n", c->die_id); + } ++ if (c->has_cluster_id) { ++ monitor_printf(mon, " cluster-id: \"%" PRIu64 "\"\n", c->cluster_id); ++ } + if (c->has_core_id) { + monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id); + } +diff --git a/hw/core/machine.c b/hw/core/machine.c +index 45fb0fd2eb..cb539104a1 100644 +--- a/hw/core/machine.c ++++ b/hw/core/machine.c +@@ -686,6 +686,11 @@ void machine_set_cpu_numa_node(MachineState *machine, + return; + } + ++ if (props->has_cluster_id && !slot->props.has_cluster_id) { ++ error_setg(errp, "cluster-id is not supported"); ++ return; ++ } ++ + /* skip slots with explicit mismatch */ + if (props->has_thread_id && props->thread_id != slot->props.thread_id) { + continue; +@@ -695,6 +700,10 @@ void machine_set_cpu_numa_node(MachineState *machine, + continue; + } + ++ if (props->has_cluster_id && props->cluster_id != slot->props.cluster_id) { ++ continue; ++ } ++ + if (props->has_die_id && props->die_id != slot->props.die_id) { + continue; + } +@@ -989,6 +998,12 @@ static char *cpu_slot_to_string(const CPUArchId *cpu) + } + g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id); + } ++ if (cpu->props.has_cluster_id) { ++ if (s->len) { ++ g_string_append_printf(s, ", "); ++ } ++ g_string_append_printf(s, "cluster-id: %"PRId64, cpu->props.cluster_id); ++ } + if (cpu->props.has_core_id) { + if (s->len) { + g_string_append_printf(s, ", "); +-- +2.27.0 + diff --git a/hw-net-vmxnet3-Log-guest-triggerable-errors-using-LO.patch b/hw-net-vmxnet3-Log-guest-triggerable-errors-using-LO.patch new file mode 100644 index 0000000..90631fb --- /dev/null +++ b/hw-net-vmxnet3-Log-guest-triggerable-errors-using-LO.patch @@ -0,0 +1,64 @@ +From ad2660c287ff03d0190eff5f841452e618d368ff Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Fri, 24 Mar 2023 07:16:21 +0000 +Subject: [PATCH] hw/net/vmxnet3: Log guest-triggerable errors using + LOG_GUEST_ERROR mainline inclusion commit + f3e5a17593b972a9a6079ccf7677b4389d74d5a1 category: bugfix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--------------------------------------------------------------- + +The "Interrupt Cause" register (VMXNET3_REG_ICR) is read-only. +Write accesses are ignored. Log them with as LOG_GUEST_ERROR +instead of aborting: + + [R +0.239743] writeq 0xe0002031 0x46291a5a55460800 + ERROR:hw/net/vmxnet3.c:1819:vmxnet3_io_bar1_write: code should not be reached + Thread 1 "qemu-system-i38" received signal SIGABRT, Aborted. + (gdb) bt + #3 0x74c397d3 in __GI_abort () at abort.c:79 + #4 0x76d3cd4c in g_assertion_message (domain=, file=, line=, func=, message=) at ../glib/gtestutils.c:3223 + #5 0x76d9d45f in g_assertion_message_expr + (domain=0x0, file=0x59fc2e53 "hw/net/vmxnet3.c", line=1819, func=0x59fc11e0 <__func__.vmxnet3_io_bar1_write> "vmxnet3_io_bar1_write", expr=) + at ../glib/gtestutils.c:3249 + #6 0x57e80a3a in vmxnet3_io_bar1_write (opaque=0x62814100, addr=56, val=70, size=4) at hw/net/vmxnet3.c:1819 + #7 0x58c2d894 in memory_region_write_accessor (mr=0x62816b90, addr=56, value=0x7fff9450, size=4, shift=0, mask=4294967295, attrs=...) at softmmu/memory.c:492 + #8 0x58c2d1d2 in access_with_adjusted_size (addr=56, value=0x7fff9450, size=1, access_size_min=4, access_size_max=4, access_fn= + 0x58c2d290 , mr=0x62816b90, attrs=...) at softmmu/memory.c:554 + #9 0x58c2bae7 in memory_region_dispatch_write (mr=0x62816b90, addr=56, data=70, op=MO_8, attrs=...) at softmmu/memory.c:1504 + #10 0x58bfd034 in flatview_write_continue (fv=0x606000181700, addr=0xe0002038, attrs=..., ptr=0x7fffb9e0, len=1, addr1=56, l=1, mr=0x62816b90) + at softmmu/physmem.c:2782 + #11 0x58beba00 in flatview_write (fv=0x606000181700, addr=0xe0002031, attrs=..., buf=0x7fffb9e0, len=8) at softmmu/physmem.c:2822 + #12 0x58beb589 in address_space_write (as=0x608000015f20, addr=0xe0002031, attrs=..., buf=0x7fffb9e0, len=8) at softmmu/physmem.c:2914 + +Reported-by: Dike +Reported-by: Duhao <504224090@qq.com> +BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=2032932 +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: Jason Wang + +Signed-off-by: tangbinzy +--- + hw/net/vmxnet3.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c +index f65af4e9ef..0b7acf7f89 100644 +--- a/hw/net/vmxnet3.c ++++ b/hw/net/vmxnet3.c +@@ -1816,7 +1816,9 @@ vmxnet3_io_bar1_write(void *opaque, + case VMXNET3_REG_ICR: + VMW_CBPRN("Write BAR1 [VMXNET3_REG_ICR] = %" PRIx64 ", size %d", + val, size); +- g_assert_not_reached(); ++ qemu_log_mask(LOG_GUEST_ERROR, ++ "%s: write to read-only register VMXNET3_REG_ICR\n", ++ TYPE_VMXNET3); + break; + + /* Event Cause Register */ +-- +2.27.0 + diff --git a/hw-pci-Fix-a-typo.patch b/hw-pci-Fix-a-typo.patch new file mode 100644 index 0000000..7ecad41 --- /dev/null +++ b/hw-pci-Fix-a-typo.patch @@ -0,0 +1,32 @@ +From c7fe3321e6abb3502a7d4366c9fdbe690bfa9ea9 Mon Sep 17 00:00:00 2001 +From: jianchunfu +Date: Fri, 17 Mar 2023 11:04:01 +0800 +Subject: [PATCH] hw/pci: Fix a typo +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix 'interrutp' typo. + +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: jianchunfu +--- + hw/pci/pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/pci/pci.c b/hw/pci/pci.c +index 0743dc7c42..b89c36ab80 100644 +--- a/hw/pci/pci.c ++++ b/hw/pci/pci.c +@@ -1579,7 +1579,7 @@ void pci_device_set_intx_routing_notifier(PCIDevice *dev, + * 9.1: Interrupt routing. Table 9-1 + * + * the PCI Express Base Specification, Revision 2.1 +- * 2.2.8.1: INTx interrutp signaling - Rules ++ * 2.2.8.1: INTx interrupt signaling - Rules + * the Implementation Note + * Table 2-20 + */ +-- +2.27.0 + diff --git a/hw-pci-Trace-IRQ-routing-on-PCI-topology.patch b/hw-pci-Trace-IRQ-routing-on-PCI-topology.patch new file mode 100644 index 0000000..873bfcd --- /dev/null +++ b/hw-pci-Trace-IRQ-routing-on-PCI-topology.patch @@ -0,0 +1,65 @@ +From b5e972454b1c4784c6b8e163016a237c084a1b46 Mon Sep 17 00:00:00 2001 +From: jianchunfu +Date: Fri, 17 Mar 2023 11:12:02 +0800 +Subject: [PATCH] hw/pci: Trace IRQ routing on PCI topology +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Trace how IRQ are rooted from EP to RC. + +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: jianchunfu +--- + hw/pci/pci.c | 8 ++++++++ + hw/pci/trace-events | 1 + + 2 files changed, 9 insertions(+) + +diff --git a/hw/pci/pci.c b/hw/pci/pci.c +index b89c36ab80..96dcc738f2 100644 +--- a/hw/pci/pci.c ++++ b/hw/pci/pci.c +@@ -269,11 +269,15 @@ static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change) + { + PCIBus *bus; + for (;;) { ++ int dev_irq = irq_num; + bus = pci_get_bus(pci_dev); + if (!bus) { + return; + } + irq_num = bus->map_irq(pci_dev, irq_num); ++ trace_pci_route_irq(dev_irq, DEVICE(pci_dev)->canonical_path, irq_num, ++ pci_bus_is_root(bus) ? "root-complex" ++ : DEVICE(bus->parent_dev)->canonical_path); + if (bus->set_irq) + break; + pci_dev = bus->parent_dev; +@@ -1531,8 +1535,12 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) + PCIBus *bus; + + do { ++ int dev_irq = pin; + bus = pci_get_bus(dev); + pin = bus->map_irq(dev, pin); ++ trace_pci_route_irq(dev_irq, DEVICE(dev)->canonical_path, pin, ++ pci_bus_is_root(bus) ? "root-complex" ++ : DEVICE(bus->parent_dev)->canonical_path); + dev = bus->parent_dev; + } while (dev); + +diff --git a/hw/pci/trace-events b/hw/pci/trace-events +index fc777d0b5e..7e294b7e8a 100644 +--- a/hw/pci/trace-events ++++ b/hw/pci/trace-events +@@ -3,6 +3,7 @@ + # pci.c + pci_update_mappings_del(void *d, uint32_t bus, uint32_t slot, uint32_t func, int bar, uint64_t addr, uint64_t size) "d=%p %02x:%02x.%x %d,0x%"PRIx64"+0x%"PRIx64 + pci_update_mappings_add(void *d, uint32_t bus, uint32_t slot, uint32_t func, int bar, uint64_t addr, uint64_t size) "d=%p %02x:%02x.%x %d,0x%"PRIx64"+0x%"PRIx64 ++pci_route_irq(int dev_irq, const char *dev_path, int parent_irq, const char *parent_path) "IRQ %d @%s -> IRQ %d @%s" + + # pci_host.c + pci_cfg_read(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x -> 0x%x" +-- +2.27.0 + diff --git a/hw-pvrdma-Protect-against-buggy-or-malicious-guest-d.patch b/hw-pvrdma-Protect-against-buggy-or-malicious-guest-d.patch new file mode 100644 index 0000000..07ca361 --- /dev/null +++ b/hw-pvrdma-Protect-against-buggy-or-malicious-guest-d.patch @@ -0,0 +1,42 @@ +From 38f8c09d9916e76d2907d68fbe69115aef3a5310 Mon Sep 17 00:00:00 2001 +From: Yuval Shaia +Date: Sun, 3 Apr 2022 12:52:34 +0300 +Subject: [PATCH] hw/pvrdma: Protect against buggy or malicious guest driver + +Guest driver might execute HW commands when shared buffers are not yet +allocated. +This could happen on purpose (malicious guest) or because of some other +guest/host address mapping error. +We need to protect againts such case. + +Fixes: CVE-2022-1050 + +Reported-by: Raven +Signed-off-by: Yuval Shaia +Message-Id: <20220403095234.2210-1-yuval.shaia.ml@gmail.com> +Signed-off-by: Laurent Vivier +Signed-off-by: liuxiangdong +--- + hw/rdma/vmw/pvrdma_cmd.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c +index da7ddfa548..89db963c46 100644 +--- a/hw/rdma/vmw/pvrdma_cmd.c ++++ b/hw/rdma/vmw/pvrdma_cmd.c +@@ -796,6 +796,12 @@ int pvrdma_exec_cmd(PVRDMADev *dev) + + dsr_info = &dev->dsr_info; + ++ if (!dsr_info->dsr) { ++ /* Buggy or malicious guest driver */ ++ rdma_error_report("Exec command without dsr, req or rsp buffers"); ++ goto out; ++ } ++ + if (dsr_info->req->hdr.cmd >= sizeof(cmd_handlers) / + sizeof(struct cmd_handler)) { + rdma_error_report("Unsupported command"); +-- +2.27.0 + diff --git a/hw-riscv-virt-Simplify-virt_-get-set-_aclint.patch b/hw-riscv-virt-Simplify-virt_-get-set-_aclint.patch new file mode 100644 index 0000000..caa2cc1 --- /dev/null +++ b/hw-riscv-virt-Simplify-virt_-get-set-_aclint.patch @@ -0,0 +1,39 @@ +From 612fe39ec96f7171501dd3b86af7ca2d9a8efbfe Mon Sep 17 00:00:00 2001 +From: jianchunfu +Date: Thu, 16 Mar 2023 16:27:05 +0800 +Subject: [PATCH] hw/riscv: virt: Simplify virt_{get,set}_aclint() + +There is no need to declare an intermediate "MachineState *ms". + +Signed-off-by: Bin Meng +Signed-off-by: jianchunfu +--- + hw/riscv/virt.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c +index 3af074148e..cd03ba1d76 100644 +--- a/hw/riscv/virt.c ++++ b/hw/riscv/virt.c +@@ -984,16 +984,14 @@ static void virt_machine_instance_init(Object *obj) + + static bool virt_get_aclint(Object *obj, Error **errp) + { +- MachineState *ms = MACHINE(obj); +- RISCVVirtState *s = RISCV_VIRT_MACHINE(ms); ++ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); + + return s->have_aclint; + } + + static void virt_set_aclint(Object *obj, bool value, Error **errp) + { +- MachineState *ms = MACHINE(obj); +- RISCVVirtState *s = RISCV_VIRT_MACHINE(ms); ++ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); + + s->have_aclint = value; + } +-- +2.27.0 + diff --git a/i386-add-notify-VM-exit-support.patch b/i386-add-notify-VM-exit-support.patch new file mode 100644 index 0000000..83f47d1 --- /dev/null +++ b/i386-add-notify-VM-exit-support.patch @@ -0,0 +1,270 @@ +From 06d1ed3c9e3b736944e5267ffc8d341801fb758b Mon Sep 17 00:00:00 2001 +From: Chenyi Qiang +Date: Thu, 29 Sep 2022 15:20:14 +0800 +Subject: [PATCH] i386: add notify VM exit support + +from mainline-v7.2.0-rc0 +commit e2e69f6bb907a70ac518230c54e98e7abcb0c911 +category: feature +feature: Notify VM Exit +bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6GWQE + +Intel-SIG: commit e2e69f6bb907 ("i386: add notify VM exit support") + +------------------------------------------------------------------ + +i386: add notify VM exit support + +There are cases that malicious virtual machine can cause CPU stuck (due +to event windows don't open up), e.g., infinite loop in microcode when +nested #AC (CVE-2015-5307). No event window means no event (NMI, SMI and +IRQ) can be delivered. It leads the CPU to be unavailable to host or +other VMs. Notify VM exit is introduced to mitigate such kind of +attacks, which will generate a VM exit if no event window occurs in VM +non-root mode for a specified amount of time (notify window). + +A new KVM capability KVM_CAP_X86_NOTIFY_VMEXIT is exposed to user space +so that the user can query the capability and set the expected notify +window when creating VMs. The format of the argument when enabling this +capability is as follows: + Bit 63:32 - notify window specified in qemu command + Bit 31:0 - some flags (e.g. KVM_X86_NOTIFY_VMEXIT_ENABLED is set to + enable the feature.) + +Users can configure the feature by a new (x86 only) accel property: + qemu -accel kvm,notify-vmexit=run|internal-error|disable,notify-window=n + +The default option of notify-vmexit is run, which will enable the +capability and do nothing if the exit happens. The internal-error option +raises a KVM internal error if it happens. The disable option does not +enable the capability. The default value of notify-window is 0. It is valid +only when notify-vmexit is not disabled. The valid range of notify-window +is non-negative. It is even safe to set it to zero since there's an +internal hardware threshold to be added to ensure no false positive. + +Because a notify VM exit may happen with VM_CONTEXT_INVALID set in exit +qualification (no cases are anticipated that would set this bit), which +means VM context is corrupted. It would be reflected in the flags of +KVM_EXIT_NOTIFY exit. If KVM_NOTIFY_CONTEXT_INVALID bit is set, raise a KVM +internal error unconditionally. + +Acked-by: Peter Xu +Signed-off-by: Chenyi Qiang +Message-Id: <20220929072014.20705-5-chenyi.qiang@intel.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Jason Zeng +--- + accel/kvm/kvm-all.c | 2 + + qapi/run-state.json | 17 ++++++++ + qemu-options.hx | 11 +++++ + target/i386/kvm/kvm.c | 98 +++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 128 insertions(+) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index 91d93facf2..799d993f6c 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -3602,6 +3602,8 @@ static void kvm_accel_instance_init(Object *obj) + s->kernel_irqchip_split = ON_OFF_AUTO_AUTO; + /* KVM dirty ring is by default off */ + s->kvm_dirty_ring_size = 0; ++ s->notify_vmexit = NOTIFY_VMEXIT_OPTION_RUN; ++ s->notify_window = 0; + } + + static void kvm_accel_class_init(ObjectClass *oc, void *data) +diff --git a/qapi/run-state.json b/qapi/run-state.json +index 43d66d700f..08c38b2c67 100644 +--- a/qapi/run-state.json ++++ b/qapi/run-state.json +@@ -638,3 +638,20 @@ + { 'struct': 'MemoryFailureFlags', + 'data': { 'action-required': 'bool', + 'recursive': 'bool'} } ++ ++## ++# @NotifyVmexitOption: ++# ++# An enumeration of the options specified when enabling notify VM exit ++# ++# @run: enable the feature, do nothing and continue if the notify VM exit happens. ++# ++# @internal-error: enable the feature, raise a internal error if the notify ++# VM exit happens. ++# ++# @disable: disable the feature. ++# ++# Since: 7.2 ++## ++{ 'enum': 'NotifyVmexitOption', ++ 'data': [ 'run', 'internal-error', 'disable' ] } +\ No newline at end of file +diff --git a/qemu-options.hx b/qemu-options.hx +index 047d28a357..3c9b0f022c 100644 +--- a/qemu-options.hx ++++ b/qemu-options.hx +@@ -152,6 +152,7 @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel, + " split-wx=on|off (enable TCG split w^x mapping)\n" + " tb-size=n (TCG translation block cache size)\n" + " dirty-ring-size=n (KVM dirty ring GFN count, default 0)\n" ++ " notify-vmexit=run|internal-error|disable,notify-window=n (enable notify VM exit and set notify window, x86 only)\n" + " thread=single|multi (enable multi-threaded TCG)\n", QEMU_ARCH_ALL) + SRST + ``-accel name[,prop=value[,...]]`` +@@ -203,6 +204,16 @@ SRST + is disabled (dirty-ring-size=0). When enabled, KVM will instead + record dirty pages in a bitmap. + ++ ``notify-vmexit=run|internal-error|disable,notify-window=n`` ++ Enables or disables notify VM exit support on x86 host and specify ++ the corresponding notify window to trigger the VM exit if enabled. ++ ``run`` option enables the feature. It does nothing and continue ++ if the exit happens. ``internal-error`` option enables the feature. ++ It raises a internal error. ``disable`` option doesn't enable the feature. ++ This feature can mitigate the CPU stuck issue due to event windows don't ++ open up for a specified of time (i.e. notify-window). ++ Default: notify-vmexit=run,notify-window=0. ++ + ERST + + DEF("smp", HAS_ARG, QEMU_OPTION_smp, +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index e2f28ce958..b8257e7e5f 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -15,6 +15,7 @@ + #include "qemu/osdep.h" + #include "qapi/qapi-events-run-state.h" + #include "qapi/error.h" ++#include "qapi/visitor.h" + #include + #include + #include +@@ -2496,6 +2497,21 @@ int kvm_arch_init(MachineState *ms, KVMState *s) + } + } + ++ if (s->notify_vmexit != NOTIFY_VMEXIT_OPTION_DISABLE && ++ kvm_check_extension(s, KVM_CAP_X86_NOTIFY_VMEXIT)) { ++ uint64_t notify_window_flags = ++ ((uint64_t)s->notify_window << 32) | ++ KVM_X86_NOTIFY_VMEXIT_ENABLED | ++ KVM_X86_NOTIFY_VMEXIT_USER; ++ ret = kvm_vm_enable_cap(s, KVM_CAP_X86_NOTIFY_VMEXIT, 0, ++ notify_window_flags); ++ if (ret < 0) { ++ error_report("kvm: Failed to enable notify vmexit cap: %s", ++ strerror(-ret)); ++ return ret; ++ } ++ } ++ + return 0; + } + +@@ -4839,6 +4855,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) + X86CPU *cpu = X86_CPU(cs); + uint64_t code; + int ret; ++ bool ctx_invalid; ++ char str[256]; ++ KVMState *state; + + switch (run->exit_reason) { + case KVM_EXIT_HLT: +@@ -4894,6 +4913,21 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) + /* already handled in kvm_arch_post_run */ + ret = 0; + break; ++ case KVM_EXIT_NOTIFY: ++ ctx_invalid = !!(run->notify.flags & KVM_NOTIFY_CONTEXT_INVALID); ++ state = KVM_STATE(current_accel()); ++ sprintf(str, "Encounter a notify exit with %svalid context in" ++ " guest. There can be possible misbehaves in guest." ++ " Please have a look.", ctx_invalid ? "in" : ""); ++ if (ctx_invalid || ++ state->notify_vmexit == NOTIFY_VMEXIT_OPTION_INTERNAL_ERROR) { ++ warn_report("KVM internal error: %s", str); ++ ret = -1; ++ } else { ++ warn_report_once("KVM: %s", str); ++ ret = 0; ++ } ++ break; + default: + fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); + ret = -1; +@@ -5169,6 +5203,70 @@ void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask) + } + } + ++static int kvm_arch_get_notify_vmexit(Object *obj, Error **errp) ++{ ++ KVMState *s = KVM_STATE(obj); ++ return s->notify_vmexit; ++} ++ ++static void kvm_arch_set_notify_vmexit(Object *obj, int value, Error **errp) ++{ ++ KVMState *s = KVM_STATE(obj); ++ ++ if (s->fd != -1) { ++ error_setg(errp, "Cannot set properties after the accelerator has been initialized"); ++ return; ++ } ++ ++ s->notify_vmexit = value; ++} ++ ++static void kvm_arch_get_notify_window(Object *obj, Visitor *v, ++ const char *name, void *opaque, ++ Error **errp) ++{ ++ KVMState *s = KVM_STATE(obj); ++ uint32_t value = s->notify_window; ++ ++ visit_type_uint32(v, name, &value, errp); ++} ++ ++static void kvm_arch_set_notify_window(Object *obj, Visitor *v, ++ const char *name, void *opaque, ++ Error **errp) ++{ ++ KVMState *s = KVM_STATE(obj); ++ Error *error = NULL; ++ uint32_t value; ++ ++ if (s->fd != -1) { ++ error_setg(errp, "Cannot set properties after the accelerator has been initialized"); ++ return; ++ } ++ ++ visit_type_uint32(v, name, &value, &error); ++ if (error) { ++ error_propagate(errp, error); ++ return; ++ } ++ ++ s->notify_window = value; ++} ++ + void kvm_arch_accel_class_init(ObjectClass *oc) + { ++ object_class_property_add_enum(oc, "notify-vmexit", "NotifyVMexitOption", ++ &NotifyVmexitOption_lookup, ++ kvm_arch_get_notify_vmexit, ++ kvm_arch_set_notify_vmexit); ++ object_class_property_set_description(oc, "notify-vmexit", ++ "Enable notify VM exit"); ++ ++ object_class_property_add(oc, "notify-window", "uint32", ++ kvm_arch_get_notify_window, ++ kvm_arch_set_notify_window, ++ NULL, NULL); ++ object_class_property_set_description(oc, "notify-window", ++ "Clock cycles without an event window " ++ "after which a notification VM exit occurs"); + } +-- +2.27.0 + diff --git a/i386-kvm-extend-kvm_-get-put-_vcpu_events-to-support.patch b/i386-kvm-extend-kvm_-get-put-_vcpu_events-to-support.patch new file mode 100644 index 0000000..e4bc275 --- /dev/null +++ b/i386-kvm-extend-kvm_-get-put-_vcpu_events-to-support.patch @@ -0,0 +1,156 @@ +From 752fe0479931f6ef512b6a048fb50364505ff713 Mon Sep 17 00:00:00 2001 +From: Chenyi Qiang +Date: Thu, 29 Sep 2022 15:20:11 +0800 +Subject: [PATCH] i386: kvm: extend kvm_{get, put}_vcpu_events to support + pending triple fault + +from mainline-v7.2.0-rc0 +commit 12f89a39cf3c5760cba82ce68929d748961f62df +category: feature +feature: Notify VM Exit +bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6GWQE + +Intel-SIG: commit 12f89a39cf3c ("i386: kvm: extend kvm_{get, put}_vcpu_events to support pending triple fault") + +------------------------------------------------------------------ + +i386: kvm: extend kvm_{get, put}_vcpu_events to support pending triple fault + +For the direct triple faults, i.e. hardware detected and KVM morphed +to VM-Exit, KVM will never lose them. But for triple faults sythesized +by KVM, e.g. the RSM path, if KVM exits to userspace before the request +is serviced, userspace could migrate the VM and lose the triple fault. + +A new flag KVM_VCPUEVENT_VALID_TRIPLE_FAULT is defined to signal that +the event.triple_fault_pending field contains a valid state if the +KVM_CAP_X86_TRIPLE_FAULT_EVENT capability is enabled. + +Acked-by: Peter Xu +Signed-off-by: Chenyi Qiang +Message-Id: <20220929072014.20705-2-chenyi.qiang@intel.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Jason Zeng +--- + target/i386/cpu.c | 1 + + target/i386/cpu.h | 1 + + target/i386/kvm/kvm.c | 20 ++++++++++++++++++++ + target/i386/machine.c | 20 ++++++++++++++++++++ + 4 files changed, 42 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 551b47ab1e..e3cea8397c 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -6018,6 +6018,7 @@ static void x86_cpu_reset(DeviceState *dev) + env->exception_has_payload = false; + env->exception_payload = 0; + env->nmi_injected = false; ++ env->triple_fault_pending = false; + #if !defined(CONFIG_USER_ONLY) + /* We hard-wire the BSP to the first CPU. */ + apic_designate_bsp(cpu->apic_state, s->cpu_index == 0); +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 290f1beaea..4f7fa87b95 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -1698,6 +1698,7 @@ typedef struct CPUX86State { + uint8_t has_error_code; + uint8_t exception_has_payload; + uint64_t exception_payload; ++ uint8_t triple_fault_pending; + uint32_t ins_len; + uint32_t sipi_vector; + bool tsc_valid; +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 5b15e0430b..e97d967c73 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_triple_fault_event; + + static bool has_msr_mcg_ext_ctl; + +@@ -2380,6 +2381,16 @@ int kvm_arch_init(MachineState *ms, KVMState *s) + } + } + ++ has_triple_fault_event = kvm_check_extension(s, KVM_CAP_X86_TRIPLE_FAULT_EVENT); ++ if (has_triple_fault_event) { ++ ret = kvm_vm_enable_cap(s, KVM_CAP_X86_TRIPLE_FAULT_EVENT, 0, true); ++ if (ret < 0) { ++ error_report("kvm: Failed to enable triple fault event cap: %s", ++ strerror(-ret)); ++ return ret; ++ } ++ } ++ + ret = kvm_get_supported_msrs(s); + if (ret < 0) { + return ret; +@@ -4004,6 +4015,11 @@ static int kvm_put_vcpu_events(X86CPU *cpu, int level) + } + } + ++ if (has_triple_fault_event) { ++ events.flags |= KVM_VCPUEVENT_VALID_TRIPLE_FAULT; ++ events.triple_fault.pending = env->triple_fault_pending; ++ } ++ + return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_VCPU_EVENTS, &events); + } + +@@ -4073,6 +4089,10 @@ static int kvm_get_vcpu_events(X86CPU *cpu) + } + } + ++ if (events.flags & KVM_VCPUEVENT_VALID_TRIPLE_FAULT) { ++ env->triple_fault_pending = events.triple_fault.pending; ++ } ++ + env->sipi_vector = events.sipi_vector; + + return 0; +diff --git a/target/i386/machine.c b/target/i386/machine.c +index 3977e9d8f8..41cf5c0053 100644 +--- a/target/i386/machine.c ++++ b/target/i386/machine.c +@@ -1497,6 +1497,25 @@ static const VMStateDescription vmstate_amx_xtile = { + }; + #endif + ++static bool triple_fault_needed(void *opaque) ++{ ++ X86CPU *cpu = opaque; ++ CPUX86State *env = &cpu->env; ++ ++ return env->triple_fault_pending; ++} ++ ++static const VMStateDescription vmstate_triple_fault = { ++ .name = "cpu/triple_fault", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .needed = triple_fault_needed, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT8(env.triple_fault_pending, X86CPU), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ + const VMStateDescription vmstate_x86_cpu = { + .name = "cpu", + .version_id = 12, +@@ -1639,6 +1658,7 @@ const VMStateDescription vmstate_x86_cpu = { + #ifdef TARGET_X86_64 + &vmstate_amx_xtile, + #endif ++ &vmstate_triple_fault, + NULL + } + }; +-- +2.27.0 + diff --git a/kvm-allow-target-specific-accelerator-properties.patch b/kvm-allow-target-specific-accelerator-properties.patch new file mode 100644 index 0000000..6c8c536 --- /dev/null +++ b/kvm-allow-target-specific-accelerator-properties.patch @@ -0,0 +1,129 @@ +From f90dc9f811195fabd68faf2ca98b2fe5b4fbe3d0 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 29 Sep 2022 15:20:12 +0800 +Subject: [PATCH] kvm: allow target-specific accelerator properties + +from mainline-v7.2.0-rc0 +commit 3dba0a335cf5c53146b606be6ddfab4df81c464e +category: feature +feature: Notify VM Exit +bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6GWQE + +Intel-SIG: commit 3dba0a335cf5 ("kvm: allow target-specific accelerator properties") + +------------------------------------------------------------------ + +kvm: allow target-specific accelerator properties + +Several hypervisor capabilities in KVM are target-specific. When exposed +to QEMU users as accelerator properties (i.e. -accel kvm,prop=value), they +should not be available for all targets. + +Add a hook for targets to add their own properties to -accel kvm, for +now no such property is defined. + +Signed-off-by: Paolo Bonzini +Message-Id: <20220929072014.20705-3-chenyi.qiang@intel.com> +Signed-off-by: Paolo Bonzini +[ remove changes in target/riscv/kvm.c since riscv kvm is not + supported in qemu-6.2.0 and linux 5.10 ] +Signed-off-by: Jason Zeng +--- + accel/kvm/kvm-all.c | 2 ++ + include/sysemu/kvm.h | 2 ++ + target/arm/kvm.c | 4 ++++ + target/i386/kvm/kvm.c | 4 ++++ + target/mips/kvm.c | 4 ++++ + target/ppc/kvm.c | 4 ++++ + target/s390x/kvm/kvm.c | 4 ++++ + 7 files changed, 24 insertions(+) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index 946ccb260b..e5681a6cd0 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -3703,6 +3703,8 @@ static void kvm_accel_class_init(ObjectClass *oc, void *data) + NULL, NULL); + object_class_property_set_description(oc, "dirty-ring-size", + "Size of KVM dirty page ring buffer (default: 0, i.e. use bitmap)"); ++ ++ kvm_arch_accel_class_init(oc); + } + + static const TypeInfo kvm_accel_type = { +diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h +index 19c5c8402a..1ec9432493 100644 +--- a/include/sysemu/kvm.h ++++ b/include/sysemu/kvm.h +@@ -334,6 +334,8 @@ bool kvm_device_supported(int vmfd, uint64_t type); + + extern const KVMCapabilityInfo kvm_arch_required_capabilities[]; + ++void kvm_arch_accel_class_init(ObjectClass *oc); ++ + void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run); + MemTxAttrs kvm_arch_post_run(CPUState *cpu, struct kvm_run *run); + +diff --git a/target/arm/kvm.c b/target/arm/kvm.c +index 29ac3f40e0..22ac5bcb97 100644 +--- a/target/arm/kvm.c ++++ b/target/arm/kvm.c +@@ -1095,3 +1095,7 @@ bool kvm_arch_cpu_check_are_resettable(void) + { + return true; + } ++ ++void kvm_arch_accel_class_init(ObjectClass *oc) ++{ ++} +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index e97d967c73..e2f28ce958 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -5168,3 +5168,7 @@ void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask) + mask &= ~BIT_ULL(bit); + } + } ++ ++void kvm_arch_accel_class_init(ObjectClass *oc) ++{ ++} +diff --git a/target/mips/kvm.c b/target/mips/kvm.c +index 086debd9f0..f80ac72dd1 100644 +--- a/target/mips/kvm.c ++++ b/target/mips/kvm.c +@@ -1295,3 +1295,7 @@ bool kvm_arch_cpu_check_are_resettable(void) + { + return true; + } ++ ++void kvm_arch_accel_class_init(ObjectClass *oc) ++{ ++} +diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c +index d73563045b..9693aab3c7 100644 +--- a/target/ppc/kvm.c ++++ b/target/ppc/kvm.c +@@ -2975,3 +2975,7 @@ bool kvm_arch_cpu_check_are_resettable(void) + { + return true; + } ++ ++void kvm_arch_accel_class_init(ObjectClass *oc) ++{ ++} +diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c +index 5b1fdb55c4..671d0f179c 100644 +--- a/target/s390x/kvm/kvm.c ++++ b/target/s390x/kvm/kvm.c +@@ -2562,3 +2562,7 @@ bool kvm_arch_cpu_check_are_resettable(void) + { + return true; + } ++ ++void kvm_arch_accel_class_init(ObjectClass *oc) ++{ ++} +-- +2.27.0 + diff --git a/kvm-expose-struct-KVMState.patch b/kvm-expose-struct-KVMState.patch new file mode 100644 index 0000000..8514cd8 --- /dev/null +++ b/kvm-expose-struct-KVMState.patch @@ -0,0 +1,218 @@ +From 9f7f9fdf2246c653673d07fccc07cdc6b03f8722 Mon Sep 17 00:00:00 2001 +From: Chenyi Qiang +Date: Thu, 29 Sep 2022 15:20:13 +0800 +Subject: [PATCH] kvm: expose struct KVMState + +from mainline-v7.2.0-rc0 +commit 5f8a6bce1f1080058ed29d716cae81ea805142ae +category: feature +feature: Notify VM Exit +bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6GWQE + +Intel-SIG: commit 5f8a6bce1f10 ("kvm: expose struct KVMState") + +------------------------------------------------------------------ + +kvm: expose struct KVMState + +Expose struct KVMState out of kvm-all.c so that the field of struct +KVMState can be accessed when defining target-specific accelerator +properties. + +Signed-off-by: Chenyi Qiang +Message-Id: <20220929072014.20705-4-chenyi.qiang@intel.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Jason Zeng +--- + accel/kvm/kvm-all.c | 74 -------------------------------------- + include/sysemu/kvm_int.h | 76 ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 76 insertions(+), 74 deletions(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index e5681a6cd0..91d93facf2 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -72,86 +72,12 @@ + do { } while (0) + #endif + +-#define KVM_MSI_HASHTAB_SIZE 256 +- + struct KVMParkedVcpu { + unsigned long vcpu_id; + int kvm_fd; + QLIST_ENTRY(KVMParkedVcpu) node; + }; + +-enum KVMDirtyRingReaperState { +- KVM_DIRTY_RING_REAPER_NONE = 0, +- /* The reaper is sleeping */ +- KVM_DIRTY_RING_REAPER_WAIT, +- /* The reaper is reaping for dirty pages */ +- KVM_DIRTY_RING_REAPER_REAPING, +-}; +- +-/* +- * KVM reaper instance, responsible for collecting the KVM dirty bits +- * via the dirty ring. +- */ +-struct KVMDirtyRingReaper { +- /* The reaper thread */ +- QemuThread reaper_thr; +- volatile uint64_t reaper_iteration; /* iteration number of reaper thr */ +- volatile enum KVMDirtyRingReaperState reaper_state; /* reap thr state */ +-}; +- +-struct KVMState +-{ +- AccelState parent_obj; +- +- int nr_slots; +- int fd; +- int vmfd; +- int coalesced_mmio; +- int coalesced_pio; +- struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; +- bool coalesced_flush_in_progress; +- int vcpu_events; +- int robust_singlestep; +- int debugregs; +-#ifdef KVM_CAP_SET_GUEST_DEBUG +- QTAILQ_HEAD(, kvm_sw_breakpoint) kvm_sw_breakpoints; +-#endif +- int max_nested_state_len; +- int many_ioeventfds; +- int intx_set_mask; +- int kvm_shadow_mem; +- bool kernel_irqchip_allowed; +- bool kernel_irqchip_required; +- OnOffAuto kernel_irqchip_split; +- bool sync_mmu; +- uint64_t manual_dirty_log_protect; +- /* The man page (and posix) say ioctl numbers are signed int, but +- * they're not. Linux, glibc and *BSD all treat ioctl numbers as +- * unsigned, and treating them as signed here can break things */ +- unsigned irq_set_ioctl; +- unsigned int sigmask_len; +- GHashTable *gsimap; +-#ifdef KVM_CAP_IRQ_ROUTING +- struct kvm_irq_routing *irq_routes; +- int nr_allocated_irq_routes; +- unsigned long *used_gsi_bitmap; +- unsigned int gsi_count; +- QTAILQ_HEAD(, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE]; +-#endif +- KVMMemoryListener memory_listener; +- QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus; +- +- /* For "info mtree -f" to tell if an MR is registered in KVM */ +- int nr_as; +- struct KVMAs { +- KVMMemoryListener *ml; +- AddressSpace *as; +- } *as; +- uint64_t kvm_dirty_ring_bytes; /* Size of the per-vcpu dirty ring */ +- uint32_t kvm_dirty_ring_size; /* Number of dirty GFNs per ring */ +- struct KVMDirtyRingReaper reaper; +-}; +- + KVMState *kvm_state; + bool kvm_kernel_irqchip; + bool kvm_split_irqchip; +diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h +index 1f5487d9b7..3b4adcdc10 100644 +--- a/include/sysemu/kvm_int.h ++++ b/include/sysemu/kvm_int.h +@@ -10,6 +10,7 @@ + #define QEMU_KVM_INT_H + + #include "exec/memory.h" ++#include "qapi/qapi-types-common.h" + #include "qemu/accel.h" + #include "sysemu/kvm.h" + +@@ -36,6 +37,81 @@ typedef struct KVMMemoryListener { + int as_id; + } KVMMemoryListener; + ++#define KVM_MSI_HASHTAB_SIZE 256 ++ ++enum KVMDirtyRingReaperState { ++ KVM_DIRTY_RING_REAPER_NONE = 0, ++ /* The reaper is sleeping */ ++ KVM_DIRTY_RING_REAPER_WAIT, ++ /* The reaper is reaping for dirty pages */ ++ KVM_DIRTY_RING_REAPER_REAPING, ++}; ++ ++/* ++ * KVM reaper instance, responsible for collecting the KVM dirty bits ++ * via the dirty ring. ++ */ ++struct KVMDirtyRingReaper { ++ /* The reaper thread */ ++ QemuThread reaper_thr; ++ volatile uint64_t reaper_iteration; /* iteration number of reaper thr */ ++ volatile enum KVMDirtyRingReaperState reaper_state; /* reap thr state */ ++}; ++struct KVMState ++{ ++ AccelState parent_obj; ++ ++ int nr_slots; ++ int fd; ++ int vmfd; ++ int coalesced_mmio; ++ int coalesced_pio; ++ struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; ++ bool coalesced_flush_in_progress; ++ int vcpu_events; ++ int robust_singlestep; ++ int debugregs; ++#ifdef KVM_CAP_SET_GUEST_DEBUG ++ QTAILQ_HEAD(, kvm_sw_breakpoint) kvm_sw_breakpoints; ++#endif ++ int max_nested_state_len; ++ int many_ioeventfds; ++ int intx_set_mask; ++ int kvm_shadow_mem; ++ bool kernel_irqchip_allowed; ++ bool kernel_irqchip_required; ++ OnOffAuto kernel_irqchip_split; ++ bool sync_mmu; ++ uint64_t manual_dirty_log_protect; ++ /* The man page (and posix) say ioctl numbers are signed int, but ++ * they're not. Linux, glibc and *BSD all treat ioctl numbers as ++ * unsigned, and treating them as signed here can break things */ ++ unsigned irq_set_ioctl; ++ unsigned int sigmask_len; ++ GHashTable *gsimap; ++#ifdef KVM_CAP_IRQ_ROUTING ++ struct kvm_irq_routing *irq_routes; ++ int nr_allocated_irq_routes; ++ unsigned long *used_gsi_bitmap; ++ unsigned int gsi_count; ++ QTAILQ_HEAD(, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE]; ++#endif ++ KVMMemoryListener memory_listener; ++ QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus; ++ ++ /* For "info mtree -f" to tell if an MR is registered in KVM */ ++ int nr_as; ++ struct KVMAs { ++ KVMMemoryListener *ml; ++ AddressSpace *as; ++ } *as; ++ uint64_t kvm_dirty_ring_bytes; /* Size of the per-vcpu dirty ring */ ++ uint32_t kvm_dirty_ring_size; /* Number of dirty GFNs per ring */ ++ struct KVMDirtyRingReaper reaper; ++ NotifyVmexitOption notify_vmexit; ++ uint32_t notify_window; ++}; ++ + void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml, + AddressSpace *as, int as_id, const char *name); + +-- +2.27.0 + diff --git a/linux-headers-include-missing-changes-from-6.0.patch b/linux-headers-include-missing-changes-from-6.0.patch new file mode 100644 index 0000000..5d2ccc4 --- /dev/null +++ b/linux-headers-include-missing-changes-from-6.0.patch @@ -0,0 +1,80 @@ +From 1e54d0c7bca44e2cf58c769e420c5ffcefb58ea1 Mon Sep 17 00:00:00 2001 +From: Jason Zeng +Date: Wed, 22 Feb 2023 13:59:37 +0800 +Subject: [PATCH] linux-headers: include missing changes from 6.0 + +Signed-off-by: Jason Zeng +--- + linux-headers/asm-x86/kvm.h | 6 +++++- + linux-headers/linux/kvm.h | 12 ++++++++++++ + 2 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h +index 2ab4f1818a..46e730b62f 100644 +--- a/linux-headers/asm-x86/kvm.h ++++ b/linux-headers/asm-x86/kvm.h +@@ -324,6 +324,7 @@ struct kvm_reinject_control { + #define KVM_VCPUEVENT_VALID_SHADOW 0x00000004 + #define KVM_VCPUEVENT_VALID_SMM 0x00000008 + #define KVM_VCPUEVENT_VALID_PAYLOAD 0x00000010 ++#define KVM_VCPUEVENT_VALID_TRIPLE_FAULT 0x00000020 + + /* Interrupt shadow states */ + #define KVM_X86_SHADOW_INT_MOV_SS 0x01 +@@ -358,7 +359,10 @@ struct kvm_vcpu_events { + __u8 smm_inside_nmi; + __u8 latched_init; + } smi; +- __u8 reserved[27]; ++ struct { ++ __u8 pending; ++ } triple_fault; ++ __u8 reserved[26]; + __u8 exception_has_payload; + __u64 exception_payload; + }; +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 7870cd0280..cda9016d49 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -269,6 +269,7 @@ struct kvm_xen_exit { + #define KVM_EXIT_AP_RESET_HOLD 32 + #define KVM_EXIT_X86_BUS_LOCK 33 + #define KVM_EXIT_XEN 34 ++#define KVM_EXIT_NOTIFY 37 + + /* For KVM_EXIT_INTERNAL_ERROR */ + /* Emulate instruction failed. */ +@@ -469,6 +470,11 @@ struct kvm_run { + } msr; + /* KVM_EXIT_XEN */ + struct kvm_xen_exit xen; ++ /* KVM_EXIT_NOTIFY */ ++ struct { ++#define KVM_NOTIFY_CONTEXT_INVALID (1 << 0) ++ __u32 flags; ++ } notify; + /* Fix the size of the union. */ + char padding[256]; + }; +@@ -1116,6 +1122,8 @@ struct kvm_ppc_resize_hpt { + #define KVM_CAP_VM_GPA_BITS 207 + #define KVM_CAP_XSAVE2 208 + #define KVM_CAP_SYS_ATTRIBUTES 209 ++#define KVM_CAP_X86_TRIPLE_FAULT_EVENT 218 ++#define KVM_CAP_X86_NOTIFY_VMEXIT 219 + + #define KVM_CAP_ARM_CPU_FEATURE 555 + +@@ -2013,4 +2021,8 @@ struct kvm_stats_desc { + /* Available with KVM_CAP_XSAVE2 */ + #define KVM_GET_XSAVE2 _IOR(KVMIO, 0xcf, struct kvm_xsave) + ++/* Available with KVM_CAP_X86_NOTIFY_VMEXIT */ ++#define KVM_X86_NOTIFY_VMEXIT_ENABLED (1ULL << 0) ++#define KVM_X86_NOTIFY_VMEXIT_USER (1ULL << 1) ++ + #endif /* __LINUX_KVM_H */ +-- +2.27.0 + diff --git a/net-Fix-uninitialized-data-usage.patch b/net-Fix-uninitialized-data-usage.patch new file mode 100644 index 0000000..d72c895 --- /dev/null +++ b/net-Fix-uninitialized-data-usage.patch @@ -0,0 +1,92 @@ +From de8ab0c3b4e5f9aac9e7be00cfbd86d724bf036e Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Fri, 24 Mar 2023 07:42:33 +0000 +Subject: [PATCH] net: Fix uninitialized data usage mainline inclusion commit + e29919c93d19118610d64de9deb9c223024c0bc6 category: bugfix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--------------------------------------------------------------- + +e.g. +1109 15:16:20.151506 Uninitialized bytes in ioctl_common_pre at offset 0 inside [0x7ffc516af9b8, 4) + 1109 15:16:20.151659 ==588974==WARNING: MemorySanitizer: use-of-uninitialized-value + 1109 15:16:20.312923 #0 0x5639b88acb21 in tap_probe_vnet_hdr_len third_party/qemu/net/tap-linux.c:183:9 + 1109 15:16:20.312952 #1 0x5639b88afd66 in net_tap_fd_init third_party/qemu/net/tap.c:409:9 + 1109 15:16:20.312954 #2 0x5639b88b2d1b in net_init_tap_one third_party/qemu/net/tap.c:681:19 + 1109 15:16:20.312956 #3 0x5639b88b16a8 in net_init_tap third_party/qemu/net/tap.c:912:13 + 1109 15:16:20.312957 #4 0x5639b8890175 in net_client_init1 third_party/qemu/net/net.c:1110:9 + 1109 15:16:20.312958 #5 0x5639b888f912 in net_client_init third_party/qemu/net/net.c:1208:15 + 1109 15:16:20.312960 #6 0x5639b8894aa5 in net_param_nic third_party/qemu/net/net.c:1588:11 + 1109 15:16:20.312961 #7 0x5639b900cd18 in qemu_opts_foreach third_party/qemu/util/qemu-option.c:1135:14 + 1109 15:16:20.312962 #8 0x5639b889393c in net_init_clients third_party/qemu/net/net.c:1612:9 + 1109 15:16:20.312964 #9 0x5639b717aaf3 in qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5 + 1109 15:16:20.312965 #10 0x5639b717aaf3 in qemu_init third_party/qemu/softmmu/vl.c:3694:5 + 1109 15:16:20.312967 #11 0x5639b71083b8 in main third_party/qemu/softmmu/main.c:49:5 + 1109 15:16:20.312968 #12 0x7f464de1d8d2 in __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x628d2) + 1109 15:16:20.312969 #13 0x5639b6bbd389 in _start /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120 + 1109 15:16:20.312970 + 1109 15:16:20.312975 Uninitialized value was stored to memory at + 1109 15:16:20.313393 #0 0x5639b88acbee in tap_probe_vnet_hdr_len third_party/qemu/net/tap-linux.c + 1109 15:16:20.313396 #1 0x5639b88afd66 in net_tap_fd_init third_party/qemu/net/tap.c:409:9 + 1109 15:16:20.313398 #2 0x5639b88b2d1b in net_init_tap_one third_party/qemu/net/tap.c:681:19 + 1109 15:16:20.313399 #3 0x5639b88b16a8 in net_init_tap third_party/qemu/net/tap.c:912:13 + 1109 15:16:20.313400 #4 0x5639b8890175 in net_client_init1 third_party/qemu/net/net.c:1110:9 + 1109 15:16:20.313401 #5 0x5639b888f912 in net_client_init third_party/qemu/net/net.c:1208:15 + 1109 15:16:20.313403 #6 0x5639b8894aa5 in net_param_nic third_party/qemu/net/net.c:1588:11 + 1109 15:16:20.313404 #7 0x5639b900cd18 in qemu_opts_foreach third_party/qemu/util/qemu-option.c:1135:14 + 1109 15:16:20.313405 #8 0x5639b889393c in net_init_clients third_party/qemu/net/net.c:1612:9 + 1109 15:16:20.313407 #9 0x5639b717aaf3 in qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5 + 1109 15:16:20.313408 #10 0x5639b717aaf3 in qemu_init third_party/qemu/softmmu/vl.c:3694:5 + 1109 15:16:20.313409 #11 0x5639b71083b8 in main third_party/qemu/softmmu/main.c:49:5 + 1109 15:16:20.313410 #12 0x7f464de1d8d2 in __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x628d2) + 1109 15:16:20.313412 #13 0x5639b6bbd389 in _start /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120 + 1109 15:16:20.313413 + 1109 15:16:20.313417 Uninitialized value was stored to memory at + 1109 15:16:20.313791 #0 0x5639b88affbd in net_tap_fd_init third_party/qemu/net/tap.c:400:26 + 1109 15:16:20.313826 #1 0x5639b88b2d1b in net_init_tap_one third_party/qemu/net/tap.c:681:19 + 1109 15:16:20.313829 #2 0x5639b88b16a8 in net_init_tap third_party/qemu/net/tap.c:912:13 + 1109 15:16:20.313831 #3 0x5639b8890175 in net_client_init1 third_party/qemu/net/net.c:1110:9 + 1109 15:16:20.313836 #4 0x5639b888f912 in net_client_init third_party/qemu/net/net.c:1208:15 + 1109 15:16:20.313838 #5 0x5639b8894aa5 in net_param_nic third_party/qemu/net/net.c:1588:11 + 1109 15:16:20.313839 #6 0x5639b900cd18 in qemu_opts_foreach third_party/qemu/util/qemu-option.c:1135:14 + 1109 15:16:20.313841 #7 0x5639b889393c in net_init_clients third_party/qemu/net/net.c:1612:9 + 1109 15:16:20.313843 #8 0x5639b717aaf3 in qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5 + 1109 15:16:20.313844 #9 0x5639b717aaf3 in qemu_init third_party/qemu/softmmu/vl.c:3694:5 + 1109 15:16:20.313845 #10 0x5639b71083b8 in main third_party/qemu/softmmu/main.c:49:5 + 1109 15:16:20.313846 #11 0x7f464de1d8d2 in __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x628d2) + 1109 15:16:20.313847 #12 0x5639b6bbd389 in _start /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120 + 1109 15:16:20.313849 + 1109 15:16:20.313851 Uninitialized value was created by an allocation of 'ifr' in the stack frame of function 'tap_probe_vnet_hdr' + 1109 15:16:20.313855 #0 0x5639b88ac680 in tap_probe_vnet_hdr third_party/qemu/net/tap-linux.c:151 + 1109 15:16:20.313856 + 1109 15:16:20.313878 SUMMARY: MemorySanitizer: use-of-uninitialized-value third_party/qemu/net/tap-linux.c:183:9 in tap_probe_vnet_hdr_len + +Fixes: dc69004c7d8 ("net: move tap_probe_vnet_hdr() to tap-linux.c") +Reviewed-by: Hao Wu +Reviewed-by: Patrick Venture +Reviewed-by: Philippe Mathieu-Daud茅 +Signed-off-by: Peter Foley +Signed-off-by: Jason Wang + +Signed-off-by: tangbinzy +--- + net/tap-linux.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/tap-linux.c b/net/tap-linux.c +index 9584769740..5e70b93037 100644 +--- a/net/tap-linux.c ++++ b/net/tap-linux.c +@@ -150,6 +150,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp) + int tap_probe_vnet_hdr(int fd, Error **errp) + { + struct ifreq ifr; ++ memset(&ifr, 0, sizeof(ifr)); + + if (ioctl(fd, TUNGETIFF, &ifr) != 0) { + /* TUNGETIFF is available since kernel v2.6.27 */ +-- +2.27.0 + diff --git a/net-eth-Don-t-consider-ESP-to-be-an-IPv6-option-head.patch b/net-eth-Don-t-consider-ESP-to-be-an-IPv6-option-head.patch new file mode 100644 index 0000000..2ff3a75 --- /dev/null +++ b/net-eth-Don-t-consider-ESP-to-be-an-IPv6-option-head.patch @@ -0,0 +1,60 @@ +From 4e18cc43f7e83714da041d69d13265605c22c50c Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Fri, 24 Mar 2023 07:28:57 +0000 +Subject: [PATCH] net/eth: Don't consider ESP to be an IPv6 option header + mainline inclusion commit 9d6267b240c114d1a3cd314a08fd6e1339d34b83 category: + bugfix + +--------------------------------------------------------------- + +The IPv6 option headers all have in common that they start with some +common fields, in particular the type of the next header followed by the +extention header length. This is used to traverse the list of the +options. The ESP header does not follow that format, which can break the +IPv6 option header traversal code in eth_parse_ipv6_hdr(). + +The effect of that is that network interfaces such as vmxnet3 that use +the following call chain + eth_is_ip6_extension_header_type + eth_parse_ipv6_hdr + net_tx_pkt_parse_headers + net_tx_pkt_parse + vmxnet3_process_tx_queue +to send packets from the VM out to the host will drop packets of the +following structure: + Ethernet-Header(IPv6-Header(ESP(encrypted data))) + +Note that not all types of network interfaces use the net_tx_pkt_parse +function though, leading to inconsistent behavior regarding sending +those packets. The e1000 network interface for example does not suffer +from this limitation. + +By not considering ESP to be an IPv6 header we can allow sending those +packets out to the host on all types of network interfaces. + +Fixes: 75020a702151 ("Common definitions for VMWARE devices") +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/149 +Buglink: https://bugs.launchpad.net/qemu/+bug/1758091 +Signed-off-by: Thomas Jansen +Signed-off-by: Jason Wang + +Signed-off-by: tangbinzy +--- + net/eth.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/net/eth.c b/net/eth.c +index fe876d1a55..f074b2f9f3 100644 +--- a/net/eth.c ++++ b/net/eth.c +@@ -389,7 +389,6 @@ eth_is_ip6_extension_header_type(uint8_t hdr_type) + case IP6_HOP_BY_HOP: + case IP6_ROUTING: + case IP6_FRAGMENT: +- case IP6_ESP: + case IP6_AUTHENTICATION: + case IP6_DESTINATON: + case IP6_MOBILITY: +-- +2.27.0 + diff --git a/qemu.spec b/qemu.spec index b1b7e02..998173d 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 6.2.0 -Release: 60 +Release: 61 Epoch: 10 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -434,6 +434,40 @@ Patch0422: migration-report-multiFd-related-thread-pid-to-libvi.patch Patch0423: vhost_net-keep-acked_feature-only-for-NET_CLIENT_DRI.patch Patch0424: linux-user-Add-strace-output-for-timer_settime64-sys.patch Patch0425: fix-qemu-core-when-vhost-user-net-config-with-server.patch +Patch0426: fix-qmp-command-migrate-set-parameters.patch +Patch0427: hw-acpi-Add-ospm_status-hook-implementation-for-acpi.patch +Patch0428: hw-acpi-Support-acpi-ged-to-report-CPU-s-OST-info.patch +Patch0429: arm-virt-Correct-timing-of-executing-cpu_synchronize.patch +Patch0430: arm-virt-Correct-timing-of-pause-all-vcpus-for-hot-p.patch +Patch0431: hw-core-machine-Fix-the-missing-consideration-of-clu.patch +Patch0432: tests-tcg-Fix-target-specific-Makefile-variables-pat.patch +Patch0433: tests-add-riscv-virt-machine-mapping-to-testenv.patch +Patch0434: curl-Fix-error-path-in-curl_open.patch +Patch0435: hw-riscv-virt-Simplify-virt_-get-set-_aclint.patch +Patch0436: hw-pci-Fix-a-typo.patch +Patch0437: hw-pci-Trace-IRQ-routing-on-PCI-topology.patch +Patch0438: Add-PowerManager-support.patch +Patch0439: Add-RTC-support.patch +Patch0440: Add-loongarch-machine.patch +Patch0441: Add-target-loongarch64.patch +Patch0442: Add-linux-headers-and-linux-user.patch +Patch0443: Add-disas-gdb.patch +Patch0444: Add-command-line.patch +Patch0445: Add-tcg.patch +Patch0446: Add-bios.patch +Patch0447: Add-compile-script.patch +Patch0448: hw-pvrdma-Protect-against-buggy-or-malicious-guest-d.patch +Patch0449: hw-audio-intel-hda-fix-stream-reset.patch +Patch0450: dsoundaudio-fix-crackling-audio-recordings.patch +Patch0451: linux-headers-include-missing-changes-from-6.0.patch +Patch0452: i386-kvm-extend-kvm_-get-put-_vcpu_events-to-support.patch +Patch0453: kvm-allow-target-specific-accelerator-properties.patch +Patch0454: kvm-expose-struct-KVMState.patch +Patch0455: i386-add-notify-VM-exit-support.patch +Patch0456: block-backend-prevent-dangling-BDS-pointers-across-a.patch +Patch0457: net-Fix-uninitialized-data-usage.patch +Patch0458: net-eth-Don-t-consider-ESP-to-be-an-IPv6-option-head.patch +Patch0459: hw-net-vmxnet3-Log-guest-triggerable-errors-using-LO.patch BuildRequires: flex BuildRequires: gcc @@ -592,6 +626,12 @@ Requires: qemu %description system-riscv This package provides the QEMU system emulator for riscv. +%package system-loongarch64 +Summary: Qemu-system-loongarch64 +Requires: qemu +%description system-loongarch64 +This package provides the QEMU system emulator for loongarch64. + %prep %setup -q -n qemu-%{version}%{?rcstr} %autopatch -p1 @@ -606,6 +646,11 @@ buildarch="aarch64-softmmu" targetarch="x86_64-softmmu arm-softmmu riscv32-softmmu riscv64-softmmu" %endif +%ifarch loongarch64 +buildarch="loongarch64-softmmu" +targetarch="x86_64-softmmu aarch64-softmmu arm-softmmu riscv32-softmmu riscv64-softmmu" +%endif + buildldflags="VL_LDFLAGS=-Wl,--build-id" qemubuilddir="build" @@ -709,7 +754,6 @@ chmod -x %{buildroot}%{_mandir}/man1/* rm -rf %{buildroot}%{_datadir}/%{name}/vgabios-ati.bin rm -rf %{buildroot}%{_datadir}/%{name}/bios-microvm.bin -rm -rf %{buildroot}%{_datadir}/%{name}/multiboot_dma.bin rm -rf %{buildroot}%{_datadir}/%{name}/openbios-* rm -rf %{buildroot}%{_datadir}/%{name}/slof.bin rm -rf %{buildroot}%{_datadir}/%{name}/QEMU,*.bin @@ -728,14 +772,15 @@ rm -rf %{buildroot}%{_bindir}/ivshmem* rm -f %{buildroot}%{_datadir}/%{name}/edk2* rm -rf %{buildroot}%{_datadir}/%{name}/firmware rm -rf %{buildroot}%{_datadir}/%{name}/qemu-nsis.bmp -rm -rf %{buildroot}%{_libdir}/%{name}/audio-oss.so rm -rf %{buildroot}%{_libdir}/%{name}/audio-pa.so rm -rf %{buildroot}%{_libdir}/%{name}/block-gluster.so -rm -rf %{buildroot}%{_libdir}/%{name}/ui-curses.so -rm -rf %{buildroot}%{_libdir}/%{name}/ui-gtk.so rm -rf %{buildroot}%{_libdir}/%{name}/ui-sdl.so -rm -rf %{buildroot}%{_libdir}/%{name}/audio-spice.so rm -rf %{buildroot}%{_libdir}/%{name}/chardev-baum.so +%ifnarch loongarch64 +rm -rf %{buildroot}%{_libdir}/%{name}/audio-oss.so +rm -rf %{buildroot}%{_libdir}/%{name}/audio-spice.so +rm -rf %{buildroot}%{_libdir}/%{name}/ui-curses.so +rm -rf %{buildroot}%{_libdir}/%{name}/ui-gtk.so rm -rf %{buildroot}%{_libdir}/%{name}/chardev-spice.so rm -rf %{buildroot}%{_libdir}/%{name}/hw-display-qxl.so rm -rf %{buildroot}%{_libdir}/%{name}/hw-s390x-virtio-gpu-ccw.so @@ -743,6 +788,7 @@ rm -rf %{buildroot}%{_libdir}/%{name}/hw-usb-redirect.so rm -rf %{buildroot}%{_libdir}/%{name}/ui-opengl.so rm -rf %{buildroot}%{_libdir}/%{name}/ui-spice-app.so rm -rf %{buildroot}%{_libdir}/%{name}/ui-spice-core.so +%endif rm -rf %{buildroot}%{_libexecdir}/vhost-user-gpu rm -rf %{buildroot}%{_datadir}/%{name}/vhost-user/50-qemu-gpu.json @@ -842,6 +888,7 @@ getent passwd qemu >/dev/null || \ %{_datadir}/%{name}/linuxboot_dma.bin %{_datadir}/%{name}/pvh.bin %{_datadir}/%{name}/multiboot.bin +%{_datadir}/%{name}/multiboot_dma.bin %{_datadir}/%{name}/kvmvapic.bin %{_datadir}/%{name}/sgabios.bin %endif @@ -876,6 +923,7 @@ getent passwd qemu >/dev/null || \ %{_datadir}/%{name}/linuxboot_dma.bin %{_datadir}/%{name}/pvh.bin %{_datadir}/%{name}/multiboot.bin +%{_datadir}/%{name}/multiboot_dma.bin %{_datadir}/%{name}/kvmvapic.bin %{_datadir}/%{name}/sgabios.bin %endif @@ -886,6 +934,27 @@ getent passwd qemu >/dev/null || \ %{_datadir}/%{name}/opensbi-riscv*.bin %{_datadir}/%{name}/opensbi-riscv*.elf +%ifarch loongarch64 +%files system-loongarch64 +%{_bindir}/qemu-system-loongarch64 +%{_datadir}/%{name}/loongarch_*.bin +%{_libdir}/%{name}/audio-oss.so +%{_libdir}/%{name}/ui-curses.so +%{_libdir}/%{name}/ui-gtk.so +%{_libdir}/%{name}/audio-spice.so +%{_libdir}/%{name}/chardev-spice.so +%{_libdir}/%{name}/hw-display-qxl.so +%{_libdir}/%{name}/hw-s390x-virtio-gpu-ccw.so +%{_libdir}/%{name}/hw-usb-redirect.so +%{_libdir}/%{name}/ui-opengl.so +%{_libdir}/%{name}/ui-spice-app.so +%{_libdir}/%{name}/ui-spice-core.so +%endif + +%ifnarch loongarch64 +%exclude %{_datadir}/%{name}/loongarch_*.bin +%endif + %files help %dir %{qemudocdir} %doc %{qemudocdir}/about @@ -948,6 +1017,34 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Tue Mar 29 2023 - 10:6.2.0-61 +- hw/net/vmxnet3: Log guest-triggerable errors using LOG_GUEST_ERROR mainline +- net/eth: Don't consider ESP to be an IPv6 option header mainline +- net: Fix uninitialized data usage mainline +- block-backend: prevent dangling BDS pointers across aio_poll() mainline inclusion +- i386: add notify VM exit support +- kvm: expose struct KVMState +- kvm: allow target-specific accelerator properties +- i386: kvm: extend kvm_{get, put}_vcpu_events to support pending triple fault +- linux-headers: include missing changes from 6.0 +- dsoundaudio: fix crackling audio recordings mainline +- hw/audio/intel-hda: fix stream reset mainline +- hw/pvrdma: Protect against buggy or malicious guest driver +- qemu support for loongarch +- hw/pci: Trace IRQ routing on PCI topology +- hw/pci: Fix a typo +- hw/riscv: virt: Simplify virt_{get,set}_aclint() +- curl: Fix error path in curl_open() +- tests: add (riscv virt) machine mapping to testenv from v7.0.0 +- tests/tcg: Fix target-specific Makefile variables path for user-mode mainline +- hw/core/machine:Fix the missing consideration of cluster-id +- arm/virt: Correct timing of pause all vcpus for hot-plugged CPUs +- arm/virt: Correct timing of executing cpu_synchronize_post_init for hot-plugged cpus +- hw/acpi: Support acpi-ged to report CPU's OST info +- hw/acpi: Add ospm_status hook implementation for acpi-ged +- fix qmp command migrate-set-parameters +- spec: Add multiboot_dma.bin + * Tue Dec 20 2022 yezengruan - 10:6.2.0-60 - linux-user: Add strace output for timer_settime64() syscall - fix qemu-core when vhost-user-net config with server mode diff --git a/tests-add-riscv-virt-machine-mapping-to-testenv.patch b/tests-add-riscv-virt-machine-mapping-to-testenv.patch new file mode 100644 index 0000000..dc008b5 --- /dev/null +++ b/tests-add-riscv-virt-machine-mapping-to-testenv.patch @@ -0,0 +1,39 @@ +From f0dbc3b6101e39ce3bc5d38f34723d1c672a12e9 Mon Sep 17 00:00:00 2001 +From: laokz +Date: Mon, 13 Mar 2023 06:20:48 +0000 +Subject: [PATCH] tests: add (riscv virt) machine mapping to testenv from + v7.0.0 commit 3213bbaf5797cc405e57f122e72c1fb55d0b08ab Author: laokz + Date: Tue Mar 8 12:33:39 2022 +0800 + + tests: add (riscv virt) machine mapping to testenv + + Some qemu-iotests(040 etc) use PCI disk to do test. Without the + mapping, RISC-V flavor use spike as default machine which has no + PCI bus, causing test failure. + + Resolves: https://gitlab.com/qemu-project/qemu/-/issues/894 + + Signed-off-by: Kai Zhang + Message-Id: + Reviewed-by: Alistair Francis + Signed-off-by: Hanna Reitz +--- + tests/qemu-iotests/testenv.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py +index c33454fa68..26ae6945cc 100644 +--- a/tests/qemu-iotests/testenv.py ++++ b/tests/qemu-iotests/testenv.py +@@ -238,6 +238,8 @@ def __init__(self, imgfmt: str, imgproto: str, aiomode: str, + ('aarch64', 'virt'), + ('avr', 'mega2560'), + ('m68k', 'virt'), ++ ('riscv32', 'virt'), ++ ('riscv64', 'virt'), + ('rx', 'gdbsim-r5f562n8'), + ('tricore', 'tricore_testboard') + ) +-- +2.27.0 + diff --git a/tests-tcg-Fix-target-specific-Makefile-variables-pat.patch b/tests-tcg-Fix-target-specific-Makefile-variables-pat.patch new file mode 100644 index 0000000..39091ad --- /dev/null +++ b/tests-tcg-Fix-target-specific-Makefile-variables-pat.patch @@ -0,0 +1,40 @@ +From 83f5dc3719af39ab442cb7fe40a4dd752a82e53a Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Fri, 17 Mar 2023 02:22:44 +0000 +Subject: [PATCH] tests/tcg: Fix target-specific Makefile variables path for + user-mode mainline inclusion commit 533b0a1a41df3d9edeb44d6dc957f04d20ca143f + category: bugfix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--------------------------------------------------------------- + +Commit 812b31d3f91 refactor missed to update this path. + +Fixes: 812b31d3f91 ("configs: rename default-configs to configs and reorganise") +Signed-off-by: Philippe Mathieu-Daudé +Message-Id: <20211226001541.3807919-1-f4bug@amsat.org> +Signed-off-by: Paolo Bonzini + +Signed-off-by: tangbinzy +--- + tests/tcg/Makefile.target | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target +index 63cf1b2573..2d6ec70156 100644 +--- a/tests/tcg/Makefile.target ++++ b/tests/tcg/Makefile.target +@@ -33,7 +33,7 @@ all: + -include ../../../config-host.mak + -include ../config-$(TARGET).mak + ifeq ($(CONFIG_USER_ONLY),y) +--include $(SRC_PATH)/default-configs/targets/$(TARGET).mak ++-include $(SRC_PATH)/configs/targets/$(TARGET)/default.mak + endif + + # for including , in command strings +-- +2.27.0 + -- Gitee

    Y1JesXB^Og2lg>M(0}1S3D1Pa=Ge6uLUWXoE-$zdP#*516 zoEm@rfIZ*;FOKUkHoYhQ3^&i46_nRGD5_d)v5=;H zi&3_R-r1n_AIq^()V%Nyu8#kp_aD~$$7!vy0A=YbGKSZ;%=N@gzUDYTYuOoR{EK~^ z9^sT;rXs<&=JvU_R?a!h9bBW;eco0I6@pld{d|6(|Kzos0R{IZeSV9#0&I1CrF?4d zrHyx(1$8wndHUdU8zN~Z^Eq?#e7pb3xBhm%;Fn@KWb0C{=3{r)q=Jh*gTn>zIXj*y zsF*+2ODNmnQtYwobHxAXCX}^a`My1*o1PNQ?A>cs^vqrFu*_I3Wg=YNhwZ}!$8^5) z$(0oP{%HJ24U`EeBhY5zV!CdWQpSJU{nk4D1957E0Xwq2_$ zD_zTy!Bogy><(QY!&aaw0Bf9mPv^OIQ}MIpxO#O-fiL3iVNWJY(&mgoszyn$wtGeO z(RI(3RS}iA`~Zm+pC`Art)GM|DfQH=3ky58Pl1$EP~w9>bhQX{5A(Wp&pT^S-1Xy$ z1SjL9d{O+C`yL+?@Z*7~Usd(##}CUe)<%EaOm!bQ6)-jaFoe290$DE75hUuO>o*!} zv@R3qyBm^u{(FD?);Z1kW4g;~OeDi`{aP$``KjfQ!-FC>p0MhS$H^xTdHx2dc_;-= zOim@a<^25qV|oJWQJdu8nfv85Z=}ScXG2oHcVp5L;2GjC{PZyG><{{HSwAj3Z!mni z)08$W$*MT`r@W!ychbe7;^`Ycr)#*RT?u72z4FF09wlRQdF|^ye)Vv2N&~ zZAHy_QXe#_hlRgM<6vOqK2gj4VjyQFvwe~E*wlA6%jXhIkN-x!)%a$eUUg6smD`x| z{kN6%TROmpv$FEGyL(vt&!|^xS(9>uLC&M4Gio}@-+pUWNdAPRn}&=n#>_%8-g6*m zc7uCAvm6Im48Fc@_myxnp3AM__Iw+!%m|S!p0%HNf7kY&d|q|exB>Mm*;hAD`EXUi zwjW++$d_UzJpiB&d!_y$d{ufpCh~eblec$NdIXbzba7VamW-@|3qYY*ZyFF_tv_gb zP~l{^>61tLyJ1f@CTCsMx_qFbu5+^+J8RF|DIld4sRFO(Kl4;`^Q}2f1TF`fcxjQwBMX4TdhLS;Wxn=g@(ekts#nZC%irs;vZ671xpvyHYH@Y8WP)4{ z&}{)T-!AJMA-4pMm?9%t#MtI=Kc7Rj=lVXiIXqyKmKK*j7eGh$xx7if06WyN%T87D z_o~i-e?209A(u*(75+NotnY~+w)2IED}7jhPZmTo@N*pP>?K59eK)TzxWCkTM3^3Y z&eU0elv$uRJwBSLj)d=S6an_fhs!hOA0ghR zoamn|pTF= zL)D{@>zolQovxrnzn8ELUcd- z%(ilj%uC&@#q!11ebM^atN9us?~hFVe0@s}SgZT(zx*;=Ij4$ccMlCJ;?O{g+Ac!R zFC>SZJi)a!W0R3i1LJ{a#k32e<|Bs>y%3*dT!;ru=4JE&62AEEVQ+P8*68Qo0e-~? zB=?p`8=^+Ov&%D51CUphO#b$cm4LNkc(kUwa&s)D@p6_-_Ya$4Z}+e2rJRldUVOFN zi?evkX7Zr#lOLr&QU<22#^!KZ_WB{OmJ=YKPsr6LEu@WC$x9_C)fIUAJ*`LjN-L;2 zM-s~lO6TWX*$6;J5&bLJYR8AZkeNcVO@lCRFJ?3yS5yEJ0J>Jw!0d`dJ7?$kxN@^q~)(LDSX;8{1fz{|GJXpQx4>`|mL;-hRgn6q)9ZZ8(LV+E8YtFN42{(yh){larl=)9^(z}!G)wtW$k?w?+P zeio{LPj6EN0U&Py>${a-XT3*4(Pohf$Xy(cohmJ!O7D^bY7f6_?E>tVtB?vp++Ib2 zzp!De#&?y<+Unn|V?H}}GQPQQ9(d2EYlu$awLnpf%32@PvxVH%#T*?}S6Dh$MV6H- z+c&OslD{&_@a3*Ld&~21->XB8RLv8s$#-N0c}r_5;O_p8^+DpRbY?Lu*Dsir!i9fT^A&_`+c|J(e>cs-k<0LjR{^xS#i?!b$>O(s@yIyGA zdS)NS?fZP=y$K8H;Cq?$$0k(-9N9PF#aEd%P0wm_@n}K5Z0b+OLXE{ciRmeUbB9fT z-wp)h91>0_f;@^=UNg~I_Sb8(Lhw2~pEzS?V z`;4p0Z*`e8(qf#4Cs|!S{1{zXl)L9yush)mEZv;Km#(LO{Gn6Pov=T_*-9+BlA@ou zrXSmo(%2A{Y~K7~N#A+vNZ!TX@$i38bl&k)e}5dWBq<{rHWg7>$(}c4i%J>U$;dUb zUE_X4k&H{S$4zEmJA2(rXXxaPgCyMBIuoqykt$2sTyKIid%zg|zE&S4hH z927ijrc&UAVVlWYjo%{VJejSvb;o?2HJbzn4T1|OJdOZzXg++3`>#oge(NiDP|~Y% z{QXiqHt{4;6!zf{BJk76?LvV^M?dyLfE;7|*o>-$@xq*`O|9|**xSRn%Jj8UXgDwK z)Sfb4AMe5U#O{{7_m^3U}n_VN=Eani*r% zQ{;)?Py7a>nK-S#Z64D8n=#rzN_hGWE^;I^mSN!UM$S>ROLGa2Q;np`sTQMv073En zJY?ma=RB#iQ+meJ$ydDTk9No)mOj%&3cn~w{V^2#zH-dOl!&hcH^w}Ei*?MWas1dk ztQ)n%cl(C)+$OKpJ3T&mL!guB2iwz9>e}iD%VwedG7?ozOvmJV@pMvPHe7U;KY*do zByYblW?>+X{Td|A6lM$+fdXlR#1n}*-qBJsP4Mk|H#@1OFY~u>sJzVAy9BkW4W1@wG^ul&icj_XGUH9f8Tr*Dl3_|D1=DpTves$WPRukyEqI4LXW9>%mnA~hiQ-mDyNKi|P< zC&i>HC&@`#@mlz|D#~FRTyS4_6&vwMW8@wP-iNj$k@TSp>F}U6*K`U+2O8Lq=G#AL zp|srxN%x`INYj86$aDaGb^oB0;*kn}vR|tSoftr?kgUW(U^VG!wz4&JT|8M5m|cjq zB@*AJ0$*ouut6`j?i90gjOx9Ke=u#%B!WJf2*|rR`+_8RCmekh zo^z{;JccFFp5V0hL-lEc$soT~wBT)^O}Z2}=5Jv!uJRHiHhuC&C>YyXt~+7fVp^tn zyYWdv)LFl+l>_b{aRW8t=v*cjJAuJ_2WvSGuU*n>1D~%l!3Uq%|HQO67wf}R-er_a z*VO<;LBmJGZ<}eB$QE3Hry%k1Yyx&SA{SD5j)jKA1*5EBPKk+T16nz~Ca!0La z@_?j!8ifu|w$S^Q#SNyIVGhrA{M#$o!d}Vku5OTJjpo8u$f~=6%XxqdRICb z(XT;MHt4z0pLbcY_XH98a0sBknFhwg-j>Z3OD7f|z*pfTVK-kN$BZqrKoUw$P9qTV zCjy~v`)NA);D$o&AWy3sAudKDa-_`u5qY$TR*<^vt;0dt;L15=aV2TfJ@f!1S$MOp z%~n-UDQ_-!dMu%>*1Ews|4uPUGD^|oQ2SwjP3+mWTs zEDb25^o(tvuNcAoQy79toYW{5dLlpapV1-s#}@6|`Zbu+Oi|)Yk!Bi|>GvxL^C8*o z+2-%>C(xVg7>9L$*h8_qB}}JIIM8uz3Uza>UKe{x+A3Km&Zgl@lo}fMQQXqB_LC#{ zpXk7~-v_h%_YW{BLL^yJV=IlPkJI41S-j0Ad8&qM(D1^HpY4wx-ZI1wa8M_SSMX}w zmvn>~Z+n|rOxEw`jMpI=n;OgnWt|sh*$HVVF=gcJwPXM*YB3w)LjWJGTM}&KP3P*H z4SQ70dsKA=FE6*#uBS|*$!rC0$Iiruo&-ppnA~V%i5@`8^Cr&coHuq@E6iT$=vy}Vi#`{RL@V3T0PA#2galW zL(+i+KsvDA$2yP>JbZQ+(u)ZEr0{GCq>?fn&|fs;$>DgptLWAq8nrVSa6Cjris8FBJ^KTV>8{5q<+)*dw zwchadkGls@7t-Q`Uu6B?7X?dy}Tt=n>qu_`qQr zHT^QR1eQ)L2?A9fIdzVYw}Wxdm=;nFYKrrsZquM5FlMn6zuXAvolK#lVXIT@&+$8~!jpvt)oq7Yf$qx6!`g$+SfImxfg?uPW>~s2R|32^?XuvH^ z>3Vx47S-^ilNr2lILXd>i&EFeb_LsMv(upEp{REML^VNO=b72z0ueqj7{Cm9vIhC; zCOBZ-R-a`nBM;x*_p4ty+PZO?CG4d`W{>}y>uKbloyu_CW9!(%93avHLaz1Vlsi*MKIj7IE-2HMI3kjlGLUu_Qt z?H6EUjGZlu`)ZkqpUx@UT~;ta51%8YBopLYmZGZ!4&4bL z_iG0Nm9#Gtpf^;YpcxLH3#D8J0YO`sx_O3@Ofc9Exk4&M)j8OG8y+vKYaS$<&4cr* zOamITXVL>;z>!&0xK*A~Bk@KQ;f`B5erys{5&|au0@vbTY#$3k-Bg=ap1=N=-w57) z;nzxVmsxu_`*-@yaDD(1+1rNDlIVgQCKhX>ehy1#H_CXMLg!w3x5R>^*{`8JDkmns z{I}Z7gK{bC%T9^g?o^iI9m>OJeP2+?QA7x)t>7*LsAH9PH+PjDIM31y*ZJ$gpI@1_ zFD{aeeu>+nR!d5PQL9by%>f6FG>H4i1qfnB(eiMwexQzEFaH~tt?rvRirU{yf^hg0 z_?g_A{gq+y!bI7>_2skHgyd~eSOED%sljxFaC8G#s26ge1ZmsBPW9y8lip!}%^=_d z%Jl^Vs${ZY!PK^m zk#hWm+40eOBVK+odmg1#MHL$$fMVCrPNMr8=u3ZS3{u0Dof_ix7+*Icp1m$NC6au} zE;L+ja|BhNUMTtxZCfINSGoT;a~$k0qW8Fgm_8}9KjUBqPay57alEp+^3M!739--; zyqc9}nmW6hTUO{5GdRn+7ryPZyk&5T)>M9YZzHC%Qq$LiZJ*prt0MJ7(d{zco^pT_w5Sa23-BO^V;A_Pb2C>G z()_-h-{SjFfQ9T@<#*o|im&im7*Rsmn*hyg{xL>Z z*0-AlR-0n{CqHiwst>-uIu!cZ$xUr2vm%#H93=t28mQKk(9c3O#B1p9HN=w-i+SI% ztv-Q)0!BnC6RA=Ru#fj7otJGW>^epL%ILT&3fyiGyk@<3o=E+h@(p2-c#>CmLP*3k z&?~k75H;Qg#aj?9fSIEY6hwcGY3Yi2UPhaD4khpO4;o0NRY_QjbsODT=54MrUQm1* ze>g!jKOr{M<9zwv#`^^EDDtZdx;7W=J_}v_nq|pWJx5`R0mESvdsqL#WW$!1x9#IQ(r}aWa zhJ1VyoNRz=&+PFYa}7WgNJ`@k>i3H=FL#z6o!BO@^ZV0{wFq$*%=Waa5;Xu)|6q2w z8;25H!o>Oa!V}aC3kjjnFrn(bT)i1Yg1Zo6(Lpo2Lj2}@E9)$Q{xr05g`9W-qD1Zh za>0|+)6k|kLR`QXZ+Svo6#G#M{CK*6?FEq?n4mTY2$Ykz%ULFa*j{MvGF}YU zDBKnb@&$dxShNr(Es6pQPe(Ru&nHMLPpsM~)}yV_14UFt(^pR7CIKs7b=EQ*)BJ*$^j(B{_~kTdfF3%%ePVEfLPbVI$d0M)9$e!Z_o!=xc$ zQX_Rn#_@SBmBp;+O%QpOD}D$GC@)JDG?{*x`J1Tl@0sh4J8h%zIG*c+u)fPo{-OY}H!?&PFOs6>Y*RS=$J1D^8-_WUR>y^vAqpz{^_@&r#VI zyqrH6h9=Vk*AEBp9RU-GYZ?ExB+-thfUTfW=;yH?g>i?Mbkf%2{|z1?5biW}@&f8wKet}?+Y90uwmzowdL%^NqVI3dtEf|_ z2?sk@%QPy*XcUsSRbcQO_*f!VwcuN6a~qldNt2KF)03pF$2B-h@A=T;)f392Ay&~o z<;1yYR^;w1AU+aqf~mR@HL>>8M*Vl@+bYDuYohj@pOPof1sK-ksY|a1$HE|zn|~Yi z51SW|#2*RGfB()B05d^)8~6b}vy(0th!-4lyq2PZ>IW|j+drgWX?tqfG@gX_D{rV~ zZ2Mpr#^s@*JImidQnWiTS=rwUOv3(&|NW`#v#Xc^8t6{b>F$*!#8LB1v03q4aq>7$ z+`FPQx6;wqIa}vV_RD@aGs&Re=kQ4~F}>^!5-=l}#%wWoXRB|!EQ0OAytLD`1B9^~>>JKp2x_^d1brX1ZLqK4`GnOFtRTTrGx z+aw|m$xrz}M1!G6n^!q&5xf1;I}r0Xapg|m2CG;gWNX||?1()1zV-rby-L!Bke=z( zxJ?}1PSHwnW*O}-&WkG$>Z3xm+*W@ANgG0YD?7?c`+0AM^1)teU{f9w}$N+Y1FHa<)~RH_ zb5x?ZAog}m>;!`fdnT$|to<{w6KX9<9JkALt@R`(bI=!M7DyJ}t)bsrD;iW)_bVp? z?Jo}{uzjU|#W&ifU@!~lhdxhQ%5Z;7s%W{-0r!Qk{gjbA$ujwBfX&>s&)wu`ug{5_ zM~xXo{*M-ViRE3msD;~zO+dcId)%I&UCS>VMQ1L^Qc7`DP%It5RI~YV@!_<5ft9 zC@9?1cCCTB={2$WS4L0Js9}-6s(H-Xe)bO9bW#Gnsa!N>9mfiU;zE}z*JOXUvfJIc zP#D!PG@C4bq5NVW*x(kR+bug#b)%$6OkYDQM;G;Ve{JEwommEA_6soirREioNEnvX zvWxk&&1_}={&@PcpBDD9_G_{qGc8~=vyUeZR6KRF2ijPg+5G}RZ&3Dfb{!dE*Il!WAv2p&-wv3}kH44}^LPIvj<2r*&~kG6c}99(`!fMflh)`b zNdfXlYLZ!3zZ|e}q@xP>y!qQ)Yv$+|25K~>LwCGLFCaOTtWR6JJ;vS~2jnmV^qtWz zoyR@2H6T6ZKArT@gUo;*y0`6-?zB|pi`m`r3!RlQ%W2TWAl9JSZ2Plvw}{>z1p;fc z1d9O$YCFK1EE$v_kuEGn`u+pEwW0cRDDjF=&eD+3zV~32jqfYFwOBfrrzxL+PU>2j z$^Be!mHdxqzPu2-@UtzWpC`{z&WB;2u-S zkN>P27g{ky1lg{d&U&bPHE)vu6{@^Sc1YZF5WWbxw3tOX4!c9RE|SVHtR}Es{KSfR z&k?Axg9nabpSQJ$-{T5jL#Y1pv%Kurn~>Et|3~QW$LDeat4D3H>6Rx8*NXb%RzkCT z9Q`(@@*-*+r62sGSRQ*7$n~wrkp{I=CdFH#F$wu7Uqe{H&C6@IK)daB^NZ@|{j{Mc zOMFlM#hplZG-x5ttC0nFQ#Z@Mw|x^9@~Hv{r*(vG?-U9{)0$07-l@(mr(SBe$}JL- z&BGI-a<&*%7K1hrkp|BB!J#Q8UxPpK)wzr{ssDL{9%=qSKd;MAlwPkKN^3!1%;Xf`nH4E^9n`w%*lRd4pSgWO)@3 z=@|dD7m(w6+&MXl8y-Ilaf-8GK8cMw%DOMNE1$ZAc1h*f&uxT^}8Ge=a_Vy{O&***E!_5 z#q6tn(G5y>OaZN<&Duw&v+cBH?o*$X75;)sK2Pwu=|;c2ho;gu$xO_!*0HZ#ZM`r$ zL+E?V95aR`GS@&vXVKMA70};C&nPf$sLy;Nj6Up*>VNCu*w5OtVkJ^_0KgrGHIGeX z-fq1;)5>r9xhY;A@+{E!I3!6{;Ehc3YP};`pdXwvQ&<%tbL=3cg!EhtGF;;I5RA9> z?8$g+CYL17w|fgl;?o&@)`0sPuwZ?rfj=zt`e18x&bj9PqLT*x9n|~bzvptFVyY6; zjy_SY2Dk~Y@zh?`E|AEpIt6;{sGr5SS2D*UH2iOj@1}X@RN|1T1v0ybi7&`oq_ZpLX0*|n_7J}1`_3f;fb`Kyk>}@E z_E4cYRL&Ad6Y*}3Le_doTaEM|#V+;uWb>3WXanKBXN>epo)U)e(slsE5IApOqR9g1 z%PPz{KMS9oyR3$QoreW}alK%1PO!;~eCZv031J$~c+%ezE&U$fC9}N<8SHw{BfHDC z3YjD1)=wd#oa+=TYPr^t0{%BJbjG$*hdk1no888f&nrHkg!gYI?tUCpT4v?dTOCtw zx+D)=ol326kX~4&Y69G1ZTzkYS7$B+Q;{rwp-#S9N?daq8NP(Ph)a9rCS-J_K*|+C z{0|xY>>@QTLQ!K~V_nv=E2+~7{>9dpetu3U4hBoj!tuUWShYQ?%&6dO>m&_nI}rL1 zW=NquNx46ROlh9*fHr4ZY9`uOony_aNT&^-!Qg|>C!c&4+6w2^ z16S{QPHMHerh?hk=u#b?59TEAJu17)|=#(=%I2SHW(az zrJw1^f0Ppoxjkn1%;I0)qcX$lzhD-Z70`uwSPb6dl$QtB;&s}I#3;hA?h-WeXGG(%1bnU7xFiepTkW@o1beeWHqoV2p)IuDQ+ zuksyRK5lt)w{rh3xiNBd4eLVn`&}OzJ_s$1D1=GW@l!P)Y_a>^!Fi(Y#zTkNW2>ZL z3&;#pN8rCe*Sml1QcS*^zCC|jvo8uu66bMX0DWql>G)4PjCy%D>~^_R*xmPkl|BCL z>sK-EC?6-B50r`7w!N_#r`#YBC~36gZ84VhZ)Vc`Y_9xI?B?y|x3^;PEXC8$=v*4M zRkTr8!X>WpdQtT7sRwJ$`A&^gE}eTpS1iDeNbw}#ymC@@a9i3D%(+Rg&@+kjbOctOo(pUlwl^WnFF#RTGm8y84{rClVsCP%Q}9n8M~lVw@>$sl zefXpB4ja60BxY!v$(~igSh?bv^{4QvUZ(7S`%Z!l4A5=v$^V*Zst@qbTuCx{Mxq+k z&pt*0O~v20{!oB#GMtq%{H&x>wN-`tt2)Pu){T3Zrd{tm!Jv>%6ap zgGaQfIY4BDrX6AS!$xm>yX4oaO&vtq*ZMoR0kiFN2)&DQYg)7IfLO4FJWof9yw{B< zU;C6y-Nn^U;=~;66ap&fL|t1Lb1RpFq`z1bcIFB0l|J3`TF~KCpbt-=L^APScYpPC z(C7B|Wu@&+z79;I?5JeM1cjIPOqZ3*uWq?rCkDt{Yw&j4;mReYT10ob78#a1V>o^S z?)1m*!Y-1CXf=%&X9*@-R;3&i+oK`dF5In&@}@)tygb{Ay3%S1#1Pfa;2(uom5Ko4>J86FKRLh2bNulv@9gGK+;zxXIP3dfEja35 zHQyWC%h!IX8W7#yi!A>u#AnEqNBH;~`*@ zGcYbQSs`=E*TIQ2d3|nPaLJ=r-yLgR7rETQRbY%I;m>EbGOuUr++g`VR^pNj1c01k zBTz=fhjxU&k(8hHt0{=7`hyqDi6g(j#802w#f7BaP}gK1iM}wvgkrVgc?^gm-`l~$ zGbucV(Na<1^GHKaTxB^H_v_IR|RI<*7d%5Gp8J>e3Lc6%-viT6~h+Zo1jzYW~tKJnK>0BnpDS z7T0VJ_Ph}oa9;q#_d9^A1-30u!CF(ZZ&}?uvQ&>l(=~UT(bAF|ymq=o@r|Ue3x^uK z*t~OsYteFc)*TxC(u=eg)zdmj1IgXni)Of^kU2hR%b@*EdDU)F?spvU-}2PH!S2PA zh4Y=n&*)m8t;NfmG|TJYZ^^DrLergo2fTfG`9%+Qj9Yfrz2GcJljWUvV{I9mUoT8r z)lK|c04-!i+y%AgRW1=^LVVO8tCo+;*j~a*UPsljFHjSaUft+P@qb=AfWVNoe6hWF zFVdD3@9?B7;yl4AekC6O1HlcZn@`p746rODQ)ss#yt_G9v7b%YBic7+^4|L=N7Wez zg%0WOB*X@3Skl$ml+KfNX(0!ynl;lhWav;lGxR;=)<-PuH3XJil5xbHdS$yb`z!5{a;`;D($A&0 z22z-xP>a8qvdaIQ&1}W-)$Awk`UKfyD8u5mfsjdtK_tFHP^@@Le1eXxk?FYEVv$nc z3NAIp*Ke#Nfpa!z6Rukh-Wx9P5v;832n|aN&U-0NZ0B3#A((wVllwU1W}AKg!PQgf z=33@Abj|()u$@0J97Sp}$i-Xdal?^sE;C45%&LKhP=*c>Uz-(=2ph*yFB@2P&*sOt#zdnP0o|M#8xn7~Vh*U)iR zgP@{XZ*yR@@A4ZkYF?AxJ+M@d+7=(%^XZAllTvLex1>9A z#ASxvV#nn`w}^owEpLt?SC6>fzCg_RQw5#I%y$z|2|w+3%v%^1{f>E=mVFzG#_4!L z#q~+2RYuR<>r&FJUL-_xDb2o-VtgSPl*LB`9=g@hKU^96ek4wtYPxXbL`|E?uUB&o zH5`F`v;ie@{gma|pvC;!Tf5+QckZ%}YVWXNp0@hnnqH2!)2-orbsOm)U;ez9c$%^E zU~ro=qv%?(B1^5I)@4`6$L7c`XZbu2!9r!tGM8kbXLc|yf7V&Cn^jwa>)fMI4MvJu zKcHLoom^9_>1K=j&hE!P$8M<|E=-a}5p4#2RZ^pIot!o}7z4oK6jdI`6fG;J;J6OXeIQa(AuV@aP+9|!0{i>g^GOm(e@bdE0Z0T-+T9*RMz|P?N<3ix&=r3$b z?1MK7>axXtDuj0ZJmT=LsXMKHm(+riM&WK(EL1Hqibbhfyum64yrE)yhXH)Uv!rHpI&cMp;2%(5$qye=f zlxM^Ia)^IK9%vRT>*I}Wx_V$Kv>%L%YI#I5G|0%)#wRc*Xy+XlF6C@9@-QSq_~XGv(n6 zT(j&qyR4r0v~(%4pYoUJzQF3%V~&!975|nD$pWl>Q_rx^?*miLSQ^dp;qCSO+b|XR z6ryH7`8BhUwOkK5TYuyid1%)ob~U$Eu0e6O=*4LBik0kI9n|5Uiy1gVj`k&~-(|2M zrPSjE+p<+if$oq-dF_(yTy3kJ`kL7m0tr4e zhOMgeRwTYmn%|WA8M5FSPWiIEP`@T(fo~nB8d*-sJ@3kgvO0$sSjEugJ2XV!doEWe z@~@L6aKQ9kKIQo-(?%=LBZSN83w^$k<+#CUcOJDD&=o43Nt0Gx_b`{Cql+nQqo8#j zv(RvfP+&Q*NHm);V!dMD1j=48^)k7@lOJyTNLzKvP?VvUyt=NmG<~xon@a)wIC*DQ z0a6%?!^rxSE6bJS5g%=jSa8m)`ps-*_YIrN23U5FKfH=Ib_u3LV8P6SVyM~+4lrNd z$-$hAg`Zh9G}_U|c1HsDWy`nZdvnsu*w)Mtpdsgft7Mi*O}kIvd-o3K zjMWM}#&3?nH|-2-?{`$0DL$X7nmS=z>k|8Fhm|~h#p-mN`zQ$Zx@a=_fTiK01Blb# zxO=6E0}V?U34ebcjaJG-yZEyTrB%>}9?kNPrb=mA+%Pz$3-764##8yQP6P4aD#cGN zz-fpA-xRmD3>t2^%18@zPAbR;G}vNUQCQBx3kQ><%5$J`WTG<=uNtAf;(p))Gk#C=pdOJiIlOvzJ_^AmUB#aM+mrOLLyyXaOxW3DuzSta=*eN*hn&6=V zYj)8z{_HgL9jtS9x2z=0=ifa6syk!Y0MklOJ%rDSJ@A|I<4;wYN#WO|G}{@0#r>lz z8#KsDuFRU8Z$qjkx?xOTt0+)tPjT3MLm8fxW>}T&f+ERtn$k@_mE3NlrC#4NkP7A^ z1KBREluu&stHdR*PXfh}tXofZ<23pyE?2|MYP%Hc9)kqBV2jpqb?yh&OeJ=q^N-Tf z8S&kW#Q`a zCtj?Jc095%o3g$IJxV&hfsn3i_c8NW76l_yEY}@)#uzd4{Pm znoYGFSrTp%Jc>tHoeoTT8if_B!)q`inEPj>Queo-%jk!X_$XcsP|tJiDF@(D*5Doc z5BA8E-2tV610>&6CazBo^d>Ohx_ZbpXR7PnM9{54koq9fC|caTeEbdt_wGB;yNPfR zQQtgE?ZkVm`FmXH0p>QkZEjhCG|5*^!qV@8&@m(uvk=~0jLdg+WjZK?)_8Do^gxbe zI@(nzc3nRI;V;v`p<^CT3&J_*_u}KxiIQ^?IQH$9lh|)DJ2J;DF1~ewH@dAzGyR*Z znS+P#{y6-6**8q)8JGSX65-eJ%G|e1ko&>&4ccFce7j(YS^&(wc4q0n4JGt2&x0wA z$qSl+DzbZRzxd;f)w28EXhoBs1>fjCD15b-v+#z>{zCB70l&$OYWEwviH^^)w)p~~ zQcMOZE~NS7TPs9Ai#Wmf4WHlKl!Y9QA-n)5w8TecgC`!7cFewG8fiKEm4Q#_phV3y zXWwCa1Z21i1;V3o$O5qC*L`@&w1~+eHG5K6+{geA=b@Glja3QaFZ{|&?nZM_LGLvxN?^}OF zF^P@)6mOCm)7Vf(-e11!9pS(4dhnMmOr>~LC<-RRCMJ*gi3^9gDn&1Sc(AR*+YtYD zpJI`Tz;p5CY|3AvvDY59EMt7{GLfEqBY~H0<_)=WH*c@Yx-glv%h`GQ6nz-xEzz;& zRjs`p257V-4R}6rI?^hqQxvP{{AX<2%_5~!SHumR0PN#vQzNH(t!|=tB3`y5DE++s zhFoZgbZRcMHW_%1Y*umfbNA1!e)KE*X2)R49I+$|E4{4IqZNLyis7NUo4aJe5wqeN z&p-c%YhpXUQKwY5x2{JQ31I>iOnHaXTN+expdc|XfYX{?EsyiZ-Yp==U}Lg#b29T6 zO*i2!lMZytz)@af6?Mwc)DZ3@N}w7=8HwvU|3X7Wsw?;>7^-bKfh0yE-L}-K?Kk+w zxZpX^%}(M2)MWPQuNbohm?l=@V-G^aGbf3!-9xwgR>J{-^agrZrb+gF`ys%~ zXFsi~K92%T$Vf89Few(f3|4iMhG|@@Nf&Q!f2<*9=w>$fc08qfm@}QUn^^dX9pDKI zZaI%m;72k&fcbE~k^ij9O1;Rc#4v1tJ$5cMkwdlj0Ct-T)UEWj5?z`QZ=}=Tb_1AMvN8&@ zgL)yz_v7J8rgK~}ruG3eOrnADI07uMKy3^f83zfp6P@%uuc6ayB zo!vRcYm@o};|9^0jxag1`Ch(TAEPv~0+_qVZd>aIbmmbF-az_2$Bi0MP>pV}` zA8f>Fa2c3ijAcMky2USldEng)eI7ZVfyO}1w zw#SxXU9jGv6%y)`SWSXOFZ1`}3eWe^=;ax7{ky|HU*gqup5y-e%*EZg%76s%0lBAH)JIj17-HXjj#*gr61q(7PZVx zuMoMJgNc@qvjiSokbOjZkN%2aX-v_{Ho1ALr3SkummU7<^WqbNad%I9G;$_FmQ>ch z!O%mNiblR-YTU}&H zBG7pFPocq%_de~>NfZ0-huyPw1{aBEX?7#?H&#jZdYnKh`vMds`BA|PZ;8w?J=C#g za@0mLegtOPT#Q+wDdWsC%N)uwhwY#U1ThIwa(DE^?#`+?-y-6NK2-eN9EcTsr)mja zEK2vkvzRN~Np9-Eu`SwaFAxGLV_3XW1Ny@%kqqR>t07o7@+LgJmW zg|I_p>-eBI?Z*4J!^cu-yOt;)4xDA_2bg4Egl473NiSl7H3$_|BW2?J^Kr~J`9 zSn`yuqjXPw!M0RudWC0nUF+(?RLvEPqz0Sdm4@SIA0!dC-}qfwByeNxz2DEg$ z5=$TNo_s`d?seP10i^@JC3@?}fU;F+=%Bpfw~}z)rAC;F;^Q-Vh&Sp2n`qG8nsnn^ zDbn8i^09+?;H7E!2X)|lAP{63iM4x=t3*t!lg zpQyBVgC+)aMgj* z1?q42T*6KA$Wn78=OHIRAH zXp=>Iw)u8$ur#2O+FbegXB*Ac@X|zZC5pHH0qt+uxatj9&)mR7OijYeH)g8IkRdyQE*1*WEm5j>`z6#pvWFRi)OY@$JlR= zV4facX$kB98Gh-f#xk_*xyHDzW0D#@EtI``nj+dZPpD^Y3T`3W(h7DWp$7r^rSuRT z>AVQJvd<_U1mZzh20y^nLFHfH5!4k1;30n{27tAj0}n0PCs-D&HO_dx_(hbfed{7s zsZG1RkX}-15)l*h*W-m%`}~?C{>>gnD7ptD(MfORSVpyt+!K+v)OyZmWH8J%U3g(t zp*ld0vUXo%Yrr~XNm}GU)*3Qg;_NOo!1WjV>dEu)QS?hf+t;rU%uV?P&ath~YrE7h ztHHqJm$ilG4;PI@oC69Bo(L>xnu-qKg2`{~4reXP>G_=dK>>Sjs-(YhHL5Y5guHTe zdNxuHXoZM#_DWhdl5HvUvioC|b-y&ovi6bfjO*|<_qKqTtS4jlmnEcssmU=SC+Gh( zcJQw0-^@F_P+BjKzci9H^pE{3N#a4!l1&=GDpxf9pk(dqrM4K)Te(svwlb~u%*eBz z;^A)*w*5g7XAS(St$BzpvgF#;Kww0`d+?KTN!#6Cr99tmsroC2+ z?b?KU`A6QD-Yjpwj5=++t{M4_iSpQ!Wt=d%YgRTAwHJf#>6Fz@EZ7pyyG2u; znk#B*e2e>>zww9?jkp3+)v_mXh7WP!4GT!$vWYoaBdmz@OH`X{cwM+^W7$zuV7=*W z%)iTOF}L%Av`IIrYqduMbBuwl&?SM^i_H!4&w;BSY0;`i=G^%V1@@LY!!2bYGK)gQ z-`6$8CT_lqLqs;OjabCPi9g$7M^8Fk`$VY@pr#4*Hji^r)?pN$Yz~_L=K@K9K97+J ze0ivSeU-84-|#-h5~D@&GNY?Z3sqJn(%yx42LIXh1cK?mh(a5%c>r1Mt=Sr~W#1z} z*f~&*(s|Gb5}tUS!B>K0?{cqF$OKH^2Q00KWPH1?nGR{Mmi*q%G-1&|+aPEhw_A=O zR@Gp*A_kgQO`?|S68MMLq>?a=>D@<%%MSvZS&pAA^L)gxwswRGHQ@);U=VQE_WL!E zinM(kFD>P^ALW1_fcw>%!up+}6tx1V8QVNx1G4`* zxeT63uy8;h1=XsXXZgdfo2tKtr(PgSl(Yo?nvHu`m6}bNxD9_(#dz#sUuUt^Ncc%L zCtoC5W3mX=+4;7I(6|+y=84>dG;xCWN*mWi%*&}vO{+XW9I^%7w1UztCS8y7q5?Bq zwE}}gWLb7Nqp~~pcZdC74~LW|e}YJ|AbZ)yY5A>jxZ{i|X>he`?~TytpeLcx(PqmO zZ7z(o@D?;8SNuKIvIBwnh)qA*<85nwd8p`Z;UV-Ye?xrJg>G*V>`A_sV(Mzb)f0`s z^td5YVg?ZTY~!}BPFesK zi$}UDfQwTsUy3<~du(tUpJYxE(p^6f#mocStMWHD;{u0n{UC*x%C@Z&uQ3lQFrb1= zSizC#2z2WPi&%%M>wDI$?cp5LqH8lxV!}N+`+(haYk9Fj9!ay`%8!fu4Zhh-{hfP0 zPO^8jI8cF<&y*gtYo0S=^mr}?bGqemZ!z5HTqv$^7x3S0yU>ao_#$NMkL);;ke5ria;?Jwzs`eYt?f6Vx7+8^no*I1q z%m$$TU7_V;ac6MsgQ{RiXpHo5RvKRf)>4}vgFLqY3%z8BT1zZqU;TGdrXe(l=QD>` zQsdP_(Ehf-uU0)g<>_Q@J;QGJ84dDMt&j%!aQeN*{8=zUY*FBto~q$7%YgH7!)8Az zS!LVMXZWRt+UQW>_n8oTQP|Zh(6lW#4A{dCi$eEUI4T~zCPmwt!`E>}N%m%!riui% z9@_q4wv!l^cTRq2DK_!=ulB2uEUatt><_1aR`jo zlcn6@8l>UJm87LGUw^stOU2ZiP3!te<-V#;*7>DN$n;osb`+M})`d>FGA&~)Ie~XZ z4)Ckh_{JD_dGoq~wIpX=i>Eh8Uu@P$+c}ecoXT%vT?0j9^iB*j1*?aHAun%}+$SEQdshRP;hT}@6Ekjh_P)Xw=R)BTM|qd#okF%>l$uYtSHI`1e*b)orQzvB z`Ijsg#kXEPbG-(;5+AG8AOZKjxpo6qo_TZ=AEAs%Ilo*<_?2o5(%})5ldL-st!6Hpw$EOYyZ@lpcl{vUso8A{m3w=G)Jrb6q zCi5^`zi_lI>~=6|@jNKKn*tZxu|ew;EBkcDx~aS7a-Z1rJ@swz$r*Sn(c1@THJs0T zA=P@UTpt(Zmxd0bW1G~Z)0MsH#?^F-JH8O}-ru2W*DN60N+kjT6j(p&9D}?hqe?S3AkFF7JNgJV`AH zkT3_%3ydzGv3Gh5^Xx-K?*K3*^P#%OxPLP~HMF;vk5J*BK^jnt2G&WTm~~;K=P~V5 zo0{;_ns}$tYwJ=FL7?4F-8GZIHVf0mH51(KrfKJ!>JV<>M>m3pjr6psH+8x>wnR!~ zawT9t8IRn8*#?=vaIdTu*es-cXn!PBVW>E9A#pk4nV;(OVOQ9PRls9soOE+`g>$;{ z#?K1SFQRg^pozW%{Cf3*FlCM(N7vIGZY1j~VGQE&7Z!#Y4Zq-^!CZam;}#1Ev)?$MkhX)h{3;G zvikI9pBfXG9F;xBV_C&EQN>dq%%$5JQ+{ye(Sk>l$ok+~m$P7r5@h}Y zqxM<1`TobZd_Sv_9N$kV1^s@iJu@U zZwc5GfNd18I{>y-0$VCzFaLFCaI1hl3$S}7urCYP7J&U6?N`VR^R92#=kEqST}u_e zYZh4_pzvEM%Z>d5v(plD{)fNvJwM)=xC`L$4hYyzRTi{+e}Mkf$=h9wYUdX15Wd`c z*_p;LYTvfU=H(;ngHNww1fSn!yJa=C61MmW8>w6d~B>XjRS4) zn|Gi+SO|EFU>xwkH~@2H1Mu1ab7ce2(@+89fQP0wY9i+`p=FH+;eBmDLn*CkyocO$ zt)|V5j?bNW4-$JD`Uf1uUf`iQ^>NBRZKbu#h4H*1e_B>Q_sRuv2lRhD&+nnll}WU{YNhqR*}49!acWC9X|8{qond^oufm<{D+HYQeO_L! zuLQmqf6;-ef4I__mqiB}e-np(k{;LPID1sy-uJ(O@sDDSGS!WFd2#M&73Z$7uRl+t z``K^Wg#YUsUVD>Jo&(-|?rPpQ$oG2SdnNE)27GS;zH91tiL+Qazg!YnFTuS|;O;ws z?Z1NdpF#U(Xn#7O()Pyxl$@jAc`>9>NWVxZ|A2~AH6npX3+OpjFPv5NUlS-~(wRGH3nyx~`~+-r#1f@i}DY3e2mEmASJx`loWeeTSU07oO9`P_l^A;FF|?3v|0 ze?@t%*Amnnt3w~E_gbLrc0Q$av04%Z(_1wBj$=T{Lu^bWe-0mfXV14Y965laY!jsqyYTrWvSKm(zX_j% zk&pi|(3Pv~)(+5JkD}~BZkmm1D&}H4h<%efoN@F8HI~c|>Q3K=X-@Q`?MC@O2(ZZO zzr}H0f#wFR@o2!|JI(>@O=jz5^}mJBpZsyJhOz=#Yx&ASjVc>79Pho*rza9me+!q> zgYPDiBOssl#xd`BwU@0|Tw^}3)hvs=TEo9C%(p1z8s_};kun%-sx>?D?6!a%WGZiK zXiqrzz*uxRAK)|S_b_jL<;R)|`7md7F*(&#!q`=5p}zuN)84g`k3i1N^=Fxk2db>3 zV;9f^w*N55cx@2AH=SbbQbE2se_&@5LB44lClUw9H>c?c>fCB~r+q(N!*KxTO&^TM z4~g?v)snTw(m(Nff108>AAq$?HL3As(0G-vH5`==JpY(scV~ls(O$EGUI(3~IzUJG z8?HODK~@g>Agn!F3h+00XVnU8FUx^|bR@7E-x)p}-%8)i1)OOr;zT`Le@JaB&xw)e zCrPLM1xl5ZGWp#fOoVaZ1&h69mBo9?kpZ%{!1$av-#1z*M;-qkdsiPEMVaQiCxO5i zVpveKir7)miGoZ*z^Hu8B$F_~0kTPeD3N56>5$RMOm;HCfGibU?v5mrguBB#O`+l) zUg>QVtff{y0!EB?;ATDQf6m*Z_M(S-Txs30W&WV9Kw0{J&)eNI{WVGSu4@0eRCQ+N zd4BKnK40(izHd+WbbKwprqQvP6nl2>clzpU z7$;I+1aaJ;pdxw#)YAjWqNKb7)!_eKq`jX?!vpDDORpU%D#+mF@ z@s;pxCr{5u4#1YZ7>BP8@_hXViTh2o&p$bT`rAy7?g5v-3%Q`F_rCM;vnZ!q@SNxA z+V_V#u^t`F!fO#;e`n#%V+!f4wKe@ScXWKV)-sFC)1=ZXXG`0TtIaMI3e`4kauOX`CN% z*gZJR{BkCKH+N{5>J-Nn#bm z>t~bbC8W^n6w~YTzGlRn=l`Xc>gOHY7i;nPolA1O`tM^knAQzHMeS`wymk*RAKfFeCJvkC&KRHYx2C{@1-%xPwR0R`+SY3arKj%A5Eff>)%`J+t2jX*84qu zYOVhb`@Jvhen8rsOySCCi^@1f94IkUN5!m`!urehHN7)$AU)f z3eawL3f}$T*_ocZ2UGdbHVOY5&YEwf_t)P6dl^_y#ymVz5uy|rRVF?UM&@V>_ZtZ zAm0l3JlAA8pf-#=gZ0NA`py^p-Ukkq&%&{tJqvt(-#GS6KDr*3|NL#t$Gz2x9?l7L zu2FQL>yxeYco6+`Kj132;~-u9Oc%F%4*DF!f8Lg`xANEBD$fqyucf*VreyzFxo^7H zYBJv*Rj|KhdxwV*-)CQ-J@}lN{@#(H&nm1>UAc8wr<`@$P-8y4SvO*PV}bX~4SMcpuJ_kBSC6Esk>yIAOzf4?<@FNJ zz4m)aieK+Qe>~>eOWgb;@h?{UxNMm}e;a;)pZXu=ub1HU$e&@%uDz|iOyIY^&D&&5 z4%u`w_u8Fw4KQroLf0>Aa?EN>EQJ3c1MAUpC2t>fQQj_tKWTkPyaM=Zva$6h`kE{U z7Y)lfNPCBR)ah~V<~y{1CwbYNaIq%iYnC7CIhR-dTR!Jf!ENoY;a2t5b6b0xf4SYg zt=y}<9o!i@*V4O>&bjc`*Ch?TPyOll^$#P5Y7q0h-}$}OSkJ5HgR&8G>U%c-vTIy< zo|{(p*7wc7Yf<|?`+b^WKI2@u)ioz86n?$M9$Wx#x$+FS+n=xe=6ITU&%N_g<@>)g z^vsRqxyQe?z(y48xij+bq19WQe~%bE!+wXu{QIAv&r#%mjQ#)5E#z-jzxyNfkzy7WA{Npp$*9EEfpIBWNG-i5U;mR5|DmLQ zLqk))pJ)G&{0w?o9X?uc@v_Q}rsc(CfUSmve}I%R$y_!O-OQ z>2X75zp3AKYxh+bPf_0Ge|7RR?}g6*7i4>l97bzn#?k^R^WJ+;>tw zXKqujN!0Q};Bhl;@Uz{O>RMV=|2_--%M|?=oJ@Yln`5DWDqmkYf1&sF+zEU=3~WC0 zwR}CJmUs9>>T4@i{Rb`dzg^Kka6-OslU@IE!didR^-l)f?_&P{Pt*B@87Jts^yvJ8 zthbhT{*HWd)Y65N9S!^hHEg5cAdAd>(W0e-~S&^e&^eHeClzjK5n*c zHmA7{P~&@tVuPA{f7*N9Gr^m!v0dA4{JqIz_N9ewZz;ANeNVP6d+4TAd-A4~j@N1& zH*mz1SM3qNF}FaH4lVt|9nDkhKMq_iju?]G|J0^&{K_`lM(^AGGV>c8SqyjKoR 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 delta 125546 zcmW)m^;^@A*Tz9WL`p@vR8*AihAF6s)JKr+?(W(fL_k_V8b%37cf&?V$LP_cy9W#y z+n(?Bocj+r*L8k5_jTW|`jOv+;X7skd-MZ>{~w}514_?tT3|dGz~x4HMz-3>GH6=r^Ju1kY;~(LBdb zSeDC~c_EX$SAS;gPc2>rPOlD~3DWFb`XJl*QP$_-)v^m7{tNvrJJ2Nz9>AaAF}RbU z(5fq(fdc~h8M(dDLW`iaR}&yLb|}1Ir8}ck(Eidk$Vj z&Vo)m`=YyIMewkTv%RY-6Un;Ps}M?L9Q)nls~jy?@+N$_o`*FahQ)J2L@=Owf7OaB zF^?V&hz64t8J%G~&l~ z*JA>|qkkdG`E9vTB=4Ct6gy9OkgMKRRD^E z=A(;lS=(ZqV||w;h{74W-%6^T_`kEzoJ_3-ikIsfVaN3+eMNoabUUpkKW;0!3;L@W zUEAu&L`Nmx0C78a&OXR{vmnWF6*$+tWNe7z>@#>C;%UCD6RP>-Gka-r90JQ%%Jiq< zsi~e=%g>Hu?)05>nY!tehWv0t=s?c8#?;76RLfrCmPNq=rr-)COt{c!vVw=&g< zWLyz1>!6Hx!VeFpNHbtHV(-Pn5iVP(6>S_;p@+N)Sot@LVfn^FF7*x6PcA0g7!=qT zhu}HQidAaA3jZeaiN@moO7cDaH>WQsm1HEHWHZU)iH$2e52mguKtWUUt|j5zyRI^A zWGB%)tW_>aaR`=)O~kB+oy76%z3nr%>x>HB2+!-#dvbp(HdgwO3aSg3sXJ_%+KwGu zPg~y=m^Iormt=}njg5CQdFER|BQo$q2YB3mbI(QWw6=t6J8%8pyN!Q8#HbBM=^I=1 z$7L-ijSMo5N2IRP$Gb4`uI)odr_oM)x6j7jc$1*hj};T;6cQpMc|Pb!Iv#c3R(3RM zsBxN3j;h6uS&L4mu|)r@fqZr^r?Nmi_KJ_%1%z1c1xA|zBb2eB-v7ihWjbu9_E^Eq++ahks`YC2dyRzt-)6`nJsb>~c)ISJ5w;Oka}o?+A}(D0N1U`% zf%J>&hp1O^a)1<`Trke@39Is?L7aT zZIph=v^-!DmtQKST5{hwG$=7pQfb1y-wsIM_zn6yanIznpMluE*zLFL5wn57x;5d~ z>G8s>(0ixFVQ^yc4D&dQvS#A(VXS}F>!4PZmZ(4Cjg=`x#sg^zdB@MPeec)c0nKo0 zg<<*O*G)oyZ=X`3lW#x#PEa2-PqOTM!!mntJ>XJ@*=p9OO@43l1}7efx-BPFwNCv~ zdUR^m|I#mtuGkI-Gix4$k!Kh8s1mX?-o3%7a1CC;#4bO5&4W`Yh^(oS4lm_BqZe$oUtg2lC5B&i)Yl zOZO&rmv*FohBR5IpA0`clh^5YOh3Xa+!qL*6VLNEQTglKYn{VGopC2m0)TsplZfQX zMJc5&g-R||x+`2|zMr(D`5@njaO#UO%5i#C8l+us?!D*85k5vETZJ;mT)>rY;p2{(0aG;iO>Es))N* z1Y%kS&;1%0YPO>u(SG=keb_%M;KhiX^4RRD;pzN$T@_w%(#ib&lVCd`Q%6Qq>+H)H z@PLeEn`J^GF@sKH2DPf*U^naBehZ5%t2mi68HKvMv%9~goDg+*f*7yjzK7oU%(K2E z&*5Z;Jk8K!hVg7bd8cT7i9Wq-g1SktUHC%mf13aHXbRykkYBncX3^m>cxg%mMZPkt zuH?7Y*9mtFXIE(fe8GGqhGc>C0XwFn)*VHj1x1$S@3w7-p|9b^z`Zt+btzSTTQz&@-|-w{e}JotCD3p5#}3;{+5pv-7VDpE zJ7@pE&UNTt!xT3o?qde2t(+ML%63MjRUX%0S>*D1_`BE|7;bfmJ5IB1#oW1S%ul^K zQq&7xL*fu#y|HJ(c1YQnGoeGuKEuqnvkUtd8EvW{>JN@_N`%tx0v;-4o3;T@d@Tk$ zs#y=Pqrhc8j_6n?-&pEFI$sPehP@9S>HkhG5B@@g)<&iWmsX~(y9k45c{`gMNO3s& z*a%BczO5VLAZ*s5EdV~@uj zc8wS+>&*<>NPKYI$y3a1YEh6w>ffz{cRMdP$$=VPK{ACXXT>sI zfc|yMd$f9%!(~8lO7kj*ex_u?BSMskz?O`)WL4p74-&gUQDTC$uD^VRi z5zTC>d4EYQK0xUmMeNkYg6eYws}7%+C}`z$LTFYt{%}6sR2j*hJNW>X4?;Y*aH*Z- z-4Sj|LFo24XhnLn>plR}2O~8$zdz|`2ks<5{k8uj`4KF5QKK`%s6$ruypAV>q}AIY zYhFjkPHa=HPNK61OyJ97>L}7;=(hGtE_=K~i*CC7$AH_Q-XZk3;)Ef}IZCez7KRvKrM?d2VNLxSw z`_B8aQmg&78~>{PmxVWrQ8XS75jib#YCkdY4J8+2o$4}0(u{R-nFMX`qKEU-l0Ij` zg-5IOhc9JW#q?dDW$qAUtjL9`ouIoFaWeyegD}RVa!;f=h)lC84U&8>HB#0zYosJ+4ca@!aH*4VPNM_=f^3QCQg?iW#^h&hbe<_gdbc zX0emwcV~>3@1y3m^nA!@Lx7ikUQn-}`qdcc6SK9ttOU9G>Z`uu&}v|~x%YX+uhqc47s-Y-uKw7K6!KfGf>4crliB^qccc;z z8{ksSSzdLKzGhCGQUGpvf5AAYW%E*PT^#siXZG_Kv^S17l>g;9w#L^oo>zTYq5oVK ze(qb`V(nhp>WK#fR{O@{YKsS7GMZh=?o`atLkLvH@-fO74p04!{N1y(;+ZDMq*8L1 z>}|YM5 zL!*j3CdfacBt=rsDQL&9d_mvk6HlhyVacooBeTu4(oIe7>7^VBYaP+C6AS03Up@R;ms#1;Q^hEC7Pzy$Qgths z$!u0qQM&^nfV7H_5_yeyF{X%RTU7GnrR>;&>amX*KP+MccPV_0AR)&yu}s@hgtxAT zPy~E48E96|&XJhc9k)+TqK@!Y<0FJOkk-}*alu$IT8{U(Y^z6KV^1EqEoOa;O%RS5 z`!q6m@!Lw3(CE)JZOHh5zrmXe?S~!D5xwp_n;g$`fTV?Y9PYUkH&O`sz7?)9^jiQz zf{Z9DKfiQ^_-I>=N&Y>vNYy)~FP*&F-*MIUKNjjV=SIon^1P7Ixk!&F3*m2!p(im$BCIa?<6(bgUD zRqYpm$7tt63t-2my0{)26xF+I2Y<-x@^QHw$=;}*1na*nNa4~+xN8OPOt|=^CcZk> z6heyU_{v>E=cVY~u{!ejjgPFSn?Xuglh+p@tB>bYSE8M2)xoj-Ub=puOjo! z_E{o^D($v#{b@n1sL`*yi=X4vx+U-1gvJ3`9mh{1b;}~QuH#DHZ~kyq7PVXtpj~Yh zM7(wIjM(|t8l{ZP+ntBGL$?|MVCeby*Ca+BJzgg4S|~tkHI9^yDpP9nxbO~g) zp6eEn98wXsJ*rl?#GfZPiGo{ zqQ1Ua{u@vwZE7W~bKiexxxFu%Vg~SSDtLVs3<@nK)EsrcaCTs-TB<;8lB(Y~&MTQ+ zPA5EZ3(+ZBqs?2%j%!UvPf6X=&xxDu?*t z*7fWK@m^s@*jqJvsE=bhPBmd_*&wyOUuX*3k=v#?uDVlUrN`x>%xl}u4cPu5SQNbH zGXK44ez+V~6{l`c)otFP)9X*<Rs2e~iw>{SmP;lHp!0w!EEsDL3)5u0$>cUw1VW947*BX^grbm+gHNTq$g>AkQlGnnG>u((QOB^ zY<=a#NDGEu%men(V1Vlw%hlU~d>aG*z)tG}2)d!glXofU@3IF9d;jZr>(kZ=_xTw| zJ&cdOa9L{^XhK~#vHyF%VoG^~<#kywWw1EoZ5LZF`pV3&v|#C0Tta&IGE3Td0j#Zr zuA0>f@DC)}eQ>^ZtPNqNY-g`f9wk&J9(%p|;p513a^WoO_U6C%%=YN(E63GXL}2j~ zIn8PNC9ITcqZ{GkgoF29e~a#Q-VGYmwRxk=6h-8O&1dI>? z+1L}xX{qCu)5lQ#k_mWaHRUyK^Bojetaea72(q8N4pM)7PSnWmO3pY&=e=$5O|*Gm zDaX8SG4Sq~L9S4uCW00Eq-9zSYEQ^1owj7jt!=mS(hhtI z@MN>lnS0GO5V0(nm$@Vzf#B?8)cqt!Y3EaZx%ldz_vbRLZvbT5q8ks4)50Euh2wA0 z9Gs#Zci#=t!@ROp`m+^p)HlkZL65K4SB85*L7HywcJ_Zxxo8V`d5a1I*V-JfWKf!{sk`fAfdVZQu- z?yh>x9U1#73!r7!9X^zOqn9CHnZM=sg-{&f|L!SANb|3VYl1UXPpyjW9z!8XwfuqJ?9~rIPaM2yUM(Xk1T-zU;tD9D*qi>mG}(3VF=&-^h`* z8_!fMeM(lni*f#F!DxEzBMYc;d|;RH+L%WupYP6-ljm+|)JwDEVAvlu0xaG#IpesT zclFE;Z#_5fnN+QbYXmQDYE^g#?v(U?yXi6H>L38duUoSGI+{Wdh-#{0X(9(hyZk}) zh0eQ^m%G_wH*oUcK_b>qXrt9@%Bwwh&e?&Uz~D3AvSl_)19QT@4M4TcfF&w5gT%-U z+N4wc<#d(u#}Va<@XsBq^1ta5K!W>G*H)9zvm z5N0p2_>5+)T$Gz-ey>Rrm)~F~YS(cPS{{<>(4LSman!u%d}EdQHS>lOH1lK8<|u+an|1Wi_H&33UNRBRU)Y_cwW+r|#Erpu1u=vp=el`{yf0h*W_1-AisN zzJ5$^x$f@oS7xO;4yN2~OupG4@>imk6dJ>xQ<=$9GE{xY3b%03T^vlo#-MIwu9xB`_9gu*YdcMG2rb|=gQHLsj_@wRR4elyX#VN zwR%3^NW+ih7qf3y6n(Qt+K(`iHX-Wyv_agafWtxu(WrIfy69iowbYYzuEOfVWTPL5 zjvBmdGmC|2S#P*<2(s(mxFRd76_L{~n9%9%m(n)!s&L4Nl|TQP3LVNL!{uue1EWg+ zQk9{e86^H5I#pd(gLVFau>{q8ZjiISA~*N(Zv_3e1n-uFQ*a>X#$O*L^ms?--ia>- z@Ytn^?8wm3s9w*=C5w2>eQthl6Vxodw4Gu;n)Tt*<=2kEnJS#+bV{y<-9aTH&h*f( zvmyN==&O8C_k1?-wWk)v}9 zEWgkHO;KgML(fT&%GBwDI*mnr3IG0yeA5f#d!tb5R(+weH*H?|97L>$zie3Qn$Zs2 z2>+c_#3GZLj{U_i{Xgun9pe_?)xGagi%@}d1d6y4A@fDTuUNsMbmm>735_aMfSRZd z&u-kG8XBBhH1v7*+qDUj<%RNDX7n!;@{EM4C~*FKdZB+~E#euA-#B>qNlz9DSjd#< zsTJKq>!P5}>iR#1iz&X_0~wo3YJ+~jCwm=+Xk`A9G{KRQyd5Rywb zmq_LfJ?*yAv8HU|usDV6EZs{30&Yu(1t;Q+jJ+gzJsO-%jYL*l!uJ}L z+xy6!(x1`)?JjMw)0jE$nn-UMsPOjk#i@?$1^?)o(l)hPe8v9r<%}-i$}ziSWLkL+ z`i2IKu(fJ>e{oH7K@!_SYa#X?ZdoHVmp)Xv(}L4u91C4aiktIlcdd>YbwT&uoc-LDRC!xSHnE9cb31Q0Mr6Q{ ziY zRlD$SQN``ogK}CGJ>E5)Px78>4K&rw9!;>X;<^@C9rUL1h)#hup=UZLomCo*t)pH` zaXR6&4K253?Zs(pioR%x8?g*)_XW$b3B(5L&F5jgcmMvl;s1V$alq_#QX|mCc?i_J z()B51fMJW+6UI4B$^;t8i1Vzm$yc7B21mf&Ba6e1l7d2TrN?>X)j=Y~yf5PXC_H3h z#eSlG97`wVV}L82vxWLfxpF|*GGzf4eMSEcURCAK;ewJA>xw_^jz3j&1g-NPEBanD zEfr?W-|wh>e7o-SmHh*_d)Tf7EPtIifYtCPmxmW2j6Y9c^i z&VI|_9v?>(K>?HR#eq!OUq>}pL=w^LbpqQ3o%|C8mUEE8$@&w%=%U3Re8m#@`Yi+3 zY{k~sp*IRCkhe!Kph7?5*`rxuLe~SF6EzI|l=%B%_fP_z1()MApHibmIpjclaEm&L zqY{u55a3GYpZ6m>UV~@4|Hz^O$|ki39pT4P{?H@Xr_zOPx zYO@g;z@J>jeToHlHv9`bYU$K+7~ynRB*FpetnP~3bOv`5j~4?iKaQNcfx?y=OK4|6 zy)sX))1PuaseI~H0wFS-k=LpEsV9Zg8~{u8*+uGkN4cuhkjJ_JHq~g=e3xP`_O_{R znl4i+M6V|2>V!*LpVqX|QpBuT9rJt6NpjgV@wEs~O|nH6H||lX`L+~YCrm_jWCdW( zCuH2mb-YiE^(hWZHJQJGOIH~kSRfQgSoQ~AL=UiuP%aY1_kb6_QWcn>9M?0WpTPOm zHUzw+`?xN{V>#!GhzUU&OW&UNei7X5jGxr>GF{d&$CG34v={oX=Logws|)CQ9e8&~ zx~f=BcgW_TVP~yr1>{NS+N`4^4FIBPbaN}Ts%HUr=C`0d;yLKp-Bn4%OD<;4z^;$< z*W96qZ#7e_r#D!wPTlJo_=3A}@1k`esivY0SGi z{UXwde&5;0hLrdvFZ*P@(JLOoPdOK5D$*(~D9Hr+T^H zR9gfIY@}-%4*eBs?MyqRVDOl4s6U)Jx65dq@{IJ;6a zp23xC=ioy-R(^q7mj5d8q1Zn^d&I}Dc!3;y@4rYr%uh5Bhj+0Gd3F=@Fwl}louf_< z6zA14oxII%QReS7mmRFyC0!tlkb@vz+<^u$YFUe7T|IuN?1QI?fZtrDbm2m$m7z)C zWglG;`xlG4P(H1aF*-pU52aOPl!Xc7c1>h@E;eOBrB{LT2>7v2_?S-?|k^&_?9%OFEF=DrGqB$y@+r0a5Z&%CCQhG*O>Rb zzebndN^!6U732`?ksH8)khH4D=hdnuOpZ^W0%!XO;PI^sP}xAuS!ES4c@p;rX;6rq zzg|wcz$jsG5iMs64S{0JjcL9M4q$Q_AL&_xPHXDd8^vbM`+j}B8ld~2Vc!Yl16;#Z zqWX0bdQ4IB;&Hmi5!2Te@2w3s63ua>#1yrn!c1y*Pu#;7Qe!>)!=;8%!6`GvK+pC(>~C+T(BPk{nh84 ze<7)uHHMOpyaecsEx@G~wJ0+oV>FTtgz+TLPS>J^_U4qM!G5Nj77~uVn zbt~r#EaU0TXfB!3z$n(B=TcO+R$Mx=f49wq-%ScM(Sj_B%zCCdx`bN>Y@LLO_{_>!!FW z9|*8TJZNa9RgwOKk~CtFGvI>TQ7?cIhF<#f$x(;xY>f z+T8ed+5u`^EOr+#nhxPChkdvI#|6kcNYj@|eW51Y&V8j#f&0l%DvP9Ucwg80pWTZehD>9J!=jwK$&A}N+PmPD3oM0 ze`WP#N=J`<>ZJl|@z2eA1&6B0URHb$- zWHu@f&Fa1;MlBJoNRZo-? zMgc-YGBhnuj;67q>+7Ss+-zNrWt*AjjxOZTud==7t4iT^@|Z7=b9RM!jUo5^)V3q? z(<3iclO{ESCi74)aNGxM{s&UPrK(&Ph&@&BQgu+yXv(#nuIcj1uRhz#tpnfry>!@0 zdO1Nxd!8{(i+0c^IpEG;%aR4c-vxeJJ!BL%o=tN~u`2mkeP~amdn#`IcMGl~X3?T@!*V&r_>-s(;wtRm!%`r>C006yb=?hs{@8#pdSlCH z!OWhX1QKsK*~Rzf>qrE@$86YH@=IlmY@Tfje<2Yb*s19ouxMBlgZh~5#vJu!I1IvV)u%*~YP_;# z_$BW;Vi%()vS5LMcnAj-{smeb7yJ(<$D^5V3fOn8KrqXyhK%lsHA* z2qFDVp_?(ba&^YDQEtfMI~8vjU?$>$WnYp57Hq{U%!x~TP73ppA-5cbdYjlz-kDEZ2y%1xst8qJZBb_rLnWDT-Y-1dDXiQjJW3^_36f2)DP_IRv-E!f zpO!dPxV?}7O)tL$u|TfyI}zEm_9E6vTIc!UlA+lSaQw*IIi%WyJS^Mb<>69x_ZTmo z_c5Q@4p&%qS$EQyDsT1J21>@vID&3f%H&)+Dr)eU)>}0Un9Q^7LAMSHl&2vXr$iI> zjai^*+JqC0IZ-MkYHkK0ay{dxy)53Z6&8pqc_WybS&kgk{+Q@an3@RIG#;76=pao` zF;&3#_)Uq9yxm*(O-t^F<8er3!hkLzT3O_KYd$|-WKFPLe+ggkxjyPSJ)Hsr})L`_?YNU1CGsIN-*9L zhCB|a+m#-6n0apE0{oZi3QT)!>POJKZZ;Rv;z8M(VJ6bUNt3azUneh4o~ZMf17tr0A~224>!`i=Zn_^MyN z7WULLQx!VWF$fEOmd%}%38Zxdj*Sj`nY#>k!sw)VikGqA>D~Pm)4DG~%sZ%Adj4_bqJRCd2alm5Jt%oEu&_`Nf#tiYtn0(V*zncT#lycI!| z$P__tLi@U0SX_kx)m3Zw(*tKwgYYfzLh*R^pf>3B?M;~i=q5jhHdywB>yp4$-{$NP z;{p3h%#v}23iKV9GpGk6TIH{EuK595Rf+89&9!MtI|2@6O5XEnp~X56cN0**5!H z111;9ji24vMspTI;<>xpV*UuLM7C!SC8fUB_j*~M;ukMUhyjrg4tW0vgp7v_I7%K?i&!Euro9%tnw0rj1eHZ);yE#jQt z+xng8sC(6AoLIYkrR+m{%D!`pm3r|LbBA0~`Nw^C&-<=in<>1=R*Uu?58ztn0yxg? z?wrdQV2fWY7#kLPMkwgG?;z@`%)LMpZE-r2@(x~D`>Sv}Uh7ell5>6GEwa(PNeOHD z69_6KImf|$cRQgJnvGwt(wrDHhyO9?rws0#KIzLSn_09tVh4_bh>DwEO03Mb6h2SY zx8zF8>_Y#nXB)PD1!aFKru?-yeeVec7Rm!{nHQNd=A6mXy64QYYU={tNE%&y>uq=Q zUdDUk(`pU8zt@ZJY)(vv%SGm;?*_7850FCqckwQ6eTuelHrGF{uBKC)y-oU^jnyGT z5olW}Z9^iWZP=jS4RUtvPxvlVV`xk>HCaW|stteD19Ov3v#_Q4;SRxOE@bc>&t2 zTD6aKmZG2BGZIFMme-;MXG@K=Z&-C~30|-HOSqf~7-V{MI>Q&e^uIKSxKOGG(Uu2tkjShmU)~If0o(u6n;+V2syj9fviv zL1z`c*~;LJs0YtBR`}ZMTQ~pF3!n+#SDSTUH!Wv*ARk>VW-`zxOhGS;$iLGpxI36M zEP}4^ubC)_9aAUiSK3{f(01Q-oqThb;-kN18Tn-JTvhfx{JG(o=U1?C+&SvmiHo0D znV{g(tr`ljLEgwv#I|Jm+2WJURnM63Eb%sXB30Z6grJ(D0JjP_fv&e4Q17>zD?nZR zYV}}UaN92}^(h?Dkfj!8F(<<^o#uF>2hI6`$(NvZrPv+*Vo-MLU+?J;h$^1avklqD z<+40m3S59kYX*pT!@XLbNyqA?Rk>*-#dO zpKxAFbm)CrS=ZC^89SK<%1=^}lm%9IxY2iA4t+9^q+ld}tQaaF_6IUOi)!Dt??eJi z4M7sMHu90ut?Y<7bFN?(x=&$Br&q?SDC7joW2?X9eG*R?ztGLnM06rAskR-CCxkY9 zVM8JA$wlUPHg@?+I?3wUFYSh-?z!MlciQ;Hy>~f;m9jG0JhuRh)$!;irAjt4X~Y3e zr54>7kcJKOCy)faEe((uQ$Ig|e^?Ig{dn*aqfo*OaG8P_Oj3ECK9B1l-1rlIx@V~ymM(W`9O>4}CF=&4b z8w-zRYB9;R1%A&XuY*4z#_ltuv)6)XP)~(g&3Pl9{6apphi#+HoaI!9D-g&Uuhk3A zo*O#)&%1}4^?ye#CAsr&CP)k_g_3T_C-5j%G~O|^<@PtR$^CwD?xY#Xgf$OqA(Q9p z81jCf`=`8#tK``>PL-C`SppY#>V4=P&Oq^=L(Y*T;Pf?t0JRb%K=|S=+BaU%gm)eM zPK>$~F;;|&wEJx%Q9ShqbjBw)+x4d02KV3!r?*dic&h8jcG;-?-Xr_pEs?<#B|G~$ zT9ypUB!Oj`(u-vZVtsn^HFYd7a3CK4_!<*JjErDGu6wp;+FYaeUsgLvIzI0dQ@#pi z@x>v5?{ITYwBAzFlPf|pD6n+DNWM zaa-?PmsDpeZB^Cco)_e6tnKM(%)-AfQZ`J9q^?+K70lE!suV|R<(Ne!XT3){)?~oeF$b3 zHE9oQ7w)zg)bR6aZ}$Xd?WgWJ3<zY4$@M@ z(S{KcmP+LcB418r`_G(!Y6htf*;ckWEq^s-Y|JDPtWimQ#PaJmCdz>$7DZN;g479o z|IGi%JPhGuO>~nP>391qXwHWDozO3%a+~wLhGM3oU;09>A?nhEmhL3DL)4j?NAs9x z%xnSwlw&N!f;Hzw4IX}qjc0I+6B9a@==Tn0eYJ@H2{Ad21zCS_9@DRuEEu@SPdP2A%83eSyfk=a$5jvAv*XSy` z%FMW(w=9pZDb;%awG|%;I~fguBB!|sa7Mc1awJB+534vOQfFyCFmsTcuq}eAy!#dd z_<}10C!0yn%@P3b9WY;U(PDc!JYRjdum5#Gzs1J;Ws`~?GTi>N+u$>3^l_CoAz#o> ziBN7rK!;LHG48=#Me^yE(paic@G^g-@X}617WEr|m25)<@JvE5AY7fT@C{g{%+J)rEw zXKY`yfM6u1XE#9nT6UfeezGIEyx%h-PAk2VA%Id3t$aF-or+q`sU&F^e&w69>f2$~ z?l7>h5(zL_Fq@5z7cBOosDpT*c@NHF1yY~y>(H5^F9$7H7BQ~Ktm%B9;M8h8{!$5X zm2Sb>?^|wBIojT6iK^i{wzzq?dy@l|POSjQg7C1~8HU7R?U2PR?I5iIH4-lQ)2xZ<`N=RrCA6OVQ7#T=IJt}g<& z=|~1V(y83w75aZENy~d)ACDNM-0{*QLYBfOK~l3hz`GaxBw4RbmdvFhRUijz%XoJ` z9K+_ZG#LaV2}y1mu>pT<%ezZ?OmDj_*TzqP6eNQ_jdK~|^}Q7uh|Q7AR-Tb10Y7U5B)s52KLx#%7lxcFI~Nzd3D*+s)Y2U z4JLVSH;l*(69!Lq_@431=sHj^jh}Ift7Ca|gm+fL zMIR@`4^G5N-i=s%?{JSdA4LfQ8B-#1FK&UhC-GGu8IWMJ!0e+y?1|7FS%VSBiAyfG zoQ)C>HPerva@U`7uVGLDnQXM%#la_b{6EZ`NA_9pDZoc^Yr$@$VXO1yTc&~)?%#V= zyj!>Q8DpFi2JjLS3o`1gv0L~fux~42tUde{)!F_(n}h&5O0{Bot%P+r5IyiIcX2g^;`(h(m@A*lU^si| zc5zd6mU{FIID@|wS(l|k(F@br!*JC~UEiN)D1X@|A5RE1NnBsev{b5&q6pU*+z+Ry ztsy+gwMlwKS&j{Tf3c`rj?a5??n60f>GGyrtNxDo`cjkGDEh?qN8rCZcEXk9fJR52i}q zB-$1mGV`4L(5N|;_I-}~QQDNdJLO7G<1eascj)((svkDvO;&k^ZHr~PM805XFHwD( z1@p!49^F`+YUO*0=u1Ba_;3FUClVs)hhyK@- zO<9xT$ypT1b7M*?pwSze^JxNgnll&K7$2(Ds`x8Ep>fcH2?NK03u~D4j-CsXf%$dL zy+id~*?$RV{oJShnZcm6oGj^wXM#uN979!wNYZ846h@a-K6= zKvko&54@;l>$MndLYGtFyZCg0@UObaM_}o}BB*?t!D)Gy+Q}8QJ>yuey4mIJtQpnd zew}7VT27^3wKz;?_f%<+!K_g(TU>>mndl|CG3L91Xhx1K=zy=9CCYb&a<45I z!Wxyj;kdp;j=WC%#cW`HhiR1e#cG zqt4J+5f^hA;MAzGlRb-6{63H-!%^`q1a#dIx=^xgoPpRSrDU+sxsmx6VjNtyMiKC7 zhi)DH5LM>XIZ|~+C=4@|UGR79l!2XMkQ6T=CK64#MjT`OSgHU-%l2o5?2Va7ZD|!0%=m($8Qyx6JQQJkh=M zw^}BLZP}+|&TtY|CX3`F4U_LvmDj9(|Edr!T-sL|hh-p@q}2a-&)12Ql!4@jCHe$d8l%AU}P`(H{n z7rB$#ASiczEwOc5+(!FiglJcB*NKQ##{Yg7bqGb2 zJLk4$$#-wfu1c?8cToE>IAy@6;iq7#3GD^}!_lq%1g^C^{?sx(RvzsN#EmgWh?Yco zL1=HyqsE7)P>zs})Yyu0t)Mx5BLrv^h+3hmg zz>jcjzz-zRX#fEj?I7HZ%^>%La;`C7hk~)RT|?_d1orevb5qU&Pn1#jbe&dJz9lo1ed#WK*h!t(M;wncTxRZUq}kz2`&uX0P7d8EQV)qx4_z zYxe&ftyYsohE_VadYTK9LPbQRum97B{`G1}h*ujU z8^DI6OvssQ=xePfbEFcEr$5}{?Y77Yv}fJ_4_rW_zmS1Skbx?)3uIySE|qNDtW6bIlaa8Fp=D~wK1Az#mUxX59a@zk*`K` z3yHMc+%~*y9h1=J@Ns_rs|{nUj5g(MiRDEcgG^q3Ch-1`O(+vXkE8AQ$Ydf_i66@+ zd@SpavvWz*|9SlG`CKmSiF1y}^SSW&(C12qqEpW?MyJt0CkxpWe#&;m!_KK)itbq< z@&3;-d0s9tZ~t_V|5qh+d4|&^c+7~atUSj0jy(P+TMybm+ZI7T^}NHee3^5M@kQMC z3y-mXecwTS=Q^)fHyON^;|d*RxJ2FO%+b5&(|Q5-hNJO(syTZ1`#|Z@MDr1Nq*R2N zjuF4MWgi`SKH^$6-4f5M8^^f*(`wAeeXV!De%H1RHy?){M``Qu^AX4Lv}7!Q=3_~1 zHRfagk-O(}p57Uy&+(Ds;ww#zwf8xJ!(N9V(F z3G6c*Hh7qwo1^pp@W{vQJ!~GggN{39Y|g}EOC4ftHzfU?!TWpQJ9aO`Wxe5f);hX> z1kZA-RL^y`JZN9)pPPBsgYnVi2ZMgBfkTvR6?Isbb)mYE0C9SF_$_c;lx8;bp`67TG?p>Ga}y+J0z%Wc522@Vu3JeVIzhy7l29{R~J8Jp=NXL{=*g z;rV=Xd~%-b{@)>HXSt^Sr_V33!}1RCxVr84KE*o2TM95cFdx6|W1q{m*|&A9drl=O z{y<53#H}d1-BqNxaRCW@on_nZ^V_a@{K|sI9OUiDn;!Rqg|-Ow7wEOmy2Sf`9|xH| ztCHf-4;2OYyV>^ywS!6f3G6!@HV0svIP6Y< z-7SHw;;>h~ZH{c=ux9{vuLSmgWe(c{u%Ds)a=KyO^&Q&mJuptsB3qy5A@X)ufoD}T zH}*9ur!C@_toJr2iz7k^_o=JUGV z^t;sN!!}E5M=Og|*|*$^o`E)(PuCD?AGho{W?M-f~z6 z0rm^IfXSuSg$@Q7r z{}063iv9r?aV`ib#f?d}eZFPZP7lWO%9YiPk6c~qy+De$Ay4fvM+3_05A4bck3%Wm z>ay?lJq_(+=lskAxX;b*M;kp4a9T)3NL7|JK8)*!g7qCSUg)8JXYnm|H?3)#r);cM zY*W;oF#qv9e?Zw)>rhUvTW0+)danO^lG@Tmb~Qdh&oDmIU*jzal>tutdzQZ>R0)5V zD}(F)@oIQTD^QM09chh?scyG_df6Q^?puwzZU++p;w}4pX9$BSE7W7_xA4j6#XAh zXOvl;^j=;XJ5I^>T~S;2@{#TAl?(Fz*Qe6in;b8_173N5-_^oT$?g|n_j=e}3%lQh z-TT^4%lBd}-oEPEi#oD*$g)R1q4FnD{%w@+M)@zVS@}zc{zd2B%JaaAoOmr6w({J) z*RA~Yj)QbRqO6zd`7efDavib2+~-ALYdhYMbt-~RFYD;EM%HPQRF=h&m*d#X_D)&5 z8g}wGI=I+>H-|XGN$@TOpih89+@kmo?Rs(Mjk8#ccfB;nS;|>^=-#kgetL_6FR;?P z)eZbF(B{6r6*3OdJ)fO)J|yyJ*9UW)7kTNd*9wXqJBL1e-fNDr*Y>#a8+MjN&a566 zeWyMkXPNZ<_w@Z`={xOxXPT)AmT1@YUXo}^` zL-@}4N0^MokWt&h^N%@*e>dk@j=wvIk0hURJM^*}dtIOKrJqr(UIX%Awz1BCMfpTy5Bj3d-N2{tf5f-`1$Mj-f@wYn-2djMxNaX z|ITQ-lQYA=i#xucn8ygt8GoGRqJDtJ%^~#1kIMI7wd%|@@;{c&`*Rsxwp7ezTDg6H zLn(Z;Rhny<17^DaF-34@Aik8Z8PM0vCt1yi5z%PgkpW+s`E<-ZdUA+{I-5N)e`4=I zAU!6qGrm)XsDG<@!48=-tR$1-Y~c2vlHQ4tJ$ zddU#liH+hLAByj`reJ&%=$vfG=7Av_9^{4IY|Nv`f3c9W0&*OXAB-8#V&-WI#*EH1 z6|XNDibr{Rwq?rpXNLb%j^m_o9P4_JufbRbbs{~L_4GjZWLB3HXP(8`To;UgGszfa zvKI#y!MA>%&PVpbmO8Y=7Pc86cl}Z=UJM|sC`3m{fZ~wtV0}X5eEm0Lloyh z9BSKpm|waB_i+1rsGs7vj6f`x2!BuSIL*#Edux}0+qo--vq8Ug?a}z8-$}{8q#x<^ z%Q5s4M$zjy)9X_6Cd8cQ|J_dg=N;Tv+4%d=Whq`Q_pv^h<_$kZ-@6`v@v3c4;`|@& ze950p_r31q{n^w`gj)NMG%k3Ws7>-QjaF@)Z}QZxUbykW82VQHMql3+rmwQU-`O1O z>wm}I_k}eD+9_|`X&0$4{e#{4jabw}zo*by9$Gy=XZ>q;z{ba3!))B- zv&>E}`X;Sz)PBrpKO1>}TI)`4vBGartPSYN!#HDnOp^Du*;z1(y!#+8kK~Qg<~rez z<*dHN(0^SZirIAYxgF`BsZ*azVMB0Uk;Y{I1-^Nk?$;Y#_I(Q3_dvE5m#9Oda;Ydc zc@*CL;F*}7we6$%&@cx78mG_K)BA_N06PF|rg6yOK)>dq^Y_qySH~cZ^t&dV`(Vf1 zB8vA~r87S5nmNO4>(}x#9CQ}URqU0SP+hVMTk;RWPdDxYE< zO9%7~y-#EQv6Fs(^98?Y)_&I{T-(@L;M1E2v1W49{jmI{cQGC}<;!|lZlZI6tOMPj ztf$8VsHb6;)n&p(x_Fo_Hro``*^jj?VQ=M!Z9$$1yf4I}Q{%G#v{W}eYc-Z{56jrE z+1lYj#P^w9v<9Ct(UYBLoNuM_q{9^B^Y&n!S{Y@hrM;_vDY9RJ>u)`*RmLU)Oa4xT zz2w`Vy`Gps_~9*Ezqq8A&gQ;__t<#OJv@YUx%8~|Cs_0MxCYsKYTd&m!^F;oSC_wt z@^o%IJ^v5;4k30;2Gkk+o{0Pu|NPjHoA&nPeu?$9Je@6V_S5=vthFcBnX0vC9_FW3 za}nk#r)>s*^f6~{6!jY3p6To!p>sdY&M$5(=^d?)bjkf>Xsr}2&6jxY%|DA`V7LbL z@fd3_bJIHlUoCNS2@-!Y`~W|-Ji-q<@Y(TqXtUY3xt0q2x_5blgh?cuZkUJeqI-a0 z>sq>hS&?IUZ6XQ&gAB|^U2@(&Vx_!Y0Dsc_ka($o@Yh&v>mceHD+g!yNI6Jrhhp^8 zgWQcnw0-mNc66(Hs*-+P?-n9m3IgAx#Ps(Uj3x^+-K&rPX&#mUI`S`?mS z@2Ba1;f-fqdiR_xl=;OvYj6R)bomUp+n--`turce&At6I`S-tWI&&ku_xR5`*m4PoP>Pk$ zf1S|#ZB+d%%3OJ0bzq0${EwjhC&Fhm7M@V+toOWG#tHTBA@TBakqPWfp%njQ>1;ed z|Lwib$@pZ?l1-HEjSSr@snCz&f0wLZ(hFhze)u;z{#{}Hy1K^yJWp$vbcTFTPZK?V zd-UxR7soxY-#igM#^-4FqXqTK(9!Fhte2&W-sK?aHM48%=k&O)NWTSt>sGF-E*z)4 zOY!p)XTWEIReg`ATE9FU{oa!GYds$JTix;T`>o)(+HdsC*1XL^=pL2}iZ(wRSaY`E zGK|BQKhe>3o2=`=vG6ln7mn%QrxsW_q&<@|0805A@(S}OON&!B)yfqE1mSNktNrEEbOdA z^|S2f!J~Z}tL7d|tzGAI?7IA~^6&qh;op4yo#T&7erKd@lR3q6fC}Fy%QggaPx-8S z9C(uzwkyjGzCU)%zSXhq9oe?S?@P8NblngOkKGWX@tKcn1Xq>(sl2?nrlyMG{`r5q zYtuOE4**w)s|r^xu1vYyOyZ4yio0?=?`Z-VzWCkvzAVkpZDdrui~O> z?&9yBG@boT^l5ZxEXw6`;eSL+!*v$)G)zW0M|^_4%}~!9UOxA`c!^Jc`2NR4(aKAF zTbrTW1f~tEhnXN%;Tl;8n|MX}r%dN$NT~k3xU7psF<}(i1of7t&)H=@^thg6jhKg&O%&q1Ut}qS(%lE}zOT1b@F3b|}gd zJsU~?go7a=&>4qdOjL z(GT1ZaETg!U6tvV)%t8!>O(m(Ee7pqdB{GgpURbtWA=mp9r%7t{FU~T94~NIx4s$iX69{@i9ex|bga;ZGEOT%$(;tiR9zYWHglkr!9?_7cLfYZUR zSHYQ`Gbg~-9L#;xc0R6+vm3bGz(w;B`BkILuPWfYD?{xoD6d@W|GmJK<%aw#+5KeL z|6Snsfj?U;Mf z-gsMJs^KYrQ{Ts${B;9An2&su@D-VD@%57$;u>!;l!OwP*$>?1HHf!_%eA+e>L+ef z=P%**0(a%fP+XDcu+_kbQP zjq?=_$sU7U;b6+yOyKse6GeA4!|ji9wx!k2Z%A!_oENY(&24_DWlj{&n?C*Iw+fH3 z{*US{QP)fI_E5c`7aEy7KksZysK2!#zHw3@uIZL$Q_IBXHPWPVeJD3jin-GSshq*t zCe+{CFun1fz_g~jo9}A5(@?K1NO6vyh+HZU_jiiC-J*`NR8Jc4S1K_7ko=PCr1&+& zHW~we6PjY0qg$e$i%^f1D?_=OtymAp{&WWOBVcNp*c{tpTo+l6wSScBs}@D4oWJNF zRw(<2UhuD0hx-Tc-9bLZaRB_pZ4u*dxwiernJ`}hu2tDiaw79B4LHlQ$TxMnGx#+9 zMj>#WHKKS`l2`0#i>tq-!Bn7ZpX7f!w6yMjIZ?bK;ne++$E5NI>;HkbZpYfqppt87 zQ3z(^KXCpXqPR!4+twCc98{3vF#`To@b^k~SeLcM)*BlpG{yv?o1&Txh60l|8nXTP zqo5Y$lzw_#?I)67h(G#jL-S;-Q!T%RM-6&;ya(UT`Y{gjqm^43QI7QL!?&tkXoqrt zIXjgz*i?#9ySs|-ul-aW7j5wgnekE_;^HLwj#2!P|4DdkVB;U~19g~Rsq>&r8(%MQ zyMKmtgdw7RE!Va$irXIG+jpbi3+J;-na@Y)B}ls?`u$>Uz5T$Qtrx|!k?lI7UY7rp zFu!UH%@>1mpVZ1t11>rsibGt4-1T~Ya=pO!0biqOFL?^VZ2k+}v}W{QT=*ZG|AIcX zSv^l>^Iy;toAvtzHva+N+N_?}v+*BvH|Slu^97%30>H+9e812VinG#Q!_zXDV?_LcyZjHL7&p#*_5$Day8ir*^?%@>e?2swX#DW1$`366f%onW zt*?W6`n2nge&BYzp3r%KQgzw;HG%eqaFCVUm|V>m3>>a>!{CwJMeC3J}8Y( zYa_?;5#VMY62IJ3qd;Nxurv1?Zwl6lz)e-?%j~1K zWUAK{kqY(K~qF9esbL4Fzd&iCZ~re(x$h-x$hLi_;uyGP-({tx`K@5%j>4fA4| z-V3_*SD5EW^!>anub=RLM=7c__4p%pwB{CD_h|aH!e}Ov-T&ILn z_7gtU`WLu@F07}u^%_=(dLFj_3EY7b@_JfnKj^L9>U|BO_sMi^`x*ey>V?J@R>bwzS26))|RkJb_tvRgYO5whtt&il)BzJ;1W-T z=3UBqi}dO}0{oGGQ~LFiywAWN1ivdX4r}$~Mc;wG_;hIfWWhQiw0SA>tAXJABFbUTFDPTR>&OyKLh-;Ka%7|Ios~9PimOicwb;flet-Fxi=~!S|gbC ze|Mri_lNe$!tL})b^nkFT>iyy|G@mSCen{(!1V$5nv9eCk$mm=v(3#pdWRIZ}TQ?;SIax+&}T2jLO#J9P6&bE0ES?0`J zFlS?GT1o2s4Uep!<1MYMdX7u-2+2tvYmz5LNb;C}xa4H}%9ZXcTTV){WznK}DJk6C zP34H%&GQmD4m<<+w!chH20Z}__m&|yedy+RdvNf>p7DxFE49Veo@v^ zS5elgRV!Bs$zWDhZxt2^NtG!k&K$uRr4oB}X_;41)v7EgmX}qu!j+qs1mPrILa%1b2GE-tC!8SRaccS^KF4@$!_14ja8e3Il{aYVc{Yn*;2Dq^AEh_ z)vlcUoD_TYh7G>TQB+&u^-*Q+(vnI~<#TiGo~^zWzRl&8&w+yKtMJE~N>4?FuM*Y% zwGz_P!ZMPR)oKa%3&~qcxBJRB2+5Co%Bp>TDa@)AVbLPN5;F9rASq6WdUBFC zrN|jim0*TzlDCzYdW8p41k3nckm)O_-UvdTud>urmRnv~H8)6t35fOjXM_^qgz`#( z^b$(93R}vngbL3_pWrDg-MGc)HF24qDvzwc6r&CJ2gQSyQ2IDm+KZO0c4ZdjKarb% zHFlB)mCUX5<(86zo#mtv)uc66*s()UXuv%6zqCCKRFhYh@1r7!wvC<67N@p;QLF() zgEEzNDI_2mC~5}L($*r8M9DTJYzR&|RR%ju2OVnZtex8Whb>wl6y2?7*X}74TkP5y zJHvF_GoC#?JDzUmR9l^;opu}1%HI2b-u;r75JcRw-#Ku> z@$d&}Dp?_b>#o7n5GG4ib8^&-C8@wWviTlxWd`7*r`}~(-Hy$m>IV4iaJV52Io;6aQR^UF>*_W-foQYGRbS)4 zE|+{;&bxsU-wMN9d7&?d-iwwJZq4XLC)YR|ag^F3~# z!+)Jw`x>!>^Vka9Hg1IIDYUsUaBEII7Q|r*Wc*+%(oVxhIn z2Obj!K6^!1stEE>7sQ9hZI9?Hb=1L($bTp4u5{N&0FSK13AGRVwB2Pv&>YM zW(aW>?nC|(gD&W%3MYqV11i2x-*!1aZqxvt9TjPSsCL8MVkD3W3lU1yk#sUlb= z-(oJ!xEH6%1Y@3Pvyk+9!#|A>vvJ>HgyR4yCZe*Guhw*bXy8E^*)IolR98emNA*SM z6oYNVG>B$v^HxUTs~;yE+Rb#kB}J=$L)#h3vU3BpQNiK zDGj@?F74J ziz;^jIvrZG-Sx0puH(bVVK=jzlc>q(ta0Sf`zG*JPI%Rqa=oxZ>?|vH%{6BE)8`s9 zL%$aL@h9{W{R0Gx?ThGFrd?I>^?v+?tjf_n(lGgxsf|gDHkP)lyv|K96J6T(P;9<7Gwe%{CXro7LvE)c{K`TjQ>)udVfXeGWUz z13aQeo!Lr{PsP*E6R^46?1bzum}`+OjS-8`P zw2y@l6Tnhk;jlYxjQ>`vs%`E~zyc)|LYlTSGq(qf*zM%)$hOwwu0w6q8c1U>L{gf9@sI@!$syzgz$9;dyU;xbjz~ z^LdS1OP{=pz1Lem`_{~V?R@u-Kl$v7;^%%?xTm0N=JZcy9KB!n;#Yx- zhp+y~yr;8xYw>B%;^5r%S!c`tT>RX>bRU>mVR?Jc9dlm4{6fR>qgT)T{JG)jfeYUb zJv9Q)*94P-0_q7aC1@r1D8U+nPY}!{xSilX5NsoOl;8=1g9JY&_-BHDCHNhG!Ks%7 zyo2Cug7XP3CAgg6DuRy?bPx>v4fzO*`Iz!<4ZW{qtZ@;w$?f=z@JDV5{n56K_k;u) z2@V|~ibes2K8!8WFsPmA2|q$gCI8*3(Gg#wo5rCrgskxq&+!vNUa(BSvR?{VYbU?g z3pj9Dz{FPs99lwtdr-h*KEf-1B|f(bXqicP+Xbw=Lh{&`LQW#tpV|+S99Ar#>lOh` z&k5MLgW_V3fYU4_=QaV)5dBe)fUPS?-YNmrR|Q<)7O;u*+_Ff(EYf4pMRFda_IF4R z>MtYv1WBGho$N;a{sSbB^qtfq;OWDJcNdM5@O^g+*qkh2ib{GA|FZ;t2c`;WB)YSE zNgjR9d`rM9WcS-Q3wVnB)jxym@&eh3^g2iU+e^qF)L$7O{9lv)gtwcZh2&17@h_my zrg8!8-WjOI`V4)L83oBNx*8&o^K0iAilMCkew)A2WcD^ZWi!Evcu6A zX&l1>mi(=NZ~nc2>&!HN-aAPz8pog(Pbt(-d|LiSzz)*?9;rP@^Tki&JWcc3pxNVpdY>VY&W?5+@9OV5 z)iv04rt56ixvrtEU>6G{26TbsfEq9ajDf6xDPRd$1Lc9rKy{!t;14tgnggwY>z2gu zpU>g{f!eDm{AXoehEeYS|NJX1eOhRDxgvC0F}oIXRKBrlpF1Zp9%K!Q)BeUdUWHXgr3TK6&@4)0Q)CEH{P=l|IWa~m`!nEC_gHQUucKZFT9sSU-Kd* z1m(vB>hZrQz|%O1v9lRU2#&(@I$WMA5$D?25JutUEwtl*Uz_q@8mdwb+y8MyXlSr?8`nf_Wdu2 z+xD|CuI>olvoQ;XnA(!a^!%Ro`4??PkH^n9ogMk<3A}f}u)K75A>BLh&~kC_KqBb! z8SyyXBkIV1;Q0D`BI`#RBw6h}k@W@;zqKdwo)mtUjWm|p9#PLLTJQ26QCHw@roM-L zCaEub44M?8Nhcbe)R#C0&CqLtCY#el-nqi>+>mq~0Nkl`-_e_3vy)`ALCIz>5$YK)A;N_w{k)Jx91LBu|TpE!~kZl>Ag!hsy5A7}Dxn zA>Fd>(XkYi{ojpqCR~$2mG~xhhy5>)c_<*p932;D0(eh38!&NRk#V7ox!5v#%w?MY z17gg7Xv-~@(&1#Xd z4JZjImMK)LRwvzKhIML6je@orXuqYHYlAU=t;Fsb>bZ}qy1y*6#h|T_$Q?^oTrmJ$FBVtZI25bk@mQi+v9;NZM=4l`6;a2W-T3lJ%(LM$u9m5asLzQ>gtH{`*OzbLeqR-65aoc$o>V<{Rv8_ zU&BcR9Mc%JMoOf*p;%v}Rn(~#K9OR7V&K)@%jLY55Uk-(>07KUr(46*NqBo-6?HqJ z?cDULSZmCz@ja}`J~9h(M}pB*8$Xnf>$1L6Z_z1Ao_seE(v^(CFBAF2H-`L%wM?)^ zlBUyHIsc8pW9YEZDIavw=(41k8ay1E?l{r?h|}Ty@AJE}I85udaG2U{O1Kbzv(`la z80)M3aOC<^O!1Rj6po*_uL|6(!=mO$DZfKH_WJWB;Z8do&c#0|3eQ)WZ#UtdJtX)> z>vrl;q;6|t@Yq8<_5yDAIJ*6YaBC06UW?14NwZmNIrKi#5PpsTek}9L!_lzD6luwYH0U<)h=r-!9^3 zIjejxdhF|Q>(p$cU$h6M*060aaZP`#DCxwaUbj?rk(`aPE{F7=ed5LkEtIc zd6t*8IsCv?rFb;n{}4}q74Tk`_FXTd;tV7;FYuma!$fS*Hq zI>3H_3jq!TTm*0)V{hvq-r)q#=TNnjyGuZy?=$w{sQiCW+*g`^4EZ)2@1}-%2=6;% z&DTW0&EY&moN4vzA=ZZD*m{_|Ik->cvJ<8GJJ=@f3AFNkxbc$EF;c(oHmoPWPL0Q_ zsSW4P`TUC`vre6k5j%G1e;3ZG=;I&8@bOmiTQ=amNj|m~mk$3XhL5udR|mLn;61>g zn+fa#YZR{Sqw>^$xdXA!hl2+~wQon|sbkQ$1Y%t~b6BLDu={|>2@&f*v>o8%6S4VU zG4xI%y~_c2R}34O4n)qc4`R*#D>VNPh& zyM3RiSDZ|E`Y62j32)0jQL7m3R=Y3KZkirbW9YGLpNP?^lndlB8=&uIeqIgVFBu-2 zu)#SAKe$(a@VY3)$9+-y9wdEF11{bTU!vp&m3Rg3R=;9@IxiR(AD74P)n~JUiLi#f zc?;yyc$T+;@bLcMrnuaoj=!@!)MXMgHsSr=ageW)nXXCbXKeZg+NQ?M3PL^{7$)14 z?H#>8(ata?$fuRC|5jP;vntH(O1@Va$v5yAqxc7Z`b7{o+3b7(a#GXlhxEb4AU9DF zwAn0mhsvDKu7>po=`$|siw$f_i2lPpy_ZvY+@&>j0c|R;t(eBYLp%Df`rrx}^Hz5L zl}XU=XQ}O>yHKTAYXu(PTvdY^K>N*iEOX&(a!EULrexBnxaYjbs>@ zJ~){bH|dqxCY0xAQ=aDEwMp}H@TK0%Ga&z&sQ%pb>V5%mZz7$vHTEW0W8WX6{oi;# z4}X4#V!#UWE3b}UBNF4{uaIY|*-*elYm`NQnmdWW=P%$(ZLcT$=)#M=m$&l!tknVZ zRTB8Bmd-Fbu$c*LW&vo0pS2K2Gno4E7V!HF@Q;sbUn1_;xK0AynGt=kkX1B^dMKlL zlmiZ|C;iBylKtoQMHf#L8Q6hKSmO`tgRMyT?|cvWehc{Vo2x8{{{?&iWCdB@C6u>+ z?WAf!pS;2Mj_+?TV--J7X2q8v9=JY9irHKUy1oT+knaMJaf`$g*Ysn+?;P;^LW-Y5 zfMWnYSg#Q2x5dvl^?(cm^kWS$oG(_TVc4SJeEU3Ko-ggYdoSbKzD}tC9n2P6{5JCi zn9t=(PP4*ho4DTb3rwFun_X$xj^9In>p?H9n=l*j=PMh`IHo36d14YvZ*BqI(H=9w zHWp?7Ybe_vlKn-5Yy-%~>y?^NR)K24Itw#l9LPt=O*8#vB$vmrOPW_scu!(0%_dgV z*#flKkF{u8;e7+hZw5G9#5u3IfbqUgqJNmb7hhV&avBwov4GpEg?~nw>0{b|?m~qA z)i2=sE8Fg%`TQu`rJFvLY&TW$m<`}3J-3~W`y1gh*3dXIGAD@g&j9`$wbG(j{?1ga zs5~xqD5j!m$_{fe)rvzIaUcVIkjRR3HYJy*RlOzr+Fg#AxW}h zg5(G6yNTcBFY*EGaf9R4tZY+%!rvEvP5OUD5Nl*5GGoiO_zcrce7@*fn4VS@= zJfpx_k^wZazLu?QZX?z$%4TyZrxdirLCjfMMYlEKlTm9+=JU9=FgS;QuzoAZGqQJ{ zS*R>DE3E&7kF#U2jwnab56t&?Bj!|8`_$& zLoHU;*FBjPG^HxD%{q3H+s?p#cPS2ZHLz4T>&$%(?K+dqX+DNA%doy$$}`xP%&MB_ zT(nuHD09q6kM_lXy`?Cru$Ja@qg^{k{&b=oWZB~9{x50QA01VHb?5J!%w%Q)lmSzT zKY%w0Y7(LhD|OK#d2a^WnIu4n+NBl9Ob8MnKtK>gAd?Uz!68z2&mMZVdy0x~C_(K} z_tY-YV6#1NYAbt|b=kG<0;LNSkklV_@l$sqmJFtVa6}UXW~ehZ?+%^88rO<8e=OUctDbmH_R4MNRwVv1b9-6r}s}AXkdp zk1-20(wjDA9{j_5w8)q<0k5KKUUxp($^#3Aa99Ey@>6hljN7B?_$XC_yj}_jUAIaf zrIhP5zh7`aY$~7I4$SR85{=!o=7$^ayPPHkk|yUeXma_7T?0qc= z5l5|lg!Wy30nLMWN0Z}4?H%Y=#7p4WGVt{dxd-+O8u5{Vk4qi-+J7b*djifs1T+q} zGiF!jXf2K@+R4OEx`U9DeV_xqhw49xv88dlvq@u$9e#t_!lI4wCTD@>U9ARL)Em!Y zX9699zb!;lqN5GEHR7nyze|2Cct*Y|#_4lAi!`@?a!@B4<>UG0hxFhyCiWUtlxdoI zpHYm{D#z=%B*urWTS12#vBXE$jBBJbr|@eZ zUdxPsg=g&T8h97+G<>!8^tg6?pN#+aioI=#Z%vL)O$85KtOES1Xr+1DlxAJ7Yw%0g ziomZBY_p5i#K>yMlx3NIDFv^VCUV+-C7|#+{dKfHAZt z<30DVXb?hXbdBV-$N%7s78F?9ObQL+4@M zju!GsR7HiX*}#VaVQ&;gBiW8PYV?Ny>xXSG2i}$JEaWPmueS$qJqv5D3Us3N{?)aA z(jGJa%xh=`=b6wG{nvy)A8kkMeFL`D*#E<9Tj#W=)~S|Z&DO!M-pi`{Db^p_L*3l} zfM+y|8clqU$V=D4S0Ud{;GM5M#{Gj8?JHRLy(949XwTALz^_tvdV?#u9iJUj91;I& zT&I{}6RvG0-$qq~oHx#UwR&75A88?f3(1%?=^sVqdksGw^x^vc0`z(=I}0B^KTi8o zWrN)e=KF^U+h_I#3ipV8sc25kGLG4ZIbOgsi1VcGyO^Q- zdShJ!dCc8;8u&M2&C>Jl@V(@=$G*5$5Pyr0u^oOy0sM$S-0&mb;C@6t$AR{LhNOKU z8=x=Vl6x?bpYTdnrk_w1m-+t~#rBDtvWH^9#=cP(mxmniXEnZO>GgdQCjC7}+VeI% zPkTGr)2>rILpcm9c-n*4X>pzQ*d30KKY!M!YlLFNyFzvrI;AFhnr-iV-V{%n-+!F@ zp_$izX@aMG+H}R|_b9LH>Gj8dIe6zf(3kj8IAqTpe#&lGi%TeuDJ?Hh;pc;Vl`MqnN~WV8Z$LhrP(2;%dz0S}wTc~9dt zVcmQVy->)m^8I^HbNg7P)k7yOaDEb~L_Evmag*-eyt`}Qv&7^cfy<76HZOdlJl3|S z1iGz4xq8=VHf>n^X6+U}48gcC53^rr1wVQ>^*T&z{dcYp69MAGg`^)!KUIEH1LE>* zPTM8$_cG<$hx^|LTy3Jbbrfh-mnfFGqbq?E7P+H+Z9+cU5{<_fC4`TA0_(QP;q&jp zJZNt~iW5)sz1`+%IiOX48FclcgwXLPu=eeEPi;cjDWWmOF7$rmK7+jv%dxHS&TSKP zA{fkJL^_>o?Ha(iF?z4!*w1}v4K}+9d?LNjjd>G&NH-O-#<*9BXk_nd6J@Qxf=#TG zb1~CpoZ|JT=)YD$m$!}lC%tnRdq8!_3b}6@)#WqlAFX5$!bA3dAm5_i=4loC`qXfk zd~J#a%;jCet{5H7jRow$pXK@o><5y*o?Yp+ENgo^kLOgEygDCrR@vS?CCt~# zT<`Xcanky~cTdEB@uz?dG}6WXgWW#n+c|^zTHJ8&=3HIe~?H zXiW}ctuS`=HN)5V#tq~LjCxlt>~8)Q*lOr7<-E#uA?-hZPJFOAyg`b?nsIcJU+c&Z zE}*!_F(pX;Tn-CBM-}x^O-0$M2LFruNK|7u9uIJNpgm__#NQp7O&+s`js;rQ`Np6f z`bKelhwIA%R;!J}x}xh@jsk5w3wP(T70`v@&{X*Pqt1szqgX`01M#TPqjJrf^0U63 zq6U(~R_YXgC%KiW`cI8MD|7!N;2d18Q|b0IQ?2x>tR-DE$<*UgrjE5xUmA@&?J&vy zOZb003q{HAQ{W>9anzj=?PJ>O)UhP^QKGuXfZYe!47#&?Er%8JycW@a8y`D$Zo8!n zSF~97DWuErTv;2afWDZ|^~GneH8btKEH*uAb0~g)w~S$Pp-0Q5t@Bp=wvYC>zgX_& zHGv<%2H0s2dN%*?jpRm*Tzn-&Tn)LIH$!JsHfQdS`3J;&Rag(ZmD2vOQD=s%{?ivy z|22y`oEeurY3FTe=Q~a3Zk#uzoo_SxpPQ0@{h7IJI&3k?bV2Z8$lPB5-#j+GKb=0Y zrp&(0&8Bg5-n02>pbGLUYRP8;>9zBq#TYZ1uHWNl?p<*;iN3+xAQMK7bDzofUx<>= z$hyZe^{9=h&x}*XX;yIEQ87*;QPg(@eu0^Wqp)^dOyxabw04}P94_6@N;|je9VEPe z7DZG0d;`EI1o|irR%UZ(Wq!&(IMgz-Mdlo_o#%y8dvyg}69MXDGV);tUHP7Tjno5D z8domfg*kbtZpri04F29_xsTxcjli>i56QHw85X&)FBW!9! zi#SOimj?a0kvV}eXL()KJhwYp_!!yVY?JLZ-=9Qthb`oNzz)iRChtuEKRhxvH*`*~ zi5?racMXi^b+_XEH{qDeiaT<7TrAd1|yD-wRd`24%gX`a5K=Q+ex1>(>g)cURyU%4rp{&|&g%e7yEo-S30W zwadLoQ}EwLJz}$;A>1w{O5Y>camoTc*8(=UP57K=OnQmt^0AcB!fnI*(PSgdwvn+< zUlaX24SfrYZ%<77RQ_(OusgYbuvb;QhqHJ{?_V&@=}ie&iFo~TV)C){y)D!1Wkx?6 z-;;VP^?wiF^Ar7C;=eVyx9zO0*8ELhZ@F8=x^Y{qnfTK~y%dOBi-v6C2@@So0_F++ z^VUUJo743xJRczHo)gk~toWX+fUg71%)OAB>3+-8nLS2)Pui!G-=GwKv)Q|p^9AJ! zD;>DS?G4<2#asSEhqwIx3Ep`NoPB{xHt9J|8;tvbcOZKr3;%NA2tLJr6W&bD0h8!n z$d9(v)pY-Tw0(Qohk-tIdm9VZYqQ5EKrwb3oYe`%GrIfRi zPmyhSa4_De(2vA-3;BI;u#$hjrNjm#T<25Q-)Gh=lTpAbr_~VU^u6$d>8P@BtPr}p zK&jDoAP(?jj$;rD_;8Ie|I0R(f56Vp9-`bX^jBvh(FolaIp9Kn3~s~G&dwZi!FCnm zp2q8h)_T$Y)bKhYy$9ZhSRhNvxXU#E?#<*UL=WE1!Ut8RLAR)fuNMc?dt;le-)q>= zf16i2c-On4ukv|K^i^K;i@wUJ?5o_yL|&6OKjlrt|6c!pMD8P`%G~8mNgu!lIy!kD)tL-kmW=Hmyf&jEQ`R1pvi9S&@yL%L zdfF`L*|16EL#Suc#TdV@n)jsNMD(5t9+e-aoMs`L+EKzT9nv8qA4>Tv*)+WT(RW7< zi}%K#>>7Z-0N7OindRl=lh>DPvkvQck_??ySd(oSfK?P!1QZmcRY1C>OMg_PrMsl1 zd%)lW6p)r~2GZRnF&fFyF=F)SZHykUpQHESJ$SyO?|PrQZ+G3Dm5ZMu3@*n*==L|v=ZA!=aP}!tBX`XwlVOu^Y_X|va++rqP5^8IUmv`bS`EvNIt?^B< z$nv?Sq)Zckvz$BX^BziQDBnJ$sZFW(2onMJMA-8HwQYy-QY}j21-Ow@6pD^ z@LQLPHA8dhf2EZa=6!ym3PzXTFE2}Pb=31eE~JvJcMXm)PTJO9UDANL(k?`7E~_67 zm$L8u>a@%HqF5?|_Q@6h77GEMMAqj@D;M^o0=Vgk8ak_HRku@J_vT@l`mbhW?}pSU z{l5PKoxdOXX0)yv@utv(S)Xf)z`@XM8gikSYuUDO(X4e%#-4gLoOFI4bAvFL&JFMZj%BJJn)*{v{++1owq?Hru7-p&m8@^wUsCoyf|p1d#BxElx$46WIPzB2KnJgVPP{T4|~ zVnonsWH`r2CkXi7tnOgw zT9;{B|q{g1Rm8J*nj*WI;c z4Z(U)2Hi9&%DfWimB)|7-DFJ<{2gBi$h5iJqTiKOO69@yXSVn<_5_}O^2S;Tqxj9< zV{xkt7`Ip28JE(8KG!w`8`9j!%l`XE3kqBtcOndxI~D z_1@HHxpM0!@`@*8&}t?-tkX>|)OHo`xt{uz-Z52c@isgMj_u=5x)v) zq3%y!RqcW-$UHh-p`?=)T@Giu$ZA}*>Be}{QLTzT>$kou^Qd1-6cU+>p}n83jGX|q zk0ga4$$I@SD)O9SD@>R;l21)}+?R4A+xq<+;~9M%gE26tIFVb)u77SqQO?e_zZkp9N4q&SrO)$vG>9a1fBck!-r=&$%5!h#QL ztwKMLHwYavMfXl|D)1Re+a64r9dPk~%e@$=cSC9I;JK-w10CzoO{O7|X@HVlMu4hD zP<4hT55h zjXCW!1ULG*Du2Xyk%&6IH|`ZGY0KY&%6*WDv#(><|NZ?s^32ze zX7BP-Ye-2d=!_cFI1qH}UxfTSiNW}Dcvv`EYT>Pj=Neh;57*al)K z_OeA5KEYeta>S5GAmcq9L+ael=otNfg*dMOflAK z@vO=&R8xBdDg+4mpLJU|;Dw5%RCX>i?X@J!Ki_!6y(@F@b|En`|1tG6BnlOK<_v%H zOPI<#1!?JaG=2YAnQ~VUc5ln@<5gDpU5x>=k5X~$HKFu1cs7(D_q~yobfGY(w2{4? z{@AH2l*k8Ex}I9X_e$Z$QK+I>*~WVwHxYnh_C=$J?hcUWA&+nSnlCfkq#ubXN}L84=E!@4Ns{H20%qOF$OG+BO*p@ZSw z&ayi39OIWczkq9^_`_)~Q>5aYPe=Q(uX$*pEnkL$hA4WeG03wqfBYTUySCns8t5Hw zR!+E`bq;VIlmW(%XMi07C-)e``U*=PM47}2fXgoNJl)mbUqeEk07L(s?v`lyKE=Df zoKF`D+Ap3icBg>>Tj-;lRf{Mzkb*26f){&DW`8OjXlR9Q^le5RpD+*`Lt42`@Z^~E zyCJur{|<)as+c>cna?)58kt`p$S$1djiudl0as_)b6(1GsNEdCR~|@0r!+%LAg<%I zH~v0@l4q$~^M6I_f&O0xG)m^1{3elGU)NJAnx7JZQdq5SlN<)^`5mnSyEpw=bWBDe z1zf`C2@k<{(;bdamRM~iT>@>d6=}|R$bD}9^c)=j8E*1@hdr6svt&GZ(!@vE$ocjX zaOZimxH!TPd{NB%#pU^)3ED~0mm5oYoHY_rVG{8q^~iGvG}=`w={Ub5G?O4ry7%dv zdVxH#pxOI;@w3O*ePYIf_0N}{5aX}YcoE8XoWI{m9O=$>h{;#ZGE%gKaiH1mGf1!S zPae}M{3MuWIBnmKnnVSUt5f4M=Z~bew#vZN75+2LM{D*YH#kn@nGr${1vt1N! zza+jSw)E)rOJ?S0zuj2_f1}MiUItmMxI^w_-lzXam@2{b2)GySgqE)CmTZPUdKUD# zmzqaFF`v%iJtGD^KNoaGtNF)2*M7#n?sodE zy|@>Szm9bOF=G+dth|DwLqAwL>qLfc(bhDu46^VgDpz2A-nBQfXnDUeEZ?$eL@$yo z>=Mtf{e9!vP!UOAHe@MwvnV)y7Y;;R73r5x*BDWd&n5e?bC%^UK9!p9EL1=*40&EW znz2bJ*Os$;Y?@f}!)Zbyc=LOch*hls$%$}5wJBTR$aFYt|FQGjzCSl^m@6{X3x|5Z zO+`;J^juh9@N9{Hi+E6q__*Z*M)QFUj1C~nxOtp;e>5r+DXK^AU4O(1kFRQZ&M7PAb=v*i)~faT12FMK!!4Qu=E&;7~! z1z%gDkZ*m*!w#*valV7xQNX-BE!onpH~qgC`Sv8vAhTS>`NC$&fV(%-87b5$F-N%= z3EAdt*w>po5@%iE?w;~6X}2eSN|cu4j+JVKc8&>dtn|c9^S6?M!mfXZF=XL}jFq9q z;M4zB)>8U4;pjPyrHgkFub{9t|SU$wm;F&u`I~FkvA_Fle!ovlRTvW)Tb*?}HboUbP5*`ILPL+;?zGbn7hUOy zkLz_=PI#F!pvkJ^%^F?R_ezIRJvqPD(LI*kpel#@%Xc8UMP<>abUNg__vrcv?}i$w zBT6`f+m(qB`oP7RY#@Oj&JAoZ`2G0Zg!$*od72;H_v<=4J1+8=?x$~(3g$lsz2kye zAUh*=6)0jhcX1h11aT#tkCFx`0z+Xvxn1FM#XaVkmvy9)rv{cw$tS&yBu;f~p>K9F z@OIi3_Z%4trHHSrS6_T5-nDDPotEv*-L8!I;)6|Z%Nn!@sn$(9>zDbIZqTtDsCqQuD&n31C)y??b?bT#6MDSAMex7$kOvZb?V!`uBEh(uh=3zt1YkX5jBa4(D)rk=HQGe+`7U^Cj2TehZ?9uD=Ua}yB6NEEK_>dnX_;aS`+rMP-Vqcl?1Dd7f_ok*_WM3!1D>;rE?F{$#z;URSk7{@orU z9lYCK{kwTVFp=fF%`=!n;Qr!cjgX<~r?csGdAq>l%VlFHPx-d-=4DV`8#DE{jKz$R zXsrJm-*`eA>wvy`+Uq*wR1$EKtBfScRrtK)6p%v!%}~|~q-%I`!ZrVN#UT=&OnV+2 zh~QaiWH<#I;apE1_VY?Tf}z{)U9BB7lUJ?jJTd&zZa2krV?hbG?uB(05J1CdA3`~z z5y1Kh+PvXuR&4<5$%lI)th*^tGd?#PO;7$o?ds^u-ZBD9Xa|b7VM0WsIr6Nd@mc|9 zCf0#$Qt?UXKmCz~rKRH+=d>wNvv%L*@a+d+aSE(! zx`FKyOSX1?8?ocmITQW1={%y^M=xxsPfS>9q=MSR#dclh8A{(;*0`Uio3)8>o*=Ui z{+dFH{CIR^CTG}ke$PuQ>IP+X%&6g?u@i!i_28E4GH$`1 z?oG*@!~USs9_sRJRwY%?oyKgT4bO$wg&tT6u0)vLsgh{y-j+Rex{*9$nU&KnWaL%! z<<(WYPg|v|M=!6TjT^{{B}*cK1YeO)#E$PXZ}>=lJ{?jSmTM_`Jnl5X3lttbtPs;A z759&Al+freK8Qt`F#!>%)%f;)fBc>87@`AzwnokY_%o)``R~bsbDzp77BRi%mE7dhdQs*0~3_(coGXzfyzf@lq}mlfd>O{&MgKTAKGKXi!B zjip2X2EQ&mVjIu%$aYfe0Cph#3^Yk~rbzjk=>C`!)+9IOiC zQ%ukmESmPVlXg?8*9dC4%3r*jJ)RY1K~Qf)$jUAOKEr|{xLWD@!MU-eIn~w!_QH@V zKk0cBna3^8be?9~g+`z!{tCiZZlzL?mA^!uo>rn1?P${T^s#5?*R{g*?fRtWmb)7Q z9_*D8OpmVaU!MXVjHP^g3;};5zBcZZj#zg3i4`r>$*XARtKmOMiw=bKu}F+TEZCqO z*e7~27dGGQYm|(-_E;IC_M`o-rxUHNQ;l|^lMOc}=*zI=9+9|B(mCG3{~CPf!=Fe? zs|R$eq48hyK4@(AKIOO1|ALX>h69dW4lW|%K>_6e1G>Ri*tDaUOUQ+0X*6eyV3f6}E z3iB>_r!`;@JUApOsc*U#p7j0^_%{M0&~G3=5d$V$Yfo%S8sdlLZ~ zpOqk(oG`mlDj@@7NzTjvg4922*jK&{XmmWyAB6zLZYS}!o$`;i37YZ0+Rw^d-f0rj zHm}BY;C=d)8BS-CUhj|gnc0KZHBY~qzxFMt{z(GVM&`FZ0`C!UMetK* zMb^;Jwl}l3#3O-R(G~3Om+%-rMZXF#5+DQ$oK5 zITrXSX%A}abEDe)qk8(YV9>QKG1V+>cG7!)b2M=wfNXO_A*ABuV=8&qUEzw~Qkq2g zkeF__3;ke$s3URyEzaDd;{6=!KFir_~2G#BN56pMubW1ldkip%1<^kbuYl z9z&v+?>xWv;7i$N+`_&Y1<8mg+A{Rm?ySsx)9od4F_glw=w7frQB+d$bnpYG{ z(FQeF^4LrCcH0;&ad{*_cC&WT&QN-Dj-jS+7Gp46O6;?9mWi30INXSZZ2$Wk=+}iS z-fR=YDLa#YIc-0t`R>;htGr zsEj(v5nItqSAQX}@GZfF?1zasa#qcDsKyKrGRg|+c*M{@@>r&F`G897caI_Q0OT~H z>K%+ZHusbZsY<<|ojkN<`;l|NJz89q7B-up6C92n9mtxx&lnvKeZdSL2kHy^#_)<` zoZGxx$Ccx*T*t{xf=xH7H2Xup$lbNl zu}=@`)FkD$*KL5AaQ0-XZ6O1l?OdumFq1Z^y4tgR9Tw%jth&yKahk^R!ZQY^8{|ooG*HjI|;qOE1n1pT*dtDMkQLjt##B~ zJc@*1-@-w-QUm>m(9-w4W36RoGDbqb@a(b2R`2u$$L{b4qg*v!$#rRFVj5`bCDL?< z^KX3j>$e*#TduG44a|3=`eq8f2F>0jcQa;FsfkVLZv6g*VI5dyS@};qc183#rbe6l z1&rPC=3Wdp;LEZIF)c$pUSQgwb@GM%n9+HUY_pNo|K%U?QmhwZTwmYTGpS?C^JlW4 zXKz+bQ272;Swk|e1}mAkC((DnZbsmqSS&t2Er%4kZ(R9!De=ZwHUPZoAQ|oRPxV@d zSDI3Ar#X3nsI>i*079OiA9ZQW2q7yXoytgg*%USjXgEyds$D^Jox^1!_oqlj=#RQAaF%=IfXQ+uYObPB+)ER?VsQ^OuKqQeXSr-r@$?AWx=U2)1Ec z@5+gkfqJu}g?14u*EEI7|0oWsdEC^>Hf-`(K0Doql>5X}=Za9Bd{Zs@2I?PQqRd>q zIw%oDe97DaUKr}zyKiwe6Ak(ZFP<#h9=eNj{xtFT#2Ol^oX@c|P5L)dgAPsMjvTVk zUg^5p^cH_}Zl_UJ$Mf;}&ElMsH+O|S?Sc(?0fEf6*81?a+Qe#nb6hplLD=sqq{7~P19ykW?9hz>VdfX4cN+G>XE}{kX#3>|v38x9WLAfv_A*Ei_ZG&- z5%euLm~yrFh5QNBcUDbxdw+_(NN#e|VwyYZC(? zmI4$|3B_PfL?Y1Xhh+LQ8&B4o4}1KxclPbjhkGNR0`@j8aNait(yWM4>|u{|O9%Gb zM@TFRBb61~4!dK_#KuU&S!vKyw9?^{kfn?qe zUD`S^)h7@9zF;=IYiQZTMs)MUFo7`^oXLu8qj{A&zWliNI{dS_L?qE5%Dr(n0Tt&; zGD+vpi|*PSzsD~5S-HI)I5f9c`MQ!x;+M5_2OrdpHIFQ7fldZ<9lZ;}(QhhQrwc3h ziMqGqbb4pbuH3hSVz@gV@XwX zV2YCuJfUz=CJ(1ljc>s&@g-^Y&+Z$V8*>MFs6}+S3}v7o=DnJz>~#$%~)O1l^KadJ(@#<5J7!Az98gre_Qo$5~EbuV>TUau}wx! z(REIkg)D?+X}A3O`N$QuHg(cH=}oo5If(4Iw?By2UyIM-`j)^m z2)UslwfT)clJ)E1>7|b#%s8s8w)hu`-(%4fyB1EHs8wS}7>ACJUZ9C&B~M|>geF?# zr&rs&Mtkr6rgeIU-IyLwezAUW)4z7!_9}h}VNQoZyA^Zc=SNRed+W~7dkFY}3W57b<*=zMSX!40l zThwWbB--%p`5ScH5j1Kh$iSPz$Ux4e*hH!rP%{oj($Ip#Xt1lHw- zkvYi0ZXpSi#wC&npbpe9?|*Y^eUYD34Sj58Gpf3a?dIhz0}ZuvW1;Ekj6V^qt|3_9 z;#a&NL72TO(`Mcu|E(Vcs)m;<9T|KkitiCg$q(Fvx47Ngm%|2GbVr?5E+FA+vy_i- zyU2n_jemdftJ+z#{1%&q%?!WoOZwx83VXgqG_JQWMsm%8T(pOuF7AMT3r-N0x1T6@ ztM0oLcZpQ+H0ip<7(Rk58r-(g&*@@-O6E+p)mch;=>2t_ioG__4VEaYc6V||tw34| zZCFS0%Zo@Z%&^OGMf0bBE@yeqSKx zzOOT&)9aAzt$GNt>oQq>_%)7!N$qzHGBmA4~o0|flij5p;ah(8o zfsIU%97-Rg=@qdu4q=HQFH{Ok_`>j@Kz9@$FPY{aA?g-AC>>Q}4%iRUaJ%A(2i3X$ z(0QN)t|110QPyvV+6%^N5UW$a=D^g$Z$b%}iWqmF?Ocv{UMT-L7A!}U(SO(*Y=Ny- zTl7r3k-L{y+JAh9Fr4+0{rt-<`~bZ#_TPS#qQ!s$etmPE?wX*MW4Kh*d{ewM_Z`+imW%nc{^JRRfc0y z#~3ld%Ht8*Q<6!nxf29R(;D{q*+R0RFq_Gx-Wixh{ zfK~F9e&}?1;6((cA}VzZAbUucMJ9fMvS|-SS++ljq`!X5i*^1AMv+KN+XMGeLRn1g zagxL*CV#*OgHbojgKSWqU5;YB0C%5aEF&Fr}}jPH>2P$;_1=4E>b>D6J!wZLJr z3)CVq(og_sH4Dc~q#Y~PZIL6?B}oy%avWkeq(7Xq1!~0@o@2dAyzGAVBQpxU%&#_g z@}$xc`Y@*i13d3BE5?A%f0SOJxR>-!G z0n;Ml*}kMgaxE6)!~_T($iGMDYE*r9Mx=W+T>kzTZT!<_-fyg=1$H{^N&Llmm#W(% z>|*)Jx_IawSH)zL%IYP#4siuj6Y2Wp%h?ZxM9ysyrPMkPXBV10SK!fhv=!V5W zLLfsU7tG>s7KoUsBJrQ%Dct(xm&*=DsFxwM5~%hVJ3oKE?D#C8{qi{f*98{cEOVftO=F4YHpl+;dP$<*?DM#B>Ze7GSpN7}F|V|B zkumx#H|54=`?JhBQ5~7zLqzDIf!JDPg(_jUGYk@XNk)-1Z$dFYitu}qMCkLuf0g-jPCY5q$xu1j z3%AeOMf!e-GlKKaE{lkJ?agN~rZKTqldiqZy*d)AUux0qEJ(PAjc@dTQxvvk?}7<@ zmCkf7m0}C&KLNzvI4J>!H)N7fqb;iA4|vTq&if`dsto%lgg(ooFdfkbwe?He$_Szk z+=4v_e~tW;gCgvMDSMku8XtjiYC@Pw#Vg=SbX>d}3znA3L2b;%Rf z@tcXq*ckFHrulEYRrJF}VcKv(h?`t;g7pyoIkO+J$oud*R)~di#n7JPh!AV*zlo{)d z2KiE#7UjEqC7+E77p|$L@7o}$!zV4Psg#Iu*tbf^wS3_>V1P!Bq_Ea2;542ncL0ZSwUAn#IXC-Lu+C>B?-W=@S%TPz9KFHYwSw1v&>#<)j963j(K* zpR)m|o25vAtm()wwElqW{k&!!Z8(3L*h_(O;KGUU_pKGzeEbdrr_&+Ns6}DCeSoM} zw9SS6Wx_w0gUvv49e7bDjdg$NX4X?hPv@`pNwOHvhxA`LS$(L1jP~A{D@HasYY~=C z71kWyVBR|Zit96^*hN~)>4lNUvI;9XE~5Ev{4Jcw9l)j9>@%Y3)ti>%vuThT9%#(ZN6S@BSx--0V< zkFG@eK3ZBK1ojJVxQ+X|L*wyuA{VnK_n~lW!W6^*}OIT?#g>0DF4Yd zAm5Iy>AV}SBHrlAHJG1E2OB|G)@J2YE5_K4S4R}m(o3X2t8dOTR~1|HF#kOjwe`fz z%`g0OwT`kH2iW~)LFDsA`~&-YCjDm7W-7Gv{G#v?R>`=|6N%%f*V{Q)xyHz^BQ3Yi zwtELZ=@6}JzvvNcA3uhVS1!_}XWoJhXia76!(@&N(9)Ag3bOWV9?{P!x? z_M{2Vxp87@;3#r5F~MHxr)dl{#LnU`BIxk>5gywgi){_iH%Wbgk}@OZ5ZfW&1nr?Hs>R7&jnM4%s}qYS74n zeE}m+Utms4=e^=A;Mp|@(>EYFlWLp7rpYTn`aU`g|X!H{>y|ULXgA zjc)Su=_%crW*^vAA2|OKG_Lr&p<$b56G|U4R{l5^*0A6|4k!IZIEa}w&)4=J{bD?N z{X|izJYQ8qV&`sR=>`Du&-5Za%6HYGT$&#bJ;GS`?tGMG%%SkCvcpt_AF)(g+?@#J zZIaFyAIhvgkdU7ctB=`^__7=*JGX$YbyRi`y6kUD`4RRUl&ug}z zyWI9LNZ!HxN@TqhUiN5Bv*aZZ%h;h}<#EYS%zC@^08NZwhawf}OBTT6;iH(yWc z3LPd>w|9LBSfsr%kB^$Jt{zB7MZps_7445?DAp{EnRhIT3sia6q8^*#NB)s{QaMS2 zWWlX2UjNzqw&`^(J9nS-(^4Uv4_pFkXuqvTi7cGM84{`^WZy2o$9;TY!aj-$z4?27 zE(DEQ!-vE!nYL4SW}noT_EMs1R=Mc4>WI=Np#<=2mGPetfcE-r+8p!HC5p2?5$lF=AGI__$=lr${Gt= z;a^$>X6lLil%yNSg&58)VK$L58@L1#yp`h3!8ZFAuSCBArFYpL`!_Ii48GytnHVj| zOCCgw9#K&QJ0&XX86|Olntz*q^NI?FA0n@vdu>iBp>|g3u(I@KHB-g$J1{g1q|nhK zYA2>MxYm7*zWEx&RW6I@!0V85apoSm&?taZNu?o1Cy_ZFQ^Iq=2t)n$^MByJ<}cPL zdwPVN%soBgvE`K?4HIq^J1MRMq`Ml&)K1ux?o$DOl;0wJhb0hkM7M!qOX=7RSOSKrK*Q{fybpnj@ zyxF?hY_`RDrxTF|ap&S=PunV``FYSfbE>z@@xuw#EB%?;ck(?tFL7J-P3JPpESQ(D z7r3X?$Y~=S^%o8TB<5}N3Ws$UzDN2sA2-ib?`v4pmI4-A=V#LKP`J60^>espZ zS4G=#jgNF`3yk5xZ$03w424^k<`Ce8r8G%xI;xp zex7$HeUA%!m9d8RMuB_L3xv@+UGvd3BRw)lv69_Qs+!&A?{2Y`QPl&P{AuE6)8_9O z>~2)Oz>y)9fV;{3jM8r34D(tGk=~QS6a265RMAnSke6H_#f7OCAu4 z*BI?fv~>?#td%e6KMS~w%G%&TTMEEH}ZCY1C4yw_jLLpkbDycW1FkA9P60P)V>wPKNJm4GJR#f^?Y(=DrL z=$sKIHz*dZ%lIa>vG*PS?fYk*vfPcH-L>L}Me#?Z__x7>ao^ae#?$JZPU);iILIqINXc1ZU zsP|?{^K_x^{&VZ_d=3U_){Ziall4_b=vHfk7#XLDk9e*dLuf}bU@q*Qar1Ek^=s4{ zyx(*x7V{Dh``|{M2FpP4xqPp#L$Z+GZa}mPRgh(@Hnn?4r`*7vWg=hc<67+d@NqM4 z3hr6!39biNI;UKF-j*9O7%t2^dZi~JUVPvm>y~)XmSKMk7v?GFGVybL3SM;koz@|H zwDDUE&t?<6@oo(8-(KH?jAisd-$IA?TplD0v_9fW2g*&^dw7bJR%xdbp_|Oy<&Wwk zSywZmcE-~p5PGx)l5&xogY{PH7y5!U=1o)fBRlPk>yfN!s%B*_gDilFSytyl6nHPP;8d0SsJt;& zu_j^YNrIHAAk2B04e3|pQ4#3eZfeoLl4`b|`{lc?n)WL=;glg2sYB!#J_ z!@K{g?x-IXDLZUxzX)lj&%_J@O?0f;hH)des42&dv%}48-OvrMf1mw%6{O2sxcbDG zMkKh}ZvBw-JbnK(_7be;(0wZlh|gIp0WRc6tv1Xqz>WfzOo}(+<%+ccA*k;KEdlt; z+Vv(&bqHR6i_z2Y?~SK^gp(`Y@#3*KJ7u|NQk1k^GRC$Pmg31y1M&0_WaMw4^=5P| zob%OO7CQuaTg$gQ*iuy&R~%P3QekY*6+Q?`1LeAFlewml2>X?{@=Y2GJNCqwgOi>@ zTSumEAFsE)%J&%Iy;mXMQW3wt(66~zD$d6+ox0IE$rT}nAE$aem+s;C+m|={`5RLF z<_%K3uf^P9D3o#FhL?P4R+!24`mYf45niX!vu=KG2Ez4MsGW96A5K|npy=S9t#V}P z3Z%C=Ce|4lHEPdyTw6a9p}WDkm$o#=^i`$cwpCEOUEglj^^YAtr)<@)pHy%S`=xX4 zX0k3`8-DpucdnBxpQnA|6IH0fGF|iBRQs$U-W4N012v3{f*}_&@u32qcAuyW-_2fm zhT)C!+)@wLPZJ_ayZ%Je5Yc|tE~q%QdUBy zj)~T5t&dY6^Bs#^W(;DyGrsV0mdBZeE?L?2ln!UKw4%^hXYJhmQuUbKQIqQ@z;H90 zVBt{Keev1b;^#V#pK}N8mM=?&F~rNvF`!e#w5r@6?xl)bc~QA#>E2NKM~$w;Zu!2W z-TOu+eg;G+bGu1aM3$Y~`QkKYDOzB!WyP)$nSGOy(*IS(XK19JZ#gl`RXOKMwu9Tfm(?SpWgSxR@p67eT6;|z*f4a5b&{|xAPV-&YxeVR2Sw}66Sow^W&4o~xvVv~ zhO6Ps;=-ChgDXj*!F7YW)}+C#4v%6Vq5~=KWROx*1MS`!>?5_RG;vvX3!P<>idZwl zkghQQy(Lqy)0N*zae`v1l(Edy6Sn>(xPl1*EN|l6(e)AU0r+kBQ6>O4RXwf{|qpPa2thtMRb0&d{@>D7CV+NPfW|7J1F3;8Wkb z53bhP&R*@K&sy>1Cl3Ii3O` zZCd|JV$ruxd4zC#agLhnz%L1P6@mp)?M-ptgq`=ug-=JwPX*3rs+(DPpb|poN0Flr={e&J>VwVg0VGfQp|j^WmVL|$@BC0_?|vrwKG1+il5Qjgrexs}g@E{vUXV44k&%Je<$7Ok5|qcXQ@Vst0m z9fNNb7uR`xmv4KY4(bX?%03)Z(DkIxOn>h!jc&oTRx@0W7y6IoH2 z`&W!zRDewaW~qDEsNoTI;xJ*mzF^uJ>t7a zh*6h5p*iZjXhQC-`u*qn%h`QdIX+h(7>gtMJM*Mwn7Q*UE86_^SO7+0*qQ2IyR_gi zH>g1-toP63kiJI@VO@qH!u4DX|MK-tL+^fes{%F{KwI6X?}w_cs!VN~yg+{lp-=l4>`8_WDSlVvQLBp^R(^mCJ&|AYsF0h!5<({T`N57mY z&js89p+Aq|B`3aI1N%lATq^qKY&E)lmY9cVN)&q){;LS1?$to_3-8x-z6q@vG)IG5e);OG|F%3LdMtljtMfoAK?smPM@;E~ z?D}pKA)sp5ekX3X6hEJN4q%Cq zly%tEEA^vy>Co>CY(e$c?2a)G4}4Me66fK0HS*UP0c}SCjw?Lle5M*GDxbv1ux*U* zdHpP3h3*Cj{d>$$_69op=0IH;z{Bifo8wuXB_{s4Y83ju?W8{~VtDL(DDQ0Ti(+oZ zzXogiI!7it^WsDHatga~yVd~g08t8h%RXd@njXhdl(o^MGKx?`yW8VPBvXx?6a)gJ zAx4ZS`k)}40z%^$m)1Tbl78AZI&uwm;uSqd%GJEr-|@+uFTL)qXBPnXVE2bVSWMO! zJ%#>9a`o2rYR32xcErQ-7;FGyiF2a33%l6k6KS$Ab;OJhcHUVCi4sg}; z_v$+WjA^7QV@$#~PJje6&^6&yCJe;g|3*F8o2NG>B5wsX*#WTjo3t`7G;`hP&|R62 z0)L#LF&L9u1KMc6kI&fILqAuG)@jRrU-Z(GGTUs(AJ`38%2nE!pTl4Moe`tmSYrPU z2Pzi9U5!O#jSuxMQYbDklSeO9$@Sv+GeUBz3;(R{_HG3N@*ME#1L-!=n&AqYF;B9> z5nq0#bmSjlhe187b~qmUXP?U4^Ow52-rEEgmVDPNI~dXHF!4y+p4T+LwDd&2WZcw) zaJ|7>f%`?+OqUK555veGyC?{6PfSGh){e7b4{lfhSdk||psfH%NjPJvPJIl!pK@0-QNNUbT<@Ck17 zc23f1d)?x#mZ|lW(C4A=mdSK7W@(@IBbAI#??jlB+Y7}1g)2>{8$5J(BpODu%Wu;%1$CdUW%8Dlw>|Bbi1Zx`bOzrmg!;{+cK-K z_)7Qrf>~vzv$0o&hIp^F77U;2ZMp9{X!gWC1ZoRkq>dgpBsDi>iVQ5zd(iivR>YTG z{r$Xr7Kr8vZ4TFiOROHXR{|zRcM)ScsnAjT6s@)9SG*bLrkxZ4 zC+h}l8{;DF%QY>Gre7x23zv0JQzwbPwT7jlcngg<=A1IZ5+^GJ5dgh&R+tFmhtJsy zQ!Xvj?^MJDufQLTgyg6=O9=pc@0pBA2yz|63x(dC`io6~>9R98H({&LnhuyXJtqp^L`^~&fI z>1`ENW!2;Mx}jrhGPiKSUp&r{DOVy~__ee{SofHx0Rf^Eg1$zvU(h~_ziDu&_m6vV z{r3|kpoNAhxk|Y9o7Al0Cin%VqFd0du_|U4vdWkDT%!E{=jklNqUydjE-C_2(hbtm zB_%PUgtT;nG)Q-IzyN9K2I(&8?(XjH9GIb*Vczk%uJ`|CKK!nGuf6s+J%L)8q0Y#Yqvi8Lu;TzanS? zVsY#6@1+!I=O4*#-}DpbR`Zag2P171V4TuyK}EWm?&*{UYrjN09E6SZ7?PkA{FieT zO018s{r7PHN}871i-xq_M+?lUMtEPxI)|%Gmja2D+HqMcXO{;D&>j zrD5r*#!I%AK%TGbEYRhj!6a&*RWtjS=p;BfhTVl}oc4_aAmwdR{L&vayykVem zKyQ`iRur1L%NpV*rKJvoP9Rn|21cb;O8HruVic2ek2!^Rc)pX}I46=W?}YU*}1m zUA6Qov*#*d;qt&SQz`3#!)#${=keNYi`Ryjq2RM4>ghs}@AFq5SDy*_3$KS)M!h2( zvVZo@jt$$d&dbaP^wUyL$1tg4m(O~Zx)0ju+xK%_nc<@tjQY8YbyC*qQy|4SdfAU? zdTeaj82%NGEzi0w?B9HBzRtrO8%l*<;0VjK-F!6Ne1)@rJQ1yV%^{O4-$XrhO|KB1 z6UDtJJuyM_Z2LQCi2Hn{J$Bn@z*gK=?Ic}ND^%AH{KGx@?fAFt&%&|e$cKYwf_=EM z$7p$R`zS^d#S5Gtak&MZseq$E;RejPDqrpH&@b37(M|pV({EmlfZ~6GM^Zm)Ngwx7 z0KeU~spF}wf-N(?Fz@MDvpyBucq;b9#{AjD(!bY@=}OGYfG{P8IM0lyA4*{xrlR%6#LAL^xIY3vQm^`cGkgn4f_O)(TkLVjm0= z@2hWJGbWGC*VE07n5?!?D|B3+S ze*EAE1_Fh}A{t=4nZ&ILpOjF5cNG2YN6~YK4oiJBg^8~6VyfNpjY{cRx?Q)KD5|JU z7EuhZv{G^UI`zAiF!~9~#r}jTz02}{*ZSgkF1iiv3zd6Uid*zW(HLgaa7j+Zld__U z!@<;!ePScrZKq02<)+A|;@sDn&#Bu*pR}irRRQkPf$cinWBDk6noT|)!MR|`A>oid z*MeHbXv}BajV7`uez50J)h#ln6;+VwJrrLA8yUm!(}m#^TDL&gchYe;57{WeS+Hraeq1Ow=qn{D(2p61zMU%;E=-If!UWqJsXu;2jCKU^FKD^HH9@cTmAPLZ|F!jh!VU)9EM;crYK47K4 zlWNXyUAy7C*oJ(N$O5R1p@D*|%tf?v|A}9iPa6BWx--GGqu`g-Wn!4sY`(v!;2p{d zYJ634VI<;`=ggeW>$~%5{y?h9?~gCOg+ThxO!{?`?(>k3wuvvq$i7B??eJ@qNpSFwz0+bYU6T;XKI516(ulL}@&+hJ#MwweL8Mp*H; zJZLZW=)(G-4AT`HhS6ooV4EZG+ntC_o;v#}{n%DQSGBkHLcm-X%qt_iOvJAq-B`fQobN&b5C&6iImeu8Jg!$bgr>95iFQ?-~I4YSXe7Yc>d;%`!66;8i)yfVQy6Q zyYmsJ#S0BCw%u)5@eTf@BN8Z2%)Y={w)^fLyA{`pZa#=L&T1q|eI)$`%)GR#>$!f9 zgsQ$wV8vXaShxPgQ$)tLGPg8>^4%8r zxu-j+2b;-tjdpypI&n>~0H~XC(!Hrj*5HZ= zw!sud6RK_f!Y4eLnc^^*V|BA8c{q!P7TyMd?g@ zdW`>WnwLyjz74OX8M4%h6*eM#&?_k)I5vsY-0^rh5!Rw{;CAf8lUSZdAGbP(>T_Q; zW0%#lNb;mv|Iz+|uksGA$`z(_eDaa>fPj4Uk+P<`_=_yX zQMFprNSs#0 zU&4Cev05zzb~&*r^aK7%{oqbrhTBRY zHh*ZR`aH_O;OlrJ?RerozFIkFxSp%qGCK=aoDop;bv#B(%b7bg(ae!eWmJ9t0uC*0~+WdAAE4x}(5Z6HdWIs_qzv3Adnkbm!H&kl1ELpJh zf#YQ&4(AHj&kw5(Qv2A`RV~KOI^V=KDAji*AM6_!3@;BhA{!TW+6*s$d^o%JY+NWT zR&wPOs5O$ckoV1`slh$2=KVKCX8zlT73R&VcZ}Sk=mTx-bhgqD1wpKz_oypZvxFX1) z#(PcPd|bnfor_}_*u2BC>^+k6*d6DslsLN|jRy^{f3EU(nQ6zZpdC!;>RS00&j>Wi z=f5FUU`!e4Npw<1;64MqQVslTz6R_XChk%N(dfuhaa5yVE_u z;O2GsS?fCdv5-NpMsXsZ_QTJy-#fqEgD5)RpNJ_r5t|^Hgd7 zV{P1!CGir!+4cjg^y?VfUxrvRfOFp1n*w!q8)pHz?A6_up)eher4*9ImeCgjOyjXr z*stF43~ z#EE5n{*D%LecQUp6!NP@wP<=DB8Ne(+`I9NTID*-tj2lb5Yx+y*DnQD4pa&XxVnxz zoAJxWETGp=Cw=*?i>vS?iyHki8Y%75LljxYdy1ZzQT;DFrnao@`p#$3HHT*yK|3*G zbGC}1m@^kr{+aCj%Dm4iVnrAz*s{v9P!`p;F1@9&dbpZ$Usx`%6}-F=yf-(_*>P1- zhSj#li&iayrDT#^7(VUBQ~)aO)waD)jy=Lej3WJ=n zv9sC`IKamf6%tBH;?iW}>pHu-KTc^=_fr64GzL6GO+#-9d$agdJM;G^b)312_d!dRTcxxqEdDG*vXBN6T&n6bMS) zW0Do|^Fdfq?LDW&tkE4n*72L#zEtxto4H@YY}HwMh=sn!zxlr^2KN9T2L~Tv~|jwhJS2cg`*L zIDK>RR-Ut2A&Oh1LmO;+{q|>Sv0sLFyS&L)Z32nd1g0>g@r*Vm?_qj(sV=E|?%Uf5Q}FU<#?L1>k&jWsgQ8vQz>u~oo0DQ z$&dt6FshXHDw@Yw=g8&{{$T3jlghh}5H1;b+c=oEZwLJ}J(!Qc#~ESvVMtZ{Mb`J% znO^K0#91mbrtvY>4jaTkc}F7sspb-hTk*qI3Cbw#xMii{9uutjZbw zy6EB7kX+ImCHy5n^Na+O-#urh7yT)Q#7T46B8KTA1xq;gVz`&uPjUAM_0#Qw_cOk2 z3o9qO)hg9Hw+Ua~=o9G}>uQS(53>ZABkR%?kZ69qrc=&Ro z^mTB`Eh{h?SpH+@JFKOJ@uIJo8f$gSX>zEJSGh95Gd*Ib=LSo7WcL?G&u>vV&4o9E z)kV#iL<-zh^t4J#x+ohk!Xz-JPpio<9McHLW=9`Z%fSpLYiz{YFTd%O+o@cZPa~Ln zdGFbD&4z6Z>jn}^9;x`{u<8>pZO& zBW0gl8nuJao1zmAi71RjaC`~O-$^ZY`j}{dF;Ait?`bE@EhJvac}!voeYWkh z(5rJazKI^a+|^*zsH*7k1zOjKjU0-uZR1kX zs58Ut_xSF>c?#anIlrewxvU>g*K@%-x9lDJD+Bzy_{M~JVUcZd*E=}!mQ!;xH^9}J z!xZX+9pQF|BlsoeQ64Lt$RK&~4)Se|qlB+VS@x#i~Pw@D!&pK-*#3B1OLl|fKbbI?{ zraMTSR3U6Z)`MGk(@k z0v-F5zk4yWdBcDGsu>zs0Uzc!$LU6+^gBGQ_sDfyvsf%*LXQAB?rzV==?9gtpUB%~ zR>{zyeG7Y{m7}i)Now!;uob)-(jc+1@+~`!@NGkJk8czD3OdqW;tij>yLtJFs*v_xs zf+*f&X3Xu)mqatoC^> z+Od$8)FKsvJN!pp`cGT+aX=%fH6uOnUd@K~a zr^oi1`TJQV<>!x=18klp&|QRRqq4T32@#PRPyTU%Qq}#Hzs>DlbMM)rM#V+pbRlVox2=*l3@SPvG!~ zw4Y+B$mkO6-4kRj1mM0<3OGRCP{mjbEH>2l!T~%;iUZq_YAbc7it-Rv&)1^t=QZ8} z{qRiGJB$I`^9x|{LG{Rlo}S0)JtwDHod2A1=Th6@>GZpNccqZr6XmnN+Fw;8G$I%0 zzq#Ap{7h7T)|!s*rY9;fZqY}G!Rkap(O z6SkmF&A`>K?(hcjCIkv%#^UFx4L?lfd^|AI`~bv(ZPyW{fHyLKyyMnqhdm6`RL`=? zaSfBi!o$q=<#MqoO+**c>k*J%96#g8|W}6pKlHI^bG+O2Z(4CjAinj2RB8n zfl7`kR{4$<_YHm=c+f@mU6fB}*1rgJ0jo2KI;01;kU85-^>`mV25%e@F&5vXPHWd! zp9?%)DeCchZGG%6Y*m7J98hH>UrWxNg18l6zi@j`kcoaDE@LRI6n=V|!oWVejSZd0Bd>94e#FTuo~c)k8z zX+KZ)Acma=t1lc6c?kL8AF@``QSdWvL3nKja7FMDJfhhve45a6$e%~?tq%9A-t?^; ztOVUW^$-Y$rqHh0ZDgVt`2g?dK@d;^hLI)wJM61=CUegtbR#MdSaNM=J_KI!lmXff zOBtWHOZ5^xoVX{O35AXgrO0?@^-4t=UiosIYi0EK)+BA#=aJ7>p`Yt0Gv8Z2fuSlN zkMqBM+~7h5d3^Kbe7ghH*svRaBbO?!6oGM(iK^FT)1=HZYKeA!W;uF{I=TO?Wq0vb zToxQma|nA6rMV3kkYbrwW&z0d@2odU$61;lsE}{M_3JdRwFxL_hkv|xKVnn#_p5$( zR{=;%wtm`* zT-11M62ha48E^VR$9D;acJ_&6j(J+hUU>xA7{4jJp_%WUzM}D52G(iqiC1qw^!W|E zc8mw9&ZE>hc(Y%uZP7WB1T<&&+9`{o#Rjh;#x%hIpBHECV^U_=$)QQOG6dEYb?2qg zⅅ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