From 7df99fe52a94e0be39694ff952a4660591cdf0c0 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Sat, 24 Dec 2022 02:25:42 -0500 Subject: [PATCH] Add loongarch support. Signed-off-by: lixianglai --- Add-Acpi-support.patch | 1347 ++ Add-disas-gdb.patch | 3191 +++ Add-linux-headers-and-linux-user.patch | 1654 ++ Add-loongarch-machine.patch | 5751 ++++++ Add-loongarch64-rh-devices.mak.patch | 3212 +++ Add-target-loongarch64.patch | 16645 ++++++++++++++++ BinDir.tar.gz | Bin 1602438 -> 2434613 bytes ...q-routing-to-compat-with-kernel-v6.4.patch | 41 + Modify-compile-script.patch | 44 + Modify-kvm-cpu-vga-qapi.patch | 371 + Support-rtc.patch | 369 + ...rtup-failed-with-netdev-tap-vhost-on.patch | 36 + qemu.spec | 57 +- 13 files changed, 32713 insertions(+), 5 deletions(-) create mode 100644 Add-Acpi-support.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-loongarch64-rh-devices.mak.patch create mode 100644 Add-target-loongarch64.patch create mode 100644 Fix-irq-routing-to-compat-with-kernel-v6.4.patch create mode 100644 Modify-compile-script.patch create mode 100644 Modify-kvm-cpu-vga-qapi.patch create mode 100644 Support-rtc.patch create mode 100644 fixup-startup-failed-with-netdev-tap-vhost-on.patch diff --git a/Add-Acpi-support.patch b/Add-Acpi-support.patch new file mode 100644 index 00000000..a7f6aa7a --- /dev/null +++ b/Add-Acpi-support.patch @@ -0,0 +1,1347 @@ +From 368c698cce8104a2748a672cf6d6bbda2059c673 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Wed, 7 Dec 2022 04:19:35 -0500 +Subject: [PATCH 01/11] Add Acpi support. + +Signed-off-by: lixianglai +--- + hw/acpi/Kconfig | 8 + + hw/acpi/larch_7a.c | 600 +++++++++++++++++++++++++++++++++++++++++ + hw/acpi/ls7a.c | 598 ++++++++++++++++++++++++++++++++++++++++ + hw/acpi/meson.build | 1 + + include/hw/acpi/ls7a.h | 80 ++++++ + 5 files changed, 1287 insertions(+) + create mode 100644 hw/acpi/larch_7a.c + create mode 100644 hw/acpi/ls7a.c + create mode 100644 include/hw/acpi/ls7a.h + +diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig +index 622b0b50b..2f2fb33a7 100644 +--- a/hw/acpi/Kconfig ++++ b/hw/acpi/Kconfig +@@ -15,6 +15,14 @@ config ACPI_X86_ICH + bool + select ACPI_X86 + ++config ACPI_LOONGARCH ++ bool ++ select ACPI ++ select ACPI_CPU_HOTPLUG ++ select ACPI_MEMORY_HOTPLUG ++ select ACPI_PIIX4 ++ select ACPI_PCIHP ++ + config ACPI_CPU_HOTPLUG + bool + +diff --git a/hw/acpi/larch_7a.c b/hw/acpi/larch_7a.c +new file mode 100644 +index 000000000..35d4a7526 +--- /dev/null ++++ b/hw/acpi/larch_7a.c +@@ -0,0 +1,600 @@ ++#include "qemu/osdep.h" ++#include "sysemu/sysemu.h" ++#include "sysemu/runstate.h" ++#include "sysemu/reset.h" ++#include "hw/hw.h" ++#include "hw/irq.h" ++#include "hw/acpi/acpi.h" ++#include "hw/acpi/ls7a.h" ++#include "hw/nvram/fw_cfg.h" ++#include "qemu/config-file.h" ++#include "qapi/opts-visitor.h" ++#include "qapi/qapi-events-run-state.h" ++#include "qapi/error.h" ++#include "hw/loongarch/ls7a.h" ++#include "hw/mem/pc-dimm.h" ++#include "hw/mem/nvdimm.h" ++#include "migration/vmstate.h" ++ ++static void ls7a_pm_update_sci_fn(ACPIREGS *regs) ++{ ++ LS7APCIPMRegs *pm = container_of(regs, LS7APCIPMRegs, acpi_regs); ++ acpi_update_sci(&pm->acpi_regs, pm->irq); ++} ++ ++static uint64_t ls7a_gpe_readb(void *opaque, hwaddr addr, unsigned width) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ return acpi_gpe_ioport_readb(&pm->acpi_regs, addr); ++} ++ ++static void ls7a_gpe_writeb(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val); ++ acpi_update_sci(&pm->acpi_regs, pm->irq); ++} ++ ++static const MemoryRegionOps ls7a_gpe_ops = { ++ .read = ls7a_gpe_readb, ++ .write = ls7a_gpe_writeb, ++ .valid.min_access_size = 1, ++ .valid.max_access_size = 8, ++ .impl.min_access_size = 1, ++ .impl.max_access_size = 1, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++#define VMSTATE_GPE_ARRAY(_field, _state) \ ++ { \ ++ .name = (stringify(_field)), \ ++ .version_id = 0, \ ++ .num = ACPI_GPE0_LEN, \ ++ .info = &vmstate_info_uint8, \ ++ .size = sizeof(uint8_t), \ ++ .flags = VMS_ARRAY | VMS_POINTER, \ ++ .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ ++ } ++ ++static uint64_t ls7a_reset_readw(void *opaque, hwaddr addr, unsigned width) ++{ ++ return 0; ++} ++ ++static void ls7a_reset_writew(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ if (val & 1) { ++ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); ++ return; ++ } ++} ++ ++static const MemoryRegionOps ls7a_reset_ops = { ++ .read = ls7a_reset_readw, ++ .write = ls7a_reset_writew, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static bool vmstate_test_use_memhp(void *opaque) ++{ ++ LS7APCIPMRegs *s = opaque; ++ return s->acpi_memory_hotplug.is_enabled; ++} ++ ++static const VMStateDescription vmstate_memhp_state = { ++ .name = "ls7a_pm/memhp", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .minimum_version_id_old = 1, ++ .needed = vmstate_test_use_memhp, ++ .fields = (VMStateField[]) { ++ VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, LS7APCIPMRegs), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static const VMStateDescription vmstate_cpuhp_state = { ++ .name = "ls7a_pm/cpuhp", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .minimum_version_id_old = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_CPU_HOTPLUG(cpuhp_state, LS7APCIPMRegs), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++const VMStateDescription vmstate_ls7a_pm = { ++ .name = "ls7a_pm", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT16(acpi_regs.pm1.evt.sts, LS7APCIPMRegs), ++ VMSTATE_UINT16(acpi_regs.pm1.evt.en, LS7APCIPMRegs), ++ VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, LS7APCIPMRegs), ++ VMSTATE_TIMER_PTR(acpi_regs.tmr.timer, LS7APCIPMRegs), ++ VMSTATE_INT64(acpi_regs.tmr.overflow_time, LS7APCIPMRegs), ++ VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, LS7APCIPMRegs), ++ VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, LS7APCIPMRegs), ++ VMSTATE_END_OF_LIST() ++ }, ++ .subsections = (const VMStateDescription * []) { ++ &vmstate_memhp_state, ++ &vmstate_cpuhp_state, ++ NULL ++ } ++}; ++ ++static inline int64_t acpi_pm_tmr_get_clock(void) ++{ ++ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY, ++ NANOSECONDS_PER_SECOND); ++} ++ ++static uint32_t acpi_pm_tmr_get(ACPIREGS *ar) ++{ ++ uint32_t d = acpi_pm_tmr_get_clock(); ++ return d & 0xffffff; ++} ++ ++static void acpi_pm_tmr_timer(void *opaque) ++{ ++ ACPIREGS *ar = opaque; ++ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_PMTIMER, NULL); ++ ar->tmr.update_sci(ar); ++} ++ ++static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width) ++{ ++ return acpi_pm_tmr_get(opaque); ++} ++ ++static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ /* nothing */ ++} ++ ++static const MemoryRegionOps acpi_pm_tmr_ops = { ++ .read = acpi_pm_tmr_read, ++ .write = acpi_pm_tmr_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void ls7a_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, ++ MemoryRegion *parent, uint64_t offset) ++{ ++ ar->tmr.update_sci = update_sci; ++ ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar); ++ memory_region_init_io(&ar->tmr.io, memory_region_owner(parent), ++ &acpi_pm_tmr_ops, ar, "acpi-tmr", 4); ++ memory_region_add_subregion(parent, offset, &ar->tmr.io); ++} ++ ++static void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val) ++{ ++ uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar); ++ if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) { ++ /* if TMRSTS is reset, then compute the new overflow time */ ++ acpi_pm_tmr_calc_overflow_time(ar); ++ } ++ ar->pm1.evt.sts &= ~val; ++} ++ ++static uint64_t acpi_pm_evt_read(void *opaque, hwaddr addr, unsigned width) ++{ ++ ACPIREGS *ar = opaque; ++ switch (addr) { ++ case 0: ++ return acpi_pm1_evt_get_sts(ar); ++ case 4: ++ return ar->pm1.evt.en; ++ default: ++ return 0; ++ } ++} ++ ++static void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val) ++{ ++ ar->pm1.evt.en = val; ++ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, ++ val & ACPI_BITMASK_RT_CLOCK_ENABLE); ++ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, ++ val & ACPI_BITMASK_TIMER_ENABLE); ++} ++ ++static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ ACPIREGS *ar = opaque; ++ switch (addr) { ++ case 0: ++ acpi_pm1_evt_write_sts(ar, val); ++ ar->pm1.evt.update_sci(ar); ++ break; ++ case 4: ++ acpi_pm1_evt_write_en(ar, val); ++ ar->pm1.evt.update_sci(ar); ++ break; ++ } ++} ++ ++static const MemoryRegionOps acpi_pm_evt_ops = { ++ .read = acpi_pm_evt_read, ++ .write = acpi_pm_evt_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void ls7a_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, ++ MemoryRegion *parent, uint64_t offset) ++{ ++ ar->pm1.evt.update_sci = update_sci; ++ memory_region_init_io(&ar->pm1.evt.io, memory_region_owner(parent), ++ &acpi_pm_evt_ops, ar, "acpi-evt", 8); ++ memory_region_add_subregion(parent, offset, &ar->pm1.evt.io); ++} ++ ++static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width) ++{ ++ ACPIREGS *ar = opaque; ++ return ar->pm1.cnt.cnt; ++} ++ ++/* ACPI PM1aCNT */ ++static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val) ++{ ++ ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE); ++ if (val & ACPI_BITMASK_SLEEP_ENABLE) { ++ /* change suspend type */ ++ uint16_t sus_typ = (val >> 10) & 7; ++ switch (sus_typ) { ++ /* s3,s4 not support */ ++ case 5: ++ case 6: ++ warn_report("acpi s3,s4 state not support"); ++ break; ++ /* s5: soft off */ ++ case 7: ++ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ acpi_pm1_cnt_write(opaque, val); ++} ++ ++static const MemoryRegionOps acpi_pm_cnt_ops = { ++ .read = acpi_pm_cnt_read, ++ .write = acpi_pm_cnt_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void acpi_notify_wakeup(Notifier *notifier, void *data) ++{ ++ ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup); ++ WakeupReason *reason = data; ++ ++ switch (*reason) { ++ case QEMU_WAKEUP_REASON_RTC: ++ ar->pm1.evt.sts |= ++ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS); ++ break; ++ case QEMU_WAKEUP_REASON_PMTIMER: ++ ar->pm1.evt.sts |= ++ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS); ++ break; ++ case QEMU_WAKEUP_REASON_OTHER: ++ /* ACPI_BITMASK_WAKE_STATUS should be set on resume. ++ * Pretend that resume was caused by power button */ ++ ar->pm1.evt.sts |= ++ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void ls7a_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, ++ bool disable_s3, bool disable_s4, uint8_t s4_val, uint64_t offset) ++{ ++ FWCfgState *fw_cfg; ++ ++ ar->pm1.cnt.s4_val = s4_val; ++ ar->wakeup.notify = acpi_notify_wakeup; ++ qemu_register_wakeup_notifier(&ar->wakeup); ++ memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent), ++ &acpi_pm_cnt_ops, ar, "acpi-cnt", 4); ++ memory_region_add_subregion(parent, offset, &ar->pm1.cnt.io); ++ ++ fw_cfg = fw_cfg_find(); ++ if (fw_cfg) { ++ uint8_t suspend[6] = {128, 0, 0, 129, 128, 128}; ++ suspend[3] = 1 | ((!disable_s3) << 7); ++ suspend[4] = s4_val | ((!disable_s4) << 7); ++ fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6); ++ } ++} ++ ++static void ls7a_pm_reset(void *opaque) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ ++ acpi_pm1_evt_reset(&pm->acpi_regs); ++ acpi_pm1_cnt_reset(&pm->acpi_regs); ++ acpi_pm_tmr_reset(&pm->acpi_regs); ++ acpi_gpe_reset(&pm->acpi_regs); ++ ++ acpi_update_sci(&pm->acpi_regs, pm->irq); ++} ++ ++static void pm_powerdown_req(Notifier *n, void *opaque) ++{ ++ LS7APCIPMRegs *pm = container_of(n, LS7APCIPMRegs, powerdown_notifier); ++ ++ acpi_pm1_evt_power_down(&pm->acpi_regs); ++} ++ ++void ls7a_pm_init(LS7APCIPMRegs *pm, qemu_irq *pic) ++{ ++ unsigned long base, gpe_len, acpi_aci_irq; ++ ++ /* ls7a board acpi hardware info, including ++ * acpi system io base address ++ * acpi gpe length ++ * acpi sci irq number ++ */ ++ base = ACPI_IO_BASE; ++ gpe_len = ACPI_GPE0_LEN; ++ acpi_aci_irq = ACPI_SCI_IRQ; ++ ++ pm->irq = pic[acpi_aci_irq - 64]; ++ memory_region_init(&pm->iomem, NULL, "ls7a_pm", ACPI_IO_SIZE); ++ memory_region_add_subregion(get_system_memory(), base, &pm->iomem); ++ ++ cpu_hotplug_hw_init(get_system_memory(), NULL, ++ &pm->cpuhp_state, CPU_HOTPLUG_BASE); ++ ++ ls7a_pm_tmr_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, LS7A_PM_TMR_BLK); ++ ls7a_pm1_evt_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, LS7A_PM_EVT_BLK); ++ ls7a_pm1_cnt_init(&pm->acpi_regs, &pm->iomem, false, false, 2, LS7A_PM_CNT_BLK); ++ ++ acpi_gpe_init(&pm->acpi_regs, gpe_len); ++ memory_region_init_io(&pm->iomem_gpe, NULL, &ls7a_gpe_ops, pm, ++ "acpi-gpe0", gpe_len); ++ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_STS_REG, &pm->iomem_gpe); ++ ++ memory_region_init_io(&pm->iomem_reset, NULL, &ls7a_reset_ops, pm, ++ "acpi-reset", 4); ++ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_RESET_REG, &pm->iomem_reset); ++ ++ qemu_register_reset(ls7a_pm_reset, pm); ++ ++ pm->powerdown_notifier.notify = pm_powerdown_req; ++ qemu_register_powerdown_notifier(&pm->powerdown_notifier); ++ ++ if (pm->acpi_memory_hotplug.is_enabled) { ++ acpi_memory_hotplug_init(get_system_memory(), NULL, ++ &pm->acpi_memory_hotplug, MEMORY_HOTPLUG_BASE); ++ } ++} ++ ++ ++static void ls7a_pm_get_gpe0_blk(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ uint64_t value = ACPI_IO_BASE + LS7A_GPE0_STS_REG; ++ ++ visit_type_uint64(v, name, &value, errp); ++} ++ ++static bool ls7a_pm_get_memory_hotplug_support(Object *obj, Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(obj); ++ ++ return ls7a->pm.acpi_memory_hotplug.is_enabled; ++} ++ ++static void ls7a_pm_set_memory_hotplug_support(Object *obj, bool value, ++ Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(obj); ++ ++ ls7a->pm.acpi_memory_hotplug.is_enabled = value; ++} ++ ++static void ls7a_pm_get_disable_s3(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ uint8_t value = pm->disable_s3; ++ ++ visit_type_uint8(v, name, &value, errp); ++} ++ ++static void ls7a_pm_set_disable_s3(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ Error *local_err = NULL; ++ uint8_t value; ++ ++ visit_type_uint8(v, name, &value, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ pm->disable_s3 = value; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void ls7a_pm_get_disable_s4(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ uint8_t value = pm->disable_s4; ++ ++ visit_type_uint8(v, name, &value, errp); ++} ++ ++static void ls7a_pm_set_disable_s4(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ Error *local_err = NULL; ++ uint8_t value; ++ ++ visit_type_uint8(v, name, &value, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ pm->disable_s4 = value; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void ls7a_pm_get_s4_val(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ uint8_t value = pm->s4_val; ++ ++ visit_type_uint8(v, name, &value, errp); ++} ++ ++static void ls7a_pm_set_s4_val(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ Error *local_err = NULL; ++ uint8_t value; ++ ++ visit_type_uint8(v, name, &value, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ pm->s4_val = value; ++out: ++ error_propagate(errp, local_err); ++} ++ ++void ls7a_pm_add_properties(Object *obj, LS7APCIPMRegs *pm, Error **errp) ++{ ++ static const uint32_t gpe0_len = ACPI_GPE0_LEN; ++ pm->acpi_memory_hotplug.is_enabled = true; ++ pm->disable_s3 = 0; ++ pm->disable_s4 = 0; ++ pm->s4_val = 2; ++ ++ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE, ++ &pm->pm_io_base, OBJ_PROP_FLAG_READ); ++ object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32", ++ ls7a_pm_get_gpe0_blk, ++ NULL, NULL, pm); ++ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN, ++ &gpe0_len, OBJ_PROP_FLAG_READ); ++ object_property_add_bool(obj, "memory-hotplug-support", ++ ls7a_pm_get_memory_hotplug_support, ++ ls7a_pm_set_memory_hotplug_support); ++ object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8", ++ ls7a_pm_get_disable_s3, ++ ls7a_pm_set_disable_s3, ++ NULL, pm); ++ object_property_add(obj, ACPI_PM_PROP_S4_DISABLED, "uint8", ++ ls7a_pm_get_disable_s4, ++ ls7a_pm_set_disable_s4, ++ NULL, pm); ++ object_property_add(obj, ACPI_PM_PROP_S4_VAL, "uint8", ++ ls7a_pm_get_s4_val, ++ ls7a_pm_set_s4_val, ++ NULL, pm); ++} ++ ++void ls7a_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); ++ ++ if (ls7a->pm.acpi_memory_hotplug.is_enabled && ++ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { ++ nvdimm_acpi_plug_cb(hotplug_dev, dev); ++ } else { ++ acpi_memory_plug_cb(hotplug_dev, &ls7a->pm.acpi_memory_hotplug, ++ dev, errp); ++ } ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_plug_cb(hotplug_dev, &ls7a->pm.cpuhp_state, dev, errp); ++ } else { ++ error_setg(errp, "acpi: device plug request for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++} ++ ++void ls7a_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); ++ ++ if (ls7a->pm.acpi_memory_hotplug.is_enabled && ++ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ acpi_memory_unplug_request_cb(hotplug_dev, ++ &ls7a->pm.acpi_memory_hotplug, dev, ++ errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_unplug_request_cb(hotplug_dev, &ls7a->pm.cpuhp_state, ++ dev, errp); ++ } else { ++ error_setg(errp, "acpi: device unplug request for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++} ++ ++void ls7a_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); ++ ++ if (ls7a->pm.acpi_memory_hotplug.is_enabled && ++ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ acpi_memory_unplug_cb(&ls7a->pm.acpi_memory_hotplug, dev, errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_unplug_cb(&ls7a->pm.cpuhp_state, dev, errp); ++ } else { ++ error_setg(errp, "acpi: device unplug for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++} ++ ++void ls7a_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); ++ ++ acpi_memory_ospm_status(&ls7a->pm.acpi_memory_hotplug, list); ++ acpi_cpu_ospm_status(&ls7a->pm.cpuhp_state, list); ++} ++ ++void ls7a_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); ++ ++ acpi_send_gpe_event(&ls7a->pm.acpi_regs, ls7a->pm.irq, ev); ++} ++ ++ ++ +diff --git a/hw/acpi/ls7a.c b/hw/acpi/ls7a.c +new file mode 100644 +index 000000000..2de50ccb9 +--- /dev/null ++++ b/hw/acpi/ls7a.c +@@ -0,0 +1,598 @@ ++#include "qemu/osdep.h" ++#include "sysemu/sysemu.h" ++#include "hw/hw.h" ++#include "hw/irq.h" ++#include "hw/acpi/acpi.h" ++#include "hw/acpi/ls7a.h" ++#include "hw/nvram/fw_cfg.h" ++#include "qemu/config-file.h" ++#include "qapi/opts-visitor.h" ++#include "qapi/qapi-events-run-state.h" ++#include "qapi/error.h" ++#include "hw/mips/ls7a.h" ++#include "hw/mem/pc-dimm.h" ++#include "hw/mem/nvdimm.h" ++ ++static void ls7a_pm_update_sci_fn(ACPIREGS *regs) ++{ ++ LS7APCIPMRegs *pm = container_of(regs, LS7APCIPMRegs, acpi_regs); ++ acpi_update_sci(&pm->acpi_regs, pm->irq); ++} ++ ++static uint64_t ls7a_gpe_readb(void *opaque, hwaddr addr, unsigned width) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ return acpi_gpe_ioport_readb(&pm->acpi_regs, addr); ++} ++ ++static void ls7a_gpe_writeb(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val); ++ acpi_update_sci(&pm->acpi_regs, pm->irq); ++} ++ ++static const MemoryRegionOps ls7a_gpe_ops = { ++ .read = ls7a_gpe_readb, ++ .write = ls7a_gpe_writeb, ++ .valid.min_access_size = 1, ++ .valid.max_access_size = 8, ++ .impl.min_access_size = 1, ++ .impl.max_access_size = 1, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++#define VMSTATE_GPE_ARRAY(_field, _state) \ ++ { \ ++ .name = (stringify(_field)), \ ++ .version_id = 0, \ ++ .num = ACPI_GPE0_LEN, \ ++ .info = &vmstate_info_uint8, \ ++ .size = sizeof(uint8_t), \ ++ .flags = VMS_ARRAY | VMS_POINTER, \ ++ .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ ++ } ++ ++static uint64_t ls7a_reset_readw(void *opaque, hwaddr addr, unsigned width) ++{ ++ return 0; ++} ++ ++static void ls7a_reset_writew(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ if (val & 1) { ++ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); ++ return; ++ } ++} ++ ++static const MemoryRegionOps ls7a_reset_ops = { ++ .read = ls7a_reset_readw, ++ .write = ls7a_reset_writew, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static bool vmstate_test_use_memhp(void *opaque) ++{ ++ LS7APCIPMRegs *s = opaque; ++ return s->acpi_memory_hotplug.is_enabled; ++} ++ ++static const VMStateDescription vmstate_memhp_state = { ++ .name = "ls7a_pm/memhp", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .minimum_version_id_old = 1, ++ .needed = vmstate_test_use_memhp, ++ .fields = (VMStateField[]) { ++ VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, LS7APCIPMRegs), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static const VMStateDescription vmstate_cpuhp_state = { ++ .name = "ls7a_pm/cpuhp", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .minimum_version_id_old = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_CPU_HOTPLUG(cpuhp_state, LS7APCIPMRegs), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++const VMStateDescription vmstate_ls7a_pm = { ++ .name = "ls7a_pm", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT16(acpi_regs.pm1.evt.sts, LS7APCIPMRegs), ++ VMSTATE_UINT16(acpi_regs.pm1.evt.en, LS7APCIPMRegs), ++ VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, LS7APCIPMRegs), ++ VMSTATE_TIMER_PTR(acpi_regs.tmr.timer, LS7APCIPMRegs), ++ VMSTATE_INT64(acpi_regs.tmr.overflow_time, LS7APCIPMRegs), ++ VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, LS7APCIPMRegs), ++ VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, LS7APCIPMRegs), ++ VMSTATE_END_OF_LIST() ++ }, ++ .subsections = (const VMStateDescription * []) { ++ &vmstate_memhp_state, ++ &vmstate_cpuhp_state, ++ NULL ++ } ++}; ++ ++static inline int64_t acpi_pm_tmr_get_clock(void) ++{ ++ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY, ++ NANOSECONDS_PER_SECOND); ++} ++ ++static uint32_t acpi_pm_tmr_get(ACPIREGS *ar) ++{ ++ uint32_t d = acpi_pm_tmr_get_clock(); ++ return d & 0xffffff; ++} ++ ++static void acpi_pm_tmr_timer(void *opaque) ++{ ++ ACPIREGS *ar = opaque; ++ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_PMTIMER, NULL); ++ ar->tmr.update_sci(ar); ++} ++ ++static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width) ++{ ++ return acpi_pm_tmr_get(opaque); ++} ++ ++static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ /* nothing */ ++} ++ ++static const MemoryRegionOps acpi_pm_tmr_ops = { ++ .read = acpi_pm_tmr_read, ++ .write = acpi_pm_tmr_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void ls7a_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, ++ MemoryRegion *parent, uint64_t offset) ++{ ++ ar->tmr.update_sci = update_sci; ++ ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar); ++ memory_region_init_io(&ar->tmr.io, memory_region_owner(parent), ++ &acpi_pm_tmr_ops, ar, "acpi-tmr", 4); ++ memory_region_add_subregion(parent, offset, &ar->tmr.io); ++} ++ ++static void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val) ++{ ++ uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar); ++ if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) { ++ /* if TMRSTS is reset, then compute the new overflow time */ ++ acpi_pm_tmr_calc_overflow_time(ar); ++ } ++ ar->pm1.evt.sts &= ~val; ++} ++ ++static uint64_t acpi_pm_evt_read(void *opaque, hwaddr addr, unsigned width) ++{ ++ ACPIREGS *ar = opaque; ++ switch (addr) { ++ case 0: ++ return acpi_pm1_evt_get_sts(ar); ++ case 4: ++ return ar->pm1.evt.en; ++ default: ++ return 0; ++ } ++} ++ ++static void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val) ++{ ++ ar->pm1.evt.en = val; ++ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, ++ val & ACPI_BITMASK_RT_CLOCK_ENABLE); ++ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, ++ val & ACPI_BITMASK_TIMER_ENABLE); ++} ++ ++static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ ACPIREGS *ar = opaque; ++ switch (addr) { ++ case 0: ++ acpi_pm1_evt_write_sts(ar, val); ++ ar->pm1.evt.update_sci(ar); ++ break; ++ case 4: ++ acpi_pm1_evt_write_en(ar, val); ++ ar->pm1.evt.update_sci(ar); ++ break; ++ } ++} ++ ++static const MemoryRegionOps acpi_pm_evt_ops = { ++ .read = acpi_pm_evt_read, ++ .write = acpi_pm_evt_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void ls7a_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, ++ MemoryRegion *parent, uint64_t offset) ++{ ++ ar->pm1.evt.update_sci = update_sci; ++ memory_region_init_io(&ar->pm1.evt.io, memory_region_owner(parent), ++ &acpi_pm_evt_ops, ar, "acpi-evt", 8); ++ memory_region_add_subregion(parent, offset, &ar->pm1.evt.io); ++} ++ ++static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width) ++{ ++ ACPIREGS *ar = opaque; ++ return ar->pm1.cnt.cnt; ++} ++ ++/* ACPI PM1aCNT */ ++static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val) ++{ ++ ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE); ++ ++ if (val & ACPI_BITMASK_SLEEP_ENABLE) { ++ /* change suspend type */ ++ uint16_t sus_typ = (val >> 10) & 7; ++ switch (sus_typ) { ++ case 0: /* soft power off */ ++ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); ++ break; ++ case 1: ++ qemu_system_suspend_request(); ++ break; ++ default: ++ if (sus_typ == ar->pm1.cnt.s4_val) { /* S4 request */ ++ qapi_event_send_suspend_disk(); ++ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); ++ } ++ break; ++ } ++ } ++} ++ ++static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val, ++ unsigned width) ++{ ++ acpi_pm1_cnt_write(opaque, val); ++} ++ ++static const MemoryRegionOps acpi_pm_cnt_ops = { ++ .read = acpi_pm_cnt_read, ++ .write = acpi_pm_cnt_write, ++ .valid.min_access_size = 4, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void acpi_notify_wakeup(Notifier *notifier, void *data) ++{ ++ ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup); ++ WakeupReason *reason = data; ++ ++ switch (*reason) { ++ case QEMU_WAKEUP_REASON_RTC: ++ ar->pm1.evt.sts |= ++ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS); ++ break; ++ case QEMU_WAKEUP_REASON_PMTIMER: ++ ar->pm1.evt.sts |= ++ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS); ++ break; ++ case QEMU_WAKEUP_REASON_OTHER: ++ /* ACPI_BITMASK_WAKE_STATUS should be set on resume. ++ * Pretend that resume was caused by power button */ ++ ar->pm1.evt.sts |= ++ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void ls7a_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, ++ bool disable_s3, bool disable_s4, uint8_t s4_val, uint64_t offset) ++{ ++ FWCfgState *fw_cfg; ++ ++ ar->pm1.cnt.s4_val = s4_val; ++ ar->wakeup.notify = acpi_notify_wakeup; ++ qemu_register_wakeup_notifier(&ar->wakeup); ++ memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent), ++ &acpi_pm_cnt_ops, ar, "acpi-cnt", 4); ++ memory_region_add_subregion(parent, offset, &ar->pm1.cnt.io); ++ ++ fw_cfg = fw_cfg_find(); ++ if (fw_cfg) { ++ uint8_t suspend[6] = {128, 0, 0, 129, 128, 128}; ++ suspend[3] = 1 | ((!disable_s3) << 7); ++ suspend[4] = s4_val | ((!disable_s4) << 7); ++ fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6); ++ } ++} ++ ++static void ls7a_pm_reset(void *opaque) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ ++ acpi_pm1_evt_reset(&pm->acpi_regs); ++ acpi_pm1_cnt_reset(&pm->acpi_regs); ++ acpi_pm_tmr_reset(&pm->acpi_regs); ++ acpi_gpe_reset(&pm->acpi_regs); ++ ++ acpi_update_sci(&pm->acpi_regs, pm->irq); ++} ++ ++static void pm_powerdown_req(Notifier *n, void *opaque) ++{ ++ LS7APCIPMRegs *pm = container_of(n, LS7APCIPMRegs, powerdown_notifier); ++ ++ acpi_pm1_evt_power_down(&pm->acpi_regs); ++} ++ ++void ls7a_pm_init(LS7APCIPMRegs *pm, qemu_irq *pic) ++{ ++ unsigned long base, gpe_len, acpi_aci_irq; ++ ++ /* ls7a board acpi hardware info, including ++ * acpi system io base address ++ * acpi gpe length ++ * acpi sci irq number ++ */ ++ base = ACPI_IO_BASE; ++ gpe_len = ACPI_GPE0_LEN; ++ acpi_aci_irq = ACPI_SCI_IRQ; ++ ++ pm->irq = pic[acpi_aci_irq - 64]; ++ memory_region_init(&pm->iomem, NULL, "ls7a_pm", ACPI_IO_SIZE); ++ memory_region_add_subregion(get_system_memory(), base, &pm->iomem); ++ ++ cpu_hotplug_hw_init(get_system_memory(), NULL, &pm->cpuhp_state, CPU_HOTPLUG_BASE); ++ ++ ls7a_pm_tmr_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, LS7A_PM_TMR_BLK); ++ ls7a_pm1_evt_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, LS7A_PM_EVT_BLK); ++ ls7a_pm1_cnt_init(&pm->acpi_regs, &pm->iomem, false, false, 2, LS7A_PM_CNT_BLK); ++ ++ acpi_gpe_init(&pm->acpi_regs, gpe_len); ++ memory_region_init_io(&pm->iomem_gpe, NULL, &ls7a_gpe_ops, pm, ++ "acpi-gpe0", gpe_len); ++ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_STS_REG, &pm->iomem_gpe); ++ ++ memory_region_init_io(&pm->iomem_reset, NULL, &ls7a_reset_ops, pm, ++ "acpi-reset", 4); ++ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_RESET_REG, &pm->iomem_reset); ++ ++ qemu_register_reset(ls7a_pm_reset, pm); ++ ++ pm->powerdown_notifier.notify = pm_powerdown_req; ++ qemu_register_powerdown_notifier(&pm->powerdown_notifier); ++ ++ if (pm->acpi_memory_hotplug.is_enabled) { ++ acpi_memory_hotplug_init(get_system_memory(), NULL, ++ &pm->acpi_memory_hotplug, MEMORY_HOTPLUG_BASE); ++ } ++} ++ ++ ++static void ls7a_pm_get_gpe0_blk(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ uint64_t value = ACPI_IO_BASE + LS7A_GPE0_STS_REG; ++ ++ visit_type_uint64(v, name, &value, errp); ++} ++ ++static bool ls7a_pm_get_memory_hotplug_support(Object *obj, Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(obj); ++ ++ return ls7a->pm.acpi_memory_hotplug.is_enabled; ++} ++ ++static void ls7a_pm_set_memory_hotplug_support(Object *obj, bool value, ++ Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(obj); ++ ++ ls7a->pm.acpi_memory_hotplug.is_enabled = value; ++} ++ ++static void ls7a_pm_get_disable_s3(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ uint8_t value = pm->disable_s3; ++ ++ visit_type_uint8(v, name, &value, errp); ++} ++ ++static void ls7a_pm_set_disable_s3(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ Error *local_err = NULL; ++ uint8_t value; ++ ++ visit_type_uint8(v, name, &value, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ pm->disable_s3 = value; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void ls7a_pm_get_disable_s4(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ uint8_t value = pm->disable_s4; ++ ++ visit_type_uint8(v, name, &value, errp); ++} ++ ++static void ls7a_pm_set_disable_s4(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ Error *local_err = NULL; ++ uint8_t value; ++ ++ visit_type_uint8(v, name, &value, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ pm->disable_s4 = value; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void ls7a_pm_get_s4_val(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ uint8_t value = pm->s4_val; ++ ++ visit_type_uint8(v, name, &value, errp); ++} ++ ++static void ls7a_pm_set_s4_val(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LS7APCIPMRegs *pm = opaque; ++ Error *local_err = NULL; ++ uint8_t value; ++ ++ visit_type_uint8(v, name, &value, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ pm->s4_val = value; ++out: ++ error_propagate(errp, local_err); ++} ++ ++void ls7a_pm_add_properties(Object *obj, LS7APCIPMRegs *pm, Error **errp) ++{ ++ static const uint32_t gpe0_len = ACPI_GPE0_LEN; ++ pm->acpi_memory_hotplug.is_enabled = true; ++ pm->disable_s3 = 0; ++ pm->disable_s4 = 0; ++ pm->s4_val = 2; ++ ++ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE, ++ &pm->pm_io_base, OBJ_PROP_FLAG_READ); ++ object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32", ++ ls7a_pm_get_gpe0_blk, ++ NULL, NULL, pm); ++ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN, ++ &gpe0_len, OBJ_PROP_FLAG_READ); ++ object_property_add_bool(obj, "memory-hotplug-support", ++ ls7a_pm_get_memory_hotplug_support, ++ ls7a_pm_set_memory_hotplug_support); ++ object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8", ++ ls7a_pm_get_disable_s3, ++ ls7a_pm_set_disable_s3, ++ NULL, pm); ++ object_property_add(obj, ACPI_PM_PROP_S4_DISABLED, "uint8", ++ ls7a_pm_get_disable_s4, ++ ls7a_pm_set_disable_s4, ++ NULL, pm); ++ object_property_add(obj, ACPI_PM_PROP_S4_VAL, "uint8", ++ ls7a_pm_get_s4_val, ++ ls7a_pm_set_s4_val, ++ NULL, pm); ++} ++ ++void ls7a_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); ++ ++ if (ls7a->pm.acpi_memory_hotplug.is_enabled && ++ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { ++ nvdimm_acpi_plug_cb(hotplug_dev, dev); ++ } else { ++ acpi_memory_plug_cb(hotplug_dev, &ls7a->pm.acpi_memory_hotplug, ++ dev, errp); ++ } ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_plug_cb(hotplug_dev, &ls7a->pm.cpuhp_state, dev, errp); ++ } else { ++ error_setg(errp, "acpi: device plug request for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++} ++ ++void ls7a_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); ++ ++ if (ls7a->pm.acpi_memory_hotplug.is_enabled && ++ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ acpi_memory_unplug_request_cb(hotplug_dev, ++ &ls7a->pm.acpi_memory_hotplug, dev, ++ errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_unplug_request_cb(hotplug_dev, &ls7a->pm.cpuhp_state, ++ dev, errp); ++ } else { ++ error_setg(errp, "acpi: device unplug request for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++} ++ ++void ls7a_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); ++ ++ if (ls7a->pm.acpi_memory_hotplug.is_enabled && ++ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ acpi_memory_unplug_cb(&ls7a->pm.acpi_memory_hotplug, dev, errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_unplug_cb(&ls7a->pm.cpuhp_state, dev, errp); ++ } else { ++ error_setg(errp, "acpi: device unplug for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++} ++ ++void ls7a_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); ++ ++ acpi_memory_ospm_status(&ls7a->pm.acpi_memory_hotplug, list); ++ acpi_cpu_ospm_status(&ls7a->pm.cpuhp_state, list); ++} ++ ++void ls7a_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); ++ ++ acpi_send_gpe_event(&ls7a->pm.acpi_regs, ls7a->pm.irq, ev); ++} ++ ++ ++ +diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build +index 448ea6afb..4718d143f 100644 +--- a/hw/acpi/meson.build ++++ b/hw/acpi/meson.build +@@ -6,6 +6,7 @@ acpi_ss.add(files( + 'core.c', + 'utils.c', + )) ++acpi_ss.add(when: 'CONFIG_ACPI_LOONGARCH', if_true: files('larch_7a.c')) + acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_true: files('cpu.c', 'cpu_hotplug.c')) + acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_false: files('acpi-cpu-hotplug-stub.c')) + acpi_ss.add(when: 'CONFIG_ACPI_MEMORY_HOTPLUG', if_true: files('memory_hotplug.c')) +diff --git a/include/hw/acpi/ls7a.h b/include/hw/acpi/ls7a.h +new file mode 100644 +index 000000000..4401515c7 +--- /dev/null ++++ b/include/hw/acpi/ls7a.h +@@ -0,0 +1,80 @@ ++/* ++ * QEMU GMCH/LS7A PCI PM Emulation ++ * ++ * Copyright (c) 2009 Isaku Yamahata ++ * VA Linux Systems Japan K.K. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see ++ */ ++ ++#ifndef HW_ACPI_LS7A_H ++#define HW_ACPI_LS7A_H ++ ++#include "hw/acpi/acpi.h" ++#include "hw/acpi/cpu_hotplug.h" ++#include "hw/acpi/cpu.h" ++#include "hw/acpi/memory_hotplug.h" ++#include "hw/acpi/acpi_dev_interface.h" ++#include "hw/acpi/tco.h" ++ ++#define CPU_HOTPLUG_BASE 0x1e000000 ++#define MEMORY_HOTPLUG_BASE 0x1e00000c ++ ++typedef struct LS7APCIPMRegs { ++ /* ++ * In ls7a spec says that pm1_cnt register is 32bit width and ++ * that the upper 16bits are reserved and unused. ++ * PM1a_CNT_BLK = 2 in FADT so it is defined as uint16_t. ++ */ ++ ACPIREGS acpi_regs; ++ ++ MemoryRegion iomem; ++ MemoryRegion iomem_gpe; ++ MemoryRegion iomem_smi; ++ MemoryRegion iomem_reset; ++ ++ qemu_irq irq; /* SCI */ ++ ++ uint32_t pm_io_base; ++ Notifier powerdown_notifier; ++ ++ bool cpu_hotplug_legacy; ++ AcpiCpuHotplug gpe_cpu; ++ CPUHotplugState cpuhp_state; ++ ++ MemHotplugState acpi_memory_hotplug; ++ ++ uint8_t disable_s3; ++ uint8_t disable_s4; ++ uint8_t s4_val; ++} LS7APCIPMRegs; ++ ++void ls7a_pm_init(LS7APCIPMRegs *ls7a, qemu_irq *sci_irq); ++ ++void ls7a_pm_iospace_update(LS7APCIPMRegs *pm, uint32_t pm_io_base); ++extern const VMStateDescription vmstate_ls7a_pm; ++ ++void ls7a_pm_add_properties(Object *obj, LS7APCIPMRegs *pm, Error **errp); ++ ++void ls7a_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp); ++void ls7a_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp); ++void ls7a_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp); ++ ++void ls7a_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); ++ ++void ls7a_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev); ++#endif /* HW_ACPI_LS7A_H */ +-- +2.27.0 + diff --git a/Add-disas-gdb.patch b/Add-disas-gdb.patch new file mode 100644 index 00000000..34ea6ed4 --- /dev/null +++ b/Add-disas-gdb.patch @@ -0,0 +1,3191 @@ +From 833511534eb53f7ca0cc9b9a7de5141a82edcc59 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Wed, 7 Dec 2022 04:37:36 -0500 +Subject: [PATCH 06/11] Add disas gdb. + +Signed-off-by: lixianglai +--- + .../devices/loongarch64-softmmu/default.mak | 163 + + configs/targets/loongarch64-softmmu.mak | 4 + + disas/loongarch.c | 2748 +++++++++++++++++ + disas/meson.build | 1 + + gdb-xml/loongarch-base32.xml | 43 + + gdb-xml/loongarch-base64.xml | 43 + + gdb-xml/loongarch-fpu32.xml | 52 + + gdb-xml/loongarch-fpu64.xml | 57 + + 8 files changed, 3111 insertions(+) + create mode 100644 configs/devices/loongarch64-softmmu/default.mak + create mode 100644 configs/targets/loongarch64-softmmu.mak + create mode 100644 disas/loongarch.c + create mode 100644 gdb-xml/loongarch-base32.xml + create mode 100644 gdb-xml/loongarch-base64.xml + create mode 100644 gdb-xml/loongarch-fpu32.xml + create mode 100644 gdb-xml/loongarch-fpu64.xml + +diff --git a/configs/devices/loongarch64-softmmu/default.mak b/configs/devices/loongarch64-softmmu/default.mak +new file mode 100644 +index 000000000..b4994d8a6 +--- /dev/null ++++ b/configs/devices/loongarch64-softmmu/default.mak +@@ -0,0 +1,163 @@ ++# Default configuration for loongarch-softmmu ++ ++CONFIG_PCI=y ++CONFIG_ACPI_PCI=y ++# For now, CONFIG_IDE_CORE requires ISA, so we enable it here ++CONFIG_ISA_BUS=y ++CONFIG_VIRTIO_PCI=y ++ ++CONFIG_VGA_PCI=y ++CONFIG_ACPI_SMBUS=y ++#CONFIG_VHOST_USER_SCSI=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) ++CONFIG_VHOST_USER_SCSI=y ++#CONFIG_VHOST_USER_BLK=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) ++CONFIG_VHOST_USER_BLK=y ++CONFIG_VIRTIO=y ++CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_BLK=y ++CONFIG_VIRTIO_CRYPTO=y ++CONFIG_VIRTIO_GPU=y ++CONFIG_VIRTIO_INPUT=y ++CONFIG_VIRTIO_NET=y ++CONFIG_VIRTIO_RNG=y ++CONFIG_SCSI=y ++CONFIG_VIRTIO_SCSI=y ++CONFIG_VIRTIO_SERIAL=y ++ ++CONFIG_USB_UHCI=y ++CONFIG_USB_OHCI=y ++CONFIG_USB_OHCI_PCI=y ++CONFIG_USB_XHCI=y ++CONFIG_USB_XHCI_NEC=y ++CONFIG_NE2000_PCI=y ++CONFIG_EEPRO100_PCI=y ++CONFIG_PCNET_PCI=y ++CONFIG_PCNET_COMMON=y ++CONFIG_AC97=y ++CONFIG_HDA=y ++CONFIG_ES1370=y ++CONFIG_SCSI=y ++CONFIG_LSI_SCSI_PCI=y ++CONFIG_VMW_PVSCSI_SCSI_PCI=y ++CONFIG_MEGASAS_SCSI_PCI=y ++CONFIG_MPTSAS_SCSI_PCI=y ++CONFIG_RTL8139_PCI=y ++CONFIG_E1000_PCI=y ++CONFIG_IDE_CORE=y ++CONFIG_IDE_QDEV=y ++CONFIG_IDE_PCI=y ++CONFIG_AHCI=y ++CONFIG_AHCI_ICH9=y ++CONFIG_ESP=y ++CONFIG_ESP_PCI=y ++CONFIG_SERIAL=y ++CONFIG_SERIAL_ISA=y ++CONFIG_SERIAL_PCI=y ++CONFIG_CAN_BUS=y ++CONFIG_CAN_SJA1000=y ++CONFIG_CAN_PCI=y ++CONFIG_USB_UHCI=y ++CONFIG_USB_OHCI=y ++CONFIG_USB_XHCI=y ++CONFIG_USB_XHCI_NEC=y ++CONFIG_NE2000_PCI=y ++CONFIG_EEPRO100_PCI=y ++CONFIG_PCNET_PCI=y ++CONFIG_PCNET_COMMON=y ++CONFIG_AC97=y ++CONFIG_HDA=y ++CONFIG_ES1370=y ++CONFIG_SCSI=y ++CONFIG_LSI_SCSI_PCI=y ++CONFIG_VMW_PVSCSI_SCSI_PCI=y ++CONFIG_MEGASAS_SCSI_PCI=y ++CONFIG_MPTSAS_SCSI_PCI=y ++CONFIG_RTL8139_PCI=y ++CONFIG_E1000_PCI=y ++CONFIG_IDE_CORE=y ++CONFIG_IDE_QDEV=y ++CONFIG_IDE_PCI=y ++CONFIG_AHCI=y ++CONFIG_ESP=y ++CONFIG_ESP_PCI=y ++CONFIG_SERIAL=y ++CONFIG_SERIAL_ISA=y ++CONFIG_SERIAL_PCI=y ++CONFIG_CAN_BUS=y ++CONFIG_CAN_SJA1000=y ++CONFIG_CAN_PCI=y ++ ++CONFIG_SPICE=y ++CONFIG_QXL=y ++CONFIG_ESP=y ++CONFIG_SCSI=y ++CONFIG_VGA_ISA=y ++CONFIG_VGA_ISA_MM=y ++CONFIG_VGA_CIRRUS=y ++CONFIG_VMWARE_VGA=y ++CONFIG_VIRTIO_VGA=y ++CONFIG_SERIAL=y ++CONFIG_SERIAL_ISA=y ++CONFIG_PARALLEL=y ++CONFIG_I8254=y ++CONFIG_PCSPK=y ++CONFIG_PCKBD=y ++CONFIG_FDC=y ++CONFIG_ACPI=y ++CONFIG_ACPI_MEMORY_HOTPLUG=y ++CONFIG_ACPI_NVDIMM=y ++CONFIG_ACPI_CPU_HOTPLUG=y ++CONFIG_APM=y ++CONFIG_I8257=y ++CONFIG_PIIX4=y ++CONFIG_IDE_ISA=y ++CONFIG_IDE_PIIX=y ++#CONFIG_NE2000_ISA=y ++CONFIG_MIPSNET=y ++CONFIG_PFLASH_CFI01=y ++CONFIG_I8259=y ++CONFIG_MC146818RTC=y ++CONFIG_ISA_TESTDEV=y ++CONFIG_EMPTY_SLOT=y ++CONFIG_I2C=y ++CONFIG_DIMM=y ++CONFIG_MEM_DEVICE=y ++ ++# Arch Specified CONFIG defines ++CONFIG_IDE_VIA=y ++CONFIG_VT82C686=y ++CONFIG_RC4030=y ++CONFIG_DP8393X=y ++CONFIG_DS1225Y=y ++CONFIG_FITLOADER=y ++CONFIG_SMBIOS=y ++ ++CONFIG_PCIE_PORT=y ++CONFIG_I82801B11=y ++CONFIG_XIO3130=y ++CONFIG_PCI_EXPRESS=y ++CONFIG_MSI_NONBROKEN=y ++CONFIG_IOH3420=y ++CONFIG_SD=y ++CONFIG_SDHCI=y ++CONFIG_VIRTFS=y ++CONFIG_VIRTIO_9P=y ++CONFIG_USB_EHCI=y ++CONFIG_USB_EHCI_PCI=y ++CONFIG_USB_EHCI_SYSBUS=y ++CONFIG_USB_STORAGE_BOT=y ++CONFIG_TPM_EMULATOR=y ++CONFIG_TPM_TIS=y ++CONFIG_PLATFORM_BUS=y ++CONFIG_TPM_TIS_SYSBUS=y ++CONFIG_ACPI_LOONGARCH=y ++CONFIG_LS7A_RTC=y ++ ++#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 000000000..dc5ab3966 +--- /dev/null ++++ b/configs/targets/loongarch64-softmmu.mak +@@ -0,0 +1,4 @@ ++TARGET_ARCH=loongarch64 ++TARGET_SUPPORTS_MTTCG=y ++TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu64.xml ++ +diff --git a/disas/loongarch.c b/disas/loongarch.c +new file mode 100644 +index 000000000..14dd131e2 +--- /dev/null ++++ b/disas/loongarch.c +@@ -0,0 +1,2748 @@ ++/* ++ * QEMU Loongarch Disassembler ++ * ++ * Copyright (c) 2020-2021. ++ * Author: Song Gao, gaosong@loongson.cn ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2 or later, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program. If not, see . ++ */ ++ ++#include "qemu/osdep.h" ++#include "disas/dis-asm.h" ++ ++#define INSNLEN 4 ++ ++/* types */ ++ ++typedef uint16_t la_opcode; ++ ++/* enums */ ++ ++typedef enum { ++ la_op_illegal = 0, ++ la_op_gr2scr = 1, ++ la_op_scr2gr = 2, ++ la_op_clo_w = 3, ++ la_op_clz_w = 4, ++ la_op_cto_w = 5, ++ la_op_ctz_w = 6, ++ la_op_clo_d = 7, ++ la_op_clz_d = 8, ++ la_op_cto_d = 9, ++ la_op_ctz_d = 10, ++ la_op_revb_2h = 11, ++ la_op_revb_4h = 12, ++ la_op_revb_2w = 13, ++ la_op_revb_d = 14, ++ la_op_revh_2w = 15, ++ la_op_revh_d = 16, ++ la_op_bitrev_4b = 17, ++ la_op_bitrev_8b = 18, ++ la_op_bitrev_w = 19, ++ la_op_bitrev_d = 20, ++ la_op_ext_w_h = 21, ++ la_op_ext_w_b = 22, ++ la_op_rdtime_d = 23, ++ la_op_cpucfg = 24, ++ la_op_asrtle_d = 25, ++ la_op_asrtgt_d = 26, ++ la_op_alsl_w = 27, ++ la_op_alsl_wu = 28, ++ la_op_bytepick_w = 29, ++ la_op_bytepick_d = 30, ++ la_op_add_w = 31, ++ la_op_add_d = 32, ++ la_op_sub_w = 33, ++ la_op_sub_d = 34, ++ la_op_slt = 35, ++ la_op_sltu = 36, ++ la_op_maskeqz = 37, ++ la_op_masknez = 38, ++ la_op_nor = 39, ++ la_op_and = 40, ++ la_op_or = 41, ++ la_op_xor = 42, ++ la_op_orn = 43, ++ la_op_andn = 44, ++ la_op_sll_w = 45, ++ la_op_srl_w = 46, ++ la_op_sra_w = 47, ++ la_op_sll_d = 48, ++ la_op_srl_d = 49, ++ la_op_sra_d = 50, ++ la_op_rotr_w = 51, ++ la_op_rotr_d = 52, ++ la_op_mul_w = 53, ++ la_op_mulh_w = 54, ++ la_op_mulh_wu = 55, ++ la_op_mul_d = 56, ++ la_op_mulh_d = 57, ++ la_op_mulh_du = 58, ++ la_op_mulw_d_w = 59, ++ la_op_mulw_d_wu = 60, ++ la_op_div_w = 61, ++ la_op_mod_w = 62, ++ la_op_div_wu = 63, ++ la_op_mod_wu = 64, ++ la_op_div_d = 65, ++ la_op_mod_d = 66, ++ la_op_div_du = 67, ++ la_op_mod_du = 68, ++ la_op_crc_w_b_w = 69, ++ la_op_crc_w_h_w = 70, ++ la_op_crc_w_w_w = 71, ++ la_op_crc_w_d_w = 72, ++ la_op_crcc_w_b_w = 73, ++ la_op_crcc_w_h_w = 74, ++ la_op_crcc_w_w_w = 75, ++ la_op_crcc_w_d_w = 76, ++ la_op_break = 77, ++ la_op_dbcl = 78, ++ la_op_syscall = 79, ++ la_op_alsl_d = 80, ++ la_op_slli_w = 81, ++ la_op_slli_d = 82, ++ la_op_srli_w = 83, ++ la_op_srli_d = 84, ++ la_op_srai_w = 85, ++ la_op_srai_d = 86, ++ la_op_rotri_w = 87, ++ la_op_rotri_d = 88, ++ la_op_bstrins_w = 89, ++ la_op_bstrpick_w = 90, ++ la_op_bstrins_d = 91, ++ la_op_bstrpick_d = 92, ++ la_op_fadd_s = 93, ++ la_op_fadd_d = 94, ++ la_op_fsub_s = 95, ++ la_op_fsub_d = 96, ++ la_op_fmul_s = 97, ++ la_op_fmul_d = 98, ++ la_op_fdiv_s = 99, ++ la_op_fdiv_d = 100, ++ la_op_fmax_s = 101, ++ la_op_fmax_d = 102, ++ la_op_fmin_s = 103, ++ la_op_fmin_d = 104, ++ la_op_fmaxa_s = 105, ++ la_op_fmaxa_d = 106, ++ la_op_fmina_s = 107, ++ la_op_fmina_d = 108, ++ la_op_fscaleb_s = 109, ++ la_op_fscaleb_d = 110, ++ la_op_fcopysign_s = 111, ++ la_op_fcopysign_d = 112, ++ la_op_fabs_s = 113, ++ la_op_fabs_d = 114, ++ la_op_fneg_s = 115, ++ la_op_fneg_d = 116, ++ la_op_flogb_s = 117, ++ la_op_flogb_d = 118, ++ la_op_fclass_s = 119, ++ la_op_fclass_d = 120, ++ la_op_fsqrt_s = 121, ++ la_op_fsqrt_d = 122, ++ la_op_frecip_s = 123, ++ la_op_frecip_d = 124, ++ la_op_frsqrt_s = 125, ++ la_op_frsqrt_d = 126, ++ la_op_fmov_s = 127, ++ la_op_fmov_d = 128, ++ la_op_movgr2fr_w = 129, ++ la_op_movgr2fr_d = 130, ++ la_op_movgr2frh_w = 131, ++ la_op_movfr2gr_s = 132, ++ la_op_movfr2gr_d = 133, ++ la_op_movfrh2gr_s = 134, ++ la_op_movgr2fcsr = 135, ++ la_op_movfcsr2gr = 136, ++ la_op_movfr2cf = 137, ++ la_op_movcf2fr = 138, ++ la_op_movgr2cf = 139, ++ la_op_movcf2gr = 140, ++ la_op_fcvt_s_d = 141, ++ la_op_fcvt_d_s = 142, ++ ++ la_op_ftintrm_w_s = 143, ++ la_op_ftintrm_w_d = 144, ++ la_op_ftintrm_l_s = 145, ++ la_op_ftintrm_l_d = 146, ++ la_op_ftintrp_w_s = 147, ++ la_op_ftintrp_w_d = 148, ++ la_op_ftintrp_l_s = 149, ++ la_op_ftintrp_l_d = 150, ++ la_op_ftintrz_w_s = 151, ++ la_op_ftintrz_w_d = 152, ++ la_op_ftintrz_l_s = 153, ++ la_op_ftintrz_l_d = 154, ++ la_op_ftintrne_w_s = 155, ++ la_op_ftintrne_w_d = 156, ++ la_op_ftintrne_l_s = 157, ++ la_op_ftintrne_l_d = 158, ++ la_op_ftint_w_s = 159, ++ la_op_ftint_w_d = 160, ++ la_op_ftint_l_s = 161, ++ la_op_ftint_l_d = 162, ++ la_op_ffint_s_w = 163, ++ la_op_ffint_s_l = 164, ++ la_op_ffint_d_w = 165, ++ la_op_ffint_d_l = 166, ++ la_op_frint_s = 167, ++ la_op_frint_d = 168, ++ ++ la_op_slti = 169, ++ la_op_sltui = 170, ++ la_op_addi_w = 171, ++ la_op_addi_d = 172, ++ la_op_lu52i_d = 173, ++ la_op_addi = 174, ++ la_op_ori = 175, ++ la_op_xori = 176, ++ ++ la_op_csrxchg = 177, ++ la_op_cacop = 178, ++ la_op_lddir = 179, ++ la_op_ldpte = 180, ++ la_op_iocsrrd_b = 181, ++ la_op_iocsrrd_h = 182, ++ la_op_iocsrrd_w = 183, ++ la_op_iocsrrd_d = 184, ++ la_op_iocsrwr_b = 185, ++ la_op_iocsrwr_h = 186, ++ la_op_iocsrwr_w = 187, ++ la_op_iocsrwr_d = 188, ++ la_op_tlbclr = 189, ++ la_op_tlbflush = 190, ++ la_op_tlbsrch = 191, ++ la_op_tlbrd = 192, ++ la_op_tlbwr = 193, ++ la_op_tlbfill = 194, ++ la_op_ertn = 195, ++ la_op_idle = 196, ++ la_op_invtlb = 197, ++ ++ la_op_fmadd_s = 198, ++ la_op_fmadd_d = 199, ++ la_op_fmsub_s = 200, ++ la_op_fmsub_d = 201, ++ la_op_fnmadd_s = 202, ++ la_op_fnmadd_d = 203, ++ la_op_fnmsub_s = 204, ++ la_op_fnmsub_d = 205, ++ la_op_fcmp_cond_s = 206, ++ la_op_fcmp_cond_d = 207, ++ la_op_fsel = 208, ++ la_op_addu16i_d = 209, ++ la_op_lu12i_w = 210, ++ la_op_lu32i_d = 211, ++ la_op_pcaddi = 212, ++ la_op_pcalau12i = 213, ++ la_op_pcaddu12i = 214, ++ la_op_pcaddu18i = 215, ++ ++ la_op_ll_w = 216, ++ la_op_sc_w = 217, ++ la_op_ll_d = 218, ++ la_op_sc_d = 219, ++ la_op_ldptr_w = 220, ++ la_op_stptr_w = 221, ++ la_op_ldptr_d = 222, ++ la_op_stptr_d = 223, ++ la_op_ld_b = 224, ++ la_op_ld_h = 225, ++ la_op_ld_w = 226, ++ la_op_ld_d = 227, ++ la_op_st_b = 228, ++ la_op_st_h = 229, ++ la_op_st_w = 230, ++ la_op_st_d = 231, ++ la_op_ld_bu = 232, ++ la_op_ld_hu = 233, ++ la_op_ld_wu = 234, ++ la_op_preld = 235, ++ la_op_fld_s = 236, ++ la_op_fst_s = 237, ++ la_op_fld_d = 238, ++ la_op_fst_d = 239, ++ la_op_ldl_w = 240, ++ la_op_ldr_w = 241, ++ la_op_ldl_d = 242, ++ la_op_ldr_d = 243, ++ la_op_stl_d = 244, ++ la_op_str_d = 245, ++ la_op_ldx_b = 246, ++ la_op_ldx_h = 247, ++ la_op_ldx_w = 248, ++ la_op_ldx_d = 249, ++ la_op_stx_b = 250, ++ la_op_stx_h = 251, ++ la_op_stx_w = 252, ++ la_op_stx_d = 253, ++ la_op_ldx_bu = 254, ++ la_op_ldx_hu = 255, ++ la_op_ldx_wu = 256, ++ la_op_fldx_s = 257, ++ la_op_fldx_d = 258, ++ la_op_fstx_s = 259, ++ la_op_fstx_d = 260, ++ ++ la_op_amswap_w = 261, ++ la_op_amswap_d = 262, ++ la_op_amadd_w = 263, ++ la_op_amadd_d = 264, ++ la_op_amand_w = 265, ++ la_op_amand_d = 266, ++ la_op_amor_w = 267, ++ la_op_amor_d = 268, ++ la_op_amxor_w = 269, ++ la_op_amxor_d = 270, ++ la_op_ammax_w = 271, ++ la_op_ammax_d = 272, ++ la_op_ammin_w = 273, ++ la_op_ammin_d = 274, ++ la_op_ammax_wu = 275, ++ la_op_ammax_du = 276, ++ la_op_ammin_wu = 277, ++ la_op_ammin_du = 278, ++ la_op_amswap_db_w = 279, ++ la_op_amswap_db_d = 280, ++ la_op_amadd_db_w = 281, ++ la_op_amadd_db_d = 282, ++ la_op_amand_db_w = 283, ++ la_op_amand_db_d = 284, ++ la_op_amor_db_w = 285, ++ la_op_amor_db_d = 286, ++ la_op_amxor_db_w = 287, ++ la_op_amxor_db_d = 288, ++ la_op_ammax_db_w = 289, ++ la_op_ammax_db_d = 290, ++ la_op_ammin_db_w = 291, ++ la_op_ammin_db_d = 292, ++ la_op_ammax_db_wu = 293, ++ la_op_ammax_db_du = 294, ++ la_op_ammin_db_wu = 295, ++ la_op_ammin_db_du = 296, ++ la_op_dbar = 297, ++ la_op_ibar = 298, ++ la_op_fldgt_s = 299, ++ la_op_fldgt_d = 300, ++ la_op_fldle_s = 301, ++ la_op_fldle_d = 302, ++ la_op_fstgt_s = 303, ++ la_op_fstgt_d = 304, ++ ls_op_fstle_s = 305, ++ la_op_fstle_d = 306, ++ la_op_ldgt_b = 307, ++ la_op_ldgt_h = 308, ++ la_op_ldgt_w = 309, ++ la_op_ldgt_d = 310, ++ la_op_ldle_b = 311, ++ la_op_ldle_h = 312, ++ la_op_ldle_w = 313, ++ la_op_ldle_d = 314, ++ la_op_stgt_b = 315, ++ la_op_stgt_h = 316, ++ la_op_stgt_w = 317, ++ la_op_stgt_d = 318, ++ la_op_stle_b = 319, ++ la_op_stle_h = 320, ++ la_op_stle_w = 321, ++ la_op_stle_d = 322, ++ la_op_beqz = 323, ++ la_op_bnez = 324, ++ la_op_bceqz = 325, ++ la_op_bcnez = 326, ++ la_op_jirl = 327, ++ la_op_b = 328, ++ la_op_bl = 329, ++ la_op_beq = 330, ++ la_op_bne = 331, ++ la_op_blt = 332, ++ la_op_bge = 333, ++ la_op_bltu = 334, ++ la_op_bgeu = 335, ++ ++ /* vz insn */ ++ la_op_hvcl = 336, ++ ++} la_op; ++ ++typedef enum { ++ la_codec_illegal, ++ la_codec_empty, ++ la_codec_2r, ++ la_codec_2r_u5, ++ la_codec_2r_u6, ++ la_codec_2r_2bw, ++ la_codec_2r_2bd, ++ la_codec_3r, ++ la_codec_3r_rd0, ++ la_codec_3r_sa2, ++ la_codec_3r_sa3, ++ la_codec_4r, ++ la_codec_r_im20, ++ la_codec_2r_im16, ++ la_codec_2r_im14, ++ la_codec_2r_im12, ++ la_codec_im5_r_im12, ++ la_codec_2r_im8, ++ la_codec_r_sd, ++ la_codec_r_sj, ++ la_codec_r_cd, ++ la_codec_r_cj, ++ la_codec_r_seq, ++ la_codec_code, ++ la_codec_whint, ++ la_codec_invtlb, ++ la_codec_r_ofs21, ++ la_codec_cj_ofs21, ++ la_codec_ofs26, ++ la_codec_cond, ++ la_codec_sel, ++ ++} la_codec; ++ ++#define la_fmt_illegal "nte" ++#define la_fmt_empty "nt" ++#define la_fmt_sd_rj "ntA,1" ++#define la_fmt_rd_sj "nt0,B" ++#define la_fmt_rd_rj "nt0,1" ++#define la_fmt_rj_rk "nt1,2" ++#define la_fmt_rj_seq "nt1,x" ++#define la_fmt_rd_si20 "nt0,i(x)" ++#define la_fmt_rd_rj_ui5 "nt0,1,C" ++#define la_fmt_rd_rj_ui6 "nt0,1.C" ++#define la_fmt_rd_rj_level "nt0,1,x" ++#define la_fmt_rd_rj_msbw_lsbw "nt0,1,C,D" ++#define la_fmt_rd_rj_msbd_lsbd "nt0,1,C,D" ++#define la_fmt_rd_rj_si12 "nt0,1,i(x)" ++#define la_fmt_hint_rj_si12 "ntE,1,i(x)" ++#define la_fmt_rd_rj_csr "nt0,1,x" ++#define la_fmt_rd_rj_si14 "nt0,1,i(x)" ++#define la_fmt_rd_rj_si16 "nt0,1,i(x)" ++#define la_fmt_rd_rj_rk "nt0,1,2" ++#define la_fmt_fd_rj_rk "nt3,1,2" ++#define la_fmt_rd_rj_rk_sa2 "nt0,1,2,D" ++#define la_fmt_rd_rj_rk_sa3 "nt0,1,2,D" ++#define la_fmt_fd_rj "nt3,1" ++#define la_fmt_rd_fj "nt0,4" ++#define la_fmt_fd_fj "nt3,4" ++#define la_fmt_fd_fj_si12 "nt3,4,i(x)" ++#define la_fmt_fcsrd_rj "ntF,1" ++#define la_fmt_rd_fcsrs "nt0,G" ++#define la_fmt_cd_fj "ntH,4" ++#define la_fmt_fd_cj "nt3,I" ++#define la_fmt_fd_fj_fk "nt3,4,5" ++#define la_fmt_code "ntJ" ++#define la_fmt_whint "ntx" ++#define la_fmt_invtlb "ntx,1,2" /* op,rj,rk */ ++#define la_fmt_offs26 "nto(X)p" ++#define la_fmt_rj_offs21 "nt1,o(X)p" ++#define la_fmt_cj_offs21 "ntQ,o(X)p" ++#define la_fmt_rd_rj_offs16 "nt0,1,o(X)" ++#define la_fmt_rj_rd_offs16 "nt1,0,o(X)p" ++#define la_fmt_s_cd_fj_fk "K.stH,4,5" ++#define la_fmt_d_cd_fj_fk "K.dtH,4,5" ++#define la_fmt_fd_fj_fk_fa "nt3,4,5,6" ++#define la_fmt_fd_fj_fk_ca "nt3,4,5,L" ++#define la_fmt_cop_rj_si12 "ntM,1,i(x)" ++ ++/* structures */ ++ ++typedef struct { ++ uint32_t pc; ++ uint32_t insn; ++ int32_t imm; ++ int32_t imm2; ++ uint16_t op; ++ uint16_t code; ++ uint8_t codec; ++ uint8_t r1; ++ uint8_t r2; ++ uint8_t r3; ++ uint8_t r4; ++ uint8_t bit; ++} la_decode; ++ ++typedef struct { ++ const char * const name; ++ const la_codec codec; ++ const char * const format; ++} la_opcode_data; ++ ++/* reg names */ ++ ++const char * const loongarch_r_normal_name[32] = { ++ "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", "$r7", ++ "$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15", ++ "$r16", "$r17", "$r18", "$r19", "$r20", "$r21", "$r22", "$r23", ++ "$r24", "$r25", "$r26", "$r27", "$r28", "$r29", "$r30", "$r31", ++}; ++ ++const char * const loongarch_f_normal_name[32] = { ++ "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", ++ "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", ++ "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", ++ "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", ++}; ++ ++const char * const loongarch_cr_normal_name[4] = { ++ "$scr0", "$scr1", "$scr2", "$scr3", ++}; ++ ++const char * const loongarch_c_normal_name[8] = { ++ "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7", ++}; ++ ++/* instruction data */ ++ ++const la_opcode_data opcode_data[] = { ++ { "illegal", la_codec_illegal, la_fmt_illegal }, ++ { "gr2scr", la_codec_r_sd, la_fmt_sd_rj }, ++ { "scr2gr", la_codec_r_sj, la_fmt_rd_sj }, ++ { "clo.w", la_codec_2r, la_fmt_rd_rj }, ++ { "clz.w", la_codec_2r, la_fmt_rd_rj }, ++ { "cto.w", la_codec_2r, la_fmt_rd_rj }, ++ { "ctz.w", la_codec_2r, la_fmt_rd_rj }, ++ { "clo.d", la_codec_2r, la_fmt_rd_rj }, ++ { "clz.d", la_codec_2r, la_fmt_rd_rj }, ++ { "cto.d", la_codec_2r, la_fmt_rd_rj }, ++ { "ctz_d", la_codec_2r, la_fmt_rd_rj }, ++ { "revb.2h", la_codec_2r, la_fmt_rd_rj }, ++ { "revb.4h", la_codec_2r, la_fmt_rd_rj }, ++ { "revb.2w", la_codec_2r, la_fmt_rd_rj }, ++ { "revb.d", la_codec_2r, la_fmt_rd_rj }, ++ { "revh.2w", la_codec_2r, la_fmt_rd_rj }, ++ { "revh.d", la_codec_2r, la_fmt_rd_rj }, ++ { "bitrev.4b", la_codec_2r, la_fmt_rd_rj }, ++ { "bitrev.8b", la_codec_2r, la_fmt_rd_rj }, ++ { "bitrev.w", la_codec_2r, la_fmt_rd_rj }, ++ { "bitrev.d", la_codec_2r, la_fmt_rd_rj }, ++ { "ext.w.h", la_codec_2r, la_fmt_rd_rj }, ++ { "ext.w.b", la_codec_2r, la_fmt_rd_rj }, ++ { "rdtime.d", la_codec_2r, la_fmt_rd_rj }, ++ { "cpucfg", la_codec_2r, la_fmt_rd_rj }, ++ { "asrtle.d", la_codec_3r_rd0, la_fmt_rj_rk }, ++ { "asrtgt.d", la_codec_3r_rd0, la_fmt_rj_rk }, ++ { "alsl.w", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, ++ { "alsl.wu", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, ++ { "bytepick.w", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, ++ { "bytepick.d", la_codec_3r_sa3, la_fmt_rd_rj_rk_sa3 }, ++ { "add.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "add.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sub.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sub.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "slt", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sltu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "maskeqz", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "masknez", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "nor", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "and", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "or", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "xor", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "orn", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "andn", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sll.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "srl.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sra.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sll.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "srl.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "sra.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "rotr.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "rotr.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mul.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mulh.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mulh.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mul.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mulh.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mulh.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mulw.d.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mulw.d.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "div.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mod.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "div.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mod.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "div.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mod.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "div.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "mod.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crc.w.b.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crc.w.h.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crc.w.w.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crc.w.d.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crcc.w.b.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crcc.w.h.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crcc.w.w.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "crcc.w.d.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "break", la_codec_code, la_fmt_code }, ++ { "dbcl", la_codec_code, la_fmt_code }, ++ { "syscall", la_codec_code, la_fmt_code }, ++ { "alsl.d", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, ++ { "slli.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, ++ { "slli.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, ++ { "srli.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, ++ { "srli.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, ++ { "srai.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, ++ { "srai.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, ++ { "rotri.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, ++ { "rotri.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, ++ { "bstrins.w", la_codec_2r_2bw, la_fmt_rd_rj_msbw_lsbw }, ++ { "bstrpick.w", la_codec_2r_2bw, la_fmt_rd_rj_msbw_lsbw }, ++ { "bstrins.d", la_codec_2r_2bd, la_fmt_rd_rj_msbd_lsbd }, ++ { "bstrpick.d", la_codec_2r_2bd, la_fmt_rd_rj_msbd_lsbd }, ++ { "fadd.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fadd.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fsub.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fsub.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmul.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmul.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fdiv.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fdiv.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmax.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmax.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmin.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmin.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmaxa.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmaxa.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmina.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fmina.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fscaleb.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fscaleb.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fcopysign.s", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fcopysign.d", la_codec_3r, la_fmt_fd_fj_fk }, ++ { "fabs.s", la_codec_2r, la_fmt_fd_fj }, ++ { "fabs.d", la_codec_2r, la_fmt_fd_fj }, ++ { "fneg.s", la_codec_2r, la_fmt_fd_fj }, ++ { "fneg.d", la_codec_2r, la_fmt_fd_fj }, ++ { "flogb.s", la_codec_2r, la_fmt_fd_fj }, ++ { "flogb.d", la_codec_2r, la_fmt_fd_fj }, ++ { "fclass.s", la_codec_2r, la_fmt_fd_fj }, ++ { "fclass.d", la_codec_2r, la_fmt_fd_fj }, ++ { "fsqrt.s", la_codec_2r, la_fmt_fd_fj }, ++ { "fsqrt.d", la_codec_2r, la_fmt_fd_fj }, ++ { "frecip.s", la_codec_2r, la_fmt_fd_fj }, ++ { "frecip.d", la_codec_2r, la_fmt_fd_fj }, ++ { "frsqrt.s", la_codec_2r, la_fmt_fd_fj }, ++ { "frsqrt.d", la_codec_2r, la_fmt_fd_fj }, ++ { "fmov.s", la_codec_2r, la_fmt_fd_fj }, ++ { "fmov.d", la_codec_2r, la_fmt_fd_fj }, ++ { "movgr2fr.w", la_codec_2r, la_fmt_fd_rj }, ++ { "movgr2fr.d", la_codec_2r, la_fmt_fd_rj }, ++ { "movgr2frh.w", la_codec_2r, la_fmt_fd_rj }, ++ { "movfr2gr.s", la_codec_2r, la_fmt_rd_fj }, ++ { "movfr2gr.d", la_codec_2r, la_fmt_rd_fj }, ++ { "movfrh2gr.s", la_codec_2r, la_fmt_rd_fj }, ++ { "movgr2fcsr", la_codec_2r, la_fmt_fcsrd_rj }, ++ { "movfcsr2gr", la_codec_2r, la_fmt_rd_fcsrs }, ++ { "movfr2cf", la_codec_r_cd, la_fmt_cd_fj }, ++ { "movcf2fr", la_codec_r_cj, la_fmt_fd_cj }, ++ { "movgr2cf", la_codec_r_cd, la_fmt_cd_fj }, ++ { "movcf2gr", la_codec_r_cj, la_fmt_fd_cj }, ++ { "fcvt.s.d", la_codec_2r, la_fmt_fd_fj }, ++ { "fcvt.d.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrm.w.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrm.w.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrm.l.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrm.l.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrp.w.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrp.w.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrp.l.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrp.l.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrz.w.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrz.w.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrz.l.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrz.l.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrne.w.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrne.w.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrne.l.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftintrne.l.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftint.w.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftint.w.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ftint.l.s", la_codec_2r, la_fmt_fd_fj }, ++ { "ftint.l.d", la_codec_2r, la_fmt_fd_fj }, ++ { "ffint.s.w", la_codec_2r, la_fmt_fd_fj }, ++ { "ffint.s.l", la_codec_2r, la_fmt_fd_fj }, ++ { "ffint.d.w", la_codec_2r, la_fmt_fd_fj }, ++ { "ffint.d.l", la_codec_2r, la_fmt_fd_fj }, ++ { "frint.s", la_codec_2r, la_fmt_fd_fj }, ++ { "frint.d", la_codec_2r, la_fmt_fd_fj }, ++ { "slti", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "sltui", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "addi.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "addi.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "lu52i.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "addi", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ori", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "xori", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "csrxchg", la_codec_2r_im14, la_fmt_rd_rj_csr }, ++ { "cacop", la_codec_im5_r_im12, la_fmt_cop_rj_si12 }, ++ { "lddir", la_codec_2r_im8, la_fmt_rd_rj_level }, ++ { "ldpte", la_codec_r_seq, la_fmt_rj_seq }, ++ { "iocsrrd.b", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrrd.h", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrrd.w", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrrd.d", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrwr.b", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrwr.h", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrwr.w", la_codec_2r, la_fmt_rd_rj }, ++ { "iocsrwr.d", la_codec_2r, la_fmt_rd_rj }, ++ { "tlbclr", la_codec_empty, la_fmt_empty }, ++ { "tlbflush", la_codec_empty, la_fmt_empty }, ++ { "tlbsrch", la_codec_empty, la_fmt_empty }, ++ { "tlbrd", la_codec_empty, la_fmt_empty }, ++ { "tlbwr", la_codec_empty, la_fmt_empty }, ++ { "tlbfill", la_codec_empty, la_fmt_empty }, ++ { "ertn", la_codec_empty, la_fmt_empty }, ++ { "idle", la_codec_whint, la_fmt_whint }, ++ { "invtlb", la_codec_invtlb, la_fmt_invtlb }, ++ { "fmadd.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fmadd.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fmsub.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fmsub.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fnmadd.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fnmadd.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fnmsub.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fnmsub.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, ++ { "fcmp.cond.s", la_codec_cond, la_fmt_s_cd_fj_fk }, ++ { "fcmp.cond.d", la_codec_cond, la_fmt_d_cd_fj_fk }, ++ { "fsel", la_codec_sel, la_fmt_fd_fj_fk_ca }, ++ { "addu16i.d", la_codec_2r_im16, la_fmt_rd_rj_si16 }, ++ { "lu12i.w", la_codec_r_im20, la_fmt_rd_si20 }, ++ { "lu32i.d", la_codec_r_im20, la_fmt_rd_si20 }, ++ { "pcaddi", la_codec_r_im20, la_fmt_rd_si20 }, ++ { "pcalau12i", la_codec_r_im20, la_fmt_rd_si20 }, ++ { "pcaddu12i", la_codec_r_im20, la_fmt_rd_si20 }, ++ { "pcaddu18i", la_codec_r_im20, la_fmt_rd_si20 }, ++ { "ll.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "sc.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "ll.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "sc.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "ldptr.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "stptr.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "ldptr.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "stptr.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, ++ { "ld.b", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ld.h", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ld.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ld.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "st.b", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "st.h", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "st.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "st.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ld.bu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ld.hu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ld.wu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "preld", la_codec_2r_im12, la_fmt_hint_rj_si12 }, ++ { "fld.s", la_codec_2r_im12, la_fmt_fd_fj_si12 }, ++ { "fst.s", la_codec_2r_im12, la_fmt_fd_fj_si12 }, ++ { "fld.d", la_codec_2r_im12, la_fmt_fd_fj_si12 }, ++ { "fst.d", la_codec_2r_im12, la_fmt_fd_fj_si12 }, ++ { "ldl.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ldr.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ldl.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ldr.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "stl.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "str.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, ++ { "ldx.b", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldx.h", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldx.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldx.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stx.b", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stx.h", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stx.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stx.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldx.bu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldx.hu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldx.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "fldx.s", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fldx.d", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fstx.s", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fstx.d", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "amswap.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amswap.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amadd.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amadd.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amand.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amand.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amor.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amor.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amxor.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amxor.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amswap.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amswap.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amadd.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amadd.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amand.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amand.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amor.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amor.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amxor.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "amxor.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.db.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.db.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.db.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammax.db.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.db.wu", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ammin.db.du", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "dbar", la_codec_whint, la_fmt_whint }, ++ { "ibar", la_codec_whint, la_fmt_whint }, ++ { "fldgt.s", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fldgt.d", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fldle.s", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fldle.d", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fstgt.s", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fstgt.d", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fstle.s", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "fstle.d", la_codec_3r, la_fmt_fd_rj_rk }, ++ { "ldgt.b", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldgt.h", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldgt.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldgt.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldle.b", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldle.h", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldle.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "ldle.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stgt.b", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stgt.h", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stgt.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stgt.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stle.b", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stle.h", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stle.w", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "stle.d", la_codec_3r, la_fmt_rd_rj_rk }, ++ { "beqz", la_codec_r_ofs21, la_fmt_rj_offs21 }, ++ { "bnez", la_codec_r_ofs21, la_fmt_rj_offs21 }, ++ { "bceqz", la_codec_cj_ofs21, la_fmt_cj_offs21 }, ++ { "bcnez", la_codec_cj_ofs21, la_fmt_cj_offs21 }, ++ { "jirl", la_codec_2r_im16, la_fmt_rd_rj_offs16 }, ++ { "b", la_codec_ofs26, la_fmt_offs26 }, ++ { "bl", la_codec_ofs26, la_fmt_offs26 }, ++ { "beq", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, ++ { "bne", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, ++ { "blt", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, ++ { "bge", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, ++ { "bltu", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, ++ { "bgeu", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, ++ ++ /* vz insn */ ++ { "hvcl", la_codec_code, la_fmt_code }, ++ ++}; ++ ++ ++/* decode opcode */ ++ ++static void decode_insn_opcode(la_decode *dec) ++{ ++ uint32_t insn = dec->insn; ++ uint16_t op = la_op_illegal; ++ switch ((insn >> 26) & 0x3f) { ++ case 0x0: ++ switch ((insn >> 22) & 0xf) { ++ case 0x0: ++ switch ((insn >> 18) & 0xf) { ++ case 0x0: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x2: ++ switch ((insn >> 2) & 0x7) { ++ case 0x0: ++ op = la_op_gr2scr; ++ break; ++ } ++ break; ++ case 0x3: ++ switch ((insn >> 7) & 0x7) { ++ case 0x0: ++ op = la_op_scr2gr; ++ break; ++ } ++ break; ++ case 0x4: ++ op = la_op_clo_w; ++ break; ++ case 0x5: ++ op = la_op_clz_w; ++ break; ++ case 0x6: ++ op = la_op_cto_w; ++ break; ++ case 0x7: ++ op = la_op_ctz_w; ++ break; ++ case 0x8: ++ op = la_op_clo_d; ++ break; ++ case 0x9: ++ op = la_op_clz_d; ++ break; ++ case 0xa: ++ op = la_op_cto_d; ++ break; ++ case 0xb: ++ op = la_op_ctz_d; ++ break; ++ case 0xc: ++ op = la_op_revb_2h; ++ break; ++ case 0xd: ++ op = la_op_revb_4h; ++ break; ++ case 0xe: ++ op = la_op_revb_2w; ++ break; ++ case 0xf: ++ op = la_op_revb_d; ++ break; ++ case 0x10: ++ op = la_op_revh_2w; ++ break; ++ case 0x11: ++ op = la_op_revh_d; ++ break; ++ case 0x12: ++ op = la_op_bitrev_4b; ++ break; ++ case 0x13: ++ op = la_op_bitrev_8b; ++ break; ++ case 0x14: ++ op = la_op_bitrev_w; ++ break; ++ case 0x15: ++ op = la_op_bitrev_d; ++ break; ++ case 0x16: ++ op = la_op_ext_w_h; ++ break; ++ case 0x17: ++ op = la_op_ext_w_b; ++ break; ++ case 0x1a: ++ op = la_op_rdtime_d; ++ break; ++ case 0x1b: ++ op = la_op_cpucfg; ++ break; ++ } ++ break; ++ case 0x2: ++ switch (insn & 0x0000001f) { ++ case 0x00000000: ++ op = la_op_asrtle_d; ++ break; ++ } ++ break; ++ case 0x3: ++ switch (insn & 0x0000001f) { ++ case 0x00000000: ++ op = la_op_asrtgt_d; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x1: ++ switch ((insn >> 17) & 0x1) { ++ case 0x0: ++ op = la_op_alsl_w; ++ break; ++ case 0x1: ++ op = la_op_alsl_wu; ++ break; ++ } ++ break; ++ case 0x2: ++ switch ((insn >> 17) & 0x1) { ++ case 0x0: ++ op = la_op_bytepick_w; ++ break; ++ } ++ break; ++ case 0x3: ++ op = la_op_bytepick_d; ++ break; ++ case 0x4: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ op = la_op_add_w; ++ break; ++ case 0x1: ++ op = la_op_add_d; ++ break; ++ case 0x2: ++ op = la_op_sub_w; ++ break; ++ case 0x3: ++ op = la_op_sub_d; ++ break; ++ case 0x4: ++ op = la_op_slt; ++ break; ++ case 0x5: ++ op = la_op_sltu; ++ break; ++ case 0x6: ++ op = la_op_maskeqz; ++ break; ++ case 0x7: ++ op = la_op_masknez; ++ break; ++ } ++ break; ++ case 0x5: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ op = la_op_nor; ++ break; ++ case 0x1: ++ op = la_op_and; ++ break; ++ case 0x2: ++ op = la_op_or; ++ break; ++ case 0x3: ++ op = la_op_xor; ++ break; ++ case 0x4: ++ op = la_op_orn; ++ break; ++ case 0x5: ++ op = la_op_andn; ++ break; ++ case 0x6: ++ op = la_op_sll_w; ++ break; ++ case 0x7: ++ op = la_op_srl_w; ++ break; ++ } ++ break; ++ case 0x6: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ op = la_op_sra_w; ++ break; ++ case 0x1: ++ op = la_op_sll_d; ++ break; ++ case 0x2: ++ op = la_op_srl_d; ++ break; ++ case 0x3: ++ op = la_op_sra_d; ++ break; ++ case 0x6: ++ op = la_op_rotr_w; ++ break; ++ case 0x7: ++ op = la_op_rotr_d; ++ break; ++ } ++ break; ++ case 0x7: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ op = la_op_mul_w; ++ break; ++ case 0x1: ++ op = la_op_mulh_w; ++ break; ++ case 0x2: ++ op = la_op_mulh_wu; ++ break; ++ case 0x3: ++ op = la_op_mul_d; ++ break; ++ case 0x4: ++ op = la_op_mulh_d; ++ break; ++ case 0x5: ++ op = la_op_mulh_du; ++ break; ++ case 0x6: ++ op = la_op_mulw_d_w; ++ break; ++ case 0x7: ++ op = la_op_mulw_d_wu; ++ break; ++ } ++ break; ++ case 0x8: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ op = la_op_div_w; ++ break; ++ case 0x1: ++ op = la_op_mod_w; ++ break; ++ case 0x2: ++ op = la_op_div_wu; ++ break; ++ case 0x3: ++ op = la_op_mod_wu; ++ break; ++ case 0x4: ++ op = la_op_div_d; ++ break; ++ case 0x5: ++ op = la_op_mod_d; ++ break; ++ case 0x6: ++ op = la_op_div_du; ++ break; ++ case 0x7: ++ op = la_op_mod_du; ++ break; ++ } ++ break; ++ case 0x9: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ op = la_op_crc_w_b_w; ++ break; ++ case 0x1: ++ op = la_op_crc_w_h_w; ++ break; ++ case 0x2: ++ op = la_op_crc_w_w_w; ++ break; ++ case 0x3: ++ op = la_op_crc_w_d_w; ++ break; ++ case 0x4: ++ op = la_op_crcc_w_b_w; ++ break; ++ case 0x5: ++ op = la_op_crcc_w_h_w; ++ break; ++ case 0x6: ++ op = la_op_crcc_w_w_w; ++ break; ++ case 0x7: ++ op = la_op_crcc_w_d_w; ++ break; ++ } ++ break; ++ case 0xa: ++ switch ((insn >> 15) & 0x7) { ++ case 0x4: ++ op = la_op_break; ++ break; ++ case 0x5: ++ op = la_op_dbcl; ++ break; ++ case 0x6: ++ op = la_op_syscall; ++ break; ++ case 0x7: ++ op = la_op_hvcl; ++ break; ++ } ++ break; ++ case 0xb: ++ switch ((insn >> 17) & 0x1) { ++ case 0x0: ++ op = la_op_alsl_d; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x1: ++ switch ((insn >> 21) & 0x1) { ++ case 0x0: ++ switch ((insn >> 16) & 0x1f) { ++ case 0x0: ++ switch ((insn >> 15) & 0x1) { ++ case 0x1: ++ op = la_op_slli_w; ++ break; ++ } ++ break; ++ case 0x1: ++ op = la_op_slli_d; ++ break; ++ case 0x4: ++ switch ((insn >> 15) & 0x1) { ++ case 0x1: ++ op = la_op_srli_w; ++ break; ++ } ++ break; ++ case 0x5: ++ op = la_op_srli_d; ++ break; ++ case 0x8: ++ switch ((insn >> 15) & 0x1) { ++ case 0x1: ++ op = la_op_srai_w; ++ break; ++ } ++ break; ++ case 0x9: ++ op = la_op_srai_d; ++ break; ++ case 0xc: ++ switch ((insn >> 15) & 0x1) { ++ case 0x1: ++ op = la_op_rotri_w; ++ break; ++ } ++ break; ++ case 0xd: ++ op = la_op_rotri_d; ++ break; ++ } ++ break; ++ case 0x1: ++ switch ((insn >> 15) & 0x1) { ++ case 0x0: ++ op = la_op_bstrins_w; ++ break; ++ case 0x1: ++ op = la_op_bstrpick_w; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x2: ++ op = la_op_bstrins_d; ++ break; ++ case 0x3: ++ op = la_op_bstrpick_d; ++ break; ++ case 0x4: ++ switch ((insn >> 15) & 0x7f) { ++ case 0x1: ++ op = la_op_fadd_s; ++ break; ++ case 0x2: ++ op = la_op_fadd_d; ++ break; ++ case 0x5: ++ op = la_op_fsub_s; ++ break; ++ case 0x6: ++ op = la_op_fsub_d; ++ break; ++ case 0x9: ++ op = la_op_fmul_s; ++ break; ++ case 0xa: ++ op = la_op_fmul_d; ++ break; ++ case 0xd: ++ op = la_op_fdiv_s; ++ break; ++ case 0xe: ++ op = la_op_fdiv_d; ++ break; ++ case 0x11: ++ op = la_op_fmax_s; ++ break; ++ case 0x12: ++ op = la_op_fmax_d; ++ break; ++ case 0x15: ++ op = la_op_fmin_s; ++ break; ++ case 0x16: ++ op = la_op_fmin_d; ++ break; ++ case 0x19: ++ op = la_op_fmaxa_s; ++ break; ++ case 0x1a: ++ op = la_op_fmaxa_d; ++ break; ++ case 0x1d: ++ op = la_op_fmina_s; ++ break; ++ case 0x1e: ++ op = la_op_fmina_d; ++ break; ++ case 0x21: ++ op = la_op_fscaleb_s; ++ break; ++ case 0x22: ++ op = la_op_fscaleb_d; ++ break; ++ case 0x25: ++ op = la_op_fcopysign_s; ++ break; ++ case 0x26: ++ op = la_op_fcopysign_d; ++ break; ++ case 0x28: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x1: ++ op = la_op_fabs_s; ++ break; ++ case 0x2: ++ op = la_op_fabs_d; ++ break; ++ case 0x5: ++ op = la_op_fneg_s; ++ break; ++ case 0x6: ++ op = la_op_fneg_d; ++ break; ++ case 0x9: ++ op = la_op_flogb_s; ++ break; ++ case 0xa: ++ op = la_op_flogb_d; ++ break; ++ case 0xd: ++ op = la_op_fclass_s; ++ break; ++ case 0xe: ++ op = la_op_fclass_d; ++ break; ++ case 0x11: ++ op = la_op_fsqrt_s; ++ break; ++ case 0x12: ++ op = la_op_fsqrt_d; ++ break; ++ case 0x15: ++ op = la_op_frecip_s; ++ break; ++ case 0x16: ++ op = la_op_frecip_d; ++ break; ++ case 0x19: ++ op = la_op_frsqrt_s; ++ break; ++ case 0x1a: ++ op = la_op_frsqrt_d; ++ break; ++ } ++ break; ++ case 0x29: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x5: ++ op = la_op_fmov_s; ++ break; ++ case 0x6: ++ op = la_op_fmov_d; ++ break; ++ case 0x9: ++ op = la_op_movgr2fr_w; ++ break; ++ case 0xa: ++ op = la_op_movgr2fr_d; ++ break; ++ case 0xb: ++ op = la_op_movgr2frh_w; ++ break; ++ case 0xd: ++ op = la_op_movfr2gr_s; ++ break; ++ case 0xe: ++ op = la_op_movfr2gr_d; ++ break; ++ case 0xf: ++ op = la_op_movfrh2gr_s; ++ break; ++ case 0x10: ++ op = la_op_movgr2fcsr; ++ break; ++ case 0x12: ++ op = la_op_movfcsr2gr; ++ break; ++ case 0x14: ++ switch ((insn >> 3) & 0x3) { ++ case 0x0: ++ op = la_op_movfr2cf; ++ break; ++ } ++ break; ++ case 0x15: ++ switch ((insn >> 8) & 0x3) { ++ case 0x0: ++ op = la_op_movcf2fr; ++ break; ++ } ++ break; ++ case 0x16: ++ switch ((insn >> 3) & 0x3) { ++ case 0x0: ++ op = la_op_movgr2cf; ++ break; ++ } ++ break; ++ case 0x17: ++ switch ((insn >> 8) & 0x3) { ++ case 0x0: ++ op = la_op_movcf2gr; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x32: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x6: ++ op = la_op_fcvt_s_d; ++ break; ++ case 0x9: ++ op = la_op_fcvt_d_s; ++ break; ++ } ++ break; ++ case 0x34: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x1: ++ op = la_op_ftintrm_w_s; ++ break; ++ case 0x2: ++ op = la_op_ftintrm_w_d; ++ break; ++ case 0x9: ++ op = la_op_ftintrm_l_s; ++ break; ++ case 0xa: ++ op = la_op_ftintrm_l_d; ++ break; ++ case 0x11: ++ op = la_op_ftintrp_w_s; ++ break; ++ case 0x12: ++ op = la_op_ftintrp_w_d; ++ break; ++ case 0x19: ++ op = la_op_ftintrp_l_s; ++ break; ++ case 0x1a: ++ op = la_op_ftintrp_l_d; ++ break; ++ } ++ break; ++ case 0x35: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x1: ++ op = la_op_ftintrz_w_s; ++ break; ++ case 0x2: ++ op = la_op_ftintrz_w_d; ++ break; ++ case 0x9: ++ op = la_op_ftintrz_l_s; ++ break; ++ case 0xa: ++ op = la_op_ftintrz_l_d; ++ break; ++ case 0x11: ++ op = la_op_ftintrne_w_s; ++ break; ++ case 0x12: ++ op = la_op_ftintrne_w_d; ++ break; ++ case 0x19: ++ op = la_op_ftintrne_l_s; ++ break; ++ case 0x1a: ++ op = la_op_ftintrne_l_d; ++ break; ++ } ++ break; ++ case 0x36: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x1: ++ op = la_op_ftint_w_s; ++ break; ++ case 0x2: ++ op = la_op_ftint_w_d; ++ break; ++ case 0x9: ++ op = la_op_ftint_l_s; ++ break; ++ case 0xa: ++ op = la_op_ftint_l_d; ++ break; ++ } ++ break; ++ case 0x3a: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x4: ++ op = la_op_ffint_s_w; ++ break; ++ case 0x6: ++ op = la_op_ffint_s_l; ++ break; ++ case 0x8: ++ op = la_op_ffint_d_w; ++ break; ++ case 0xa: ++ op = la_op_ffint_d_l; ++ break; ++ } ++ break; ++ case 0x3c: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x11: ++ op = la_op_frint_s; ++ break; ++ case 0x12: ++ op = la_op_frint_d; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x8: ++ op = la_op_slti; ++ break; ++ case 0x9: ++ op = la_op_sltui; ++ break; ++ case 0xa: ++ op = la_op_addi_w; ++ break; ++ case 0xb: ++ op = la_op_addi_d; ++ break; ++ case 0xc: ++ op = la_op_lu52i_d; ++ break; ++ case 0xd: ++ op = la_op_addi; ++ break; ++ case 0xe: ++ op = la_op_ori; ++ break; ++ case 0xf: ++ op = la_op_xori; ++ break; ++ } ++ break; ++ case 0x1: ++ switch ((insn >> 24) & 0x3) { ++ case 0x0: ++ op = la_op_csrxchg; ++ break; ++ case 0x2: ++ switch ((insn >> 22) & 0x3) { ++ case 0x0: ++ op = la_op_cacop; ++ break; ++ case 0x1: ++ switch ((insn >> 18) & 0xf) { ++ case 0x0: ++ op = la_op_lddir; ++ break; ++ case 0x1: ++ switch (insn & 0x0000001f) { ++ case 0x00000000: ++ op = la_op_ldpte; ++ break; ++ } ++ break; ++ case 0x2: ++ switch ((insn >> 15) & 0x7) { ++ case 0x0: ++ switch ((insn >> 10) & 0x1f) { ++ case 0x0: ++ op = la_op_iocsrrd_b; ++ break; ++ case 0x1: ++ op = la_op_iocsrrd_h; ++ break; ++ case 0x2: ++ op = la_op_iocsrrd_w; ++ break; ++ case 0x3: ++ op = la_op_iocsrrd_d; ++ break; ++ case 0x4: ++ op = la_op_iocsrwr_b; ++ break; ++ case 0x5: ++ op = la_op_iocsrwr_h; ++ break; ++ case 0x6: ++ op = la_op_iocsrwr_w; ++ break; ++ case 0x7: ++ op = la_op_iocsrwr_d; ++ break; ++ case 0x8: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_tlbclr; ++ break; ++ } ++ break; ++ case 0x9: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_tlbflush; ++ break; ++ } ++ break; ++ case 0xa: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_tlbsrch; ++ break; ++ } ++ break; ++ case 0xb: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_tlbrd; ++ break; ++ } ++ break; ++ case 0xc: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_tlbwr; ++ break; ++ } ++ break; ++ case 0xd: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_tlbfill; ++ break; ++ } ++ break; ++ case 0xe: ++ switch (insn & 0x000003ff) { ++ case 0x00000000: ++ op = la_op_ertn; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x1: ++ op = la_op_idle; ++ break; ++ case 0x3: ++ op = la_op_invtlb; ++ break; ++ } ++ break; ++ } ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x2: ++ switch ((insn >> 20) & 0x3f) { ++ case 0x1: ++ op = la_op_fmadd_s; ++ break; ++ case 0x2: ++ op = la_op_fmadd_d; ++ break; ++ case 0x5: ++ op = la_op_fmsub_s; ++ break; ++ case 0x6: ++ op = la_op_fmsub_d; ++ break; ++ case 0x9: ++ op = la_op_fnmadd_s; ++ break; ++ case 0xa: ++ op = la_op_fnmadd_d; ++ break; ++ case 0xd: ++ op = la_op_fnmsub_s; ++ break; ++ case 0xe: ++ op = la_op_fnmsub_d; ++ break; ++ } ++ break; ++ case 0x3: ++ switch ((insn >> 20) & 0x3f) { ++ case 0x1: ++ switch ((insn >> 3) & 0x3) { ++ case 0x0: ++ op = la_op_fcmp_cond_s; ++ break; ++ } ++ break; ++ case 0x2: ++ switch ((insn >> 3) & 0x3) { ++ case 0x0: ++ op = la_op_fcmp_cond_d; ++ break; ++ } ++ break; ++ case 0x10: ++ switch ((insn >> 18) & 0x3) { ++ case 0x0: ++ op = la_op_fsel; ++ break; ++ } ++ break; ++ } ++ break; ++ case 0x4: ++ op = la_op_addu16i_d; ++ break; ++ case 0x5: ++ switch ((insn >> 25) & 0x1) { ++ case 0x0: ++ op = la_op_lu12i_w; ++ break; ++ case 0x1: ++ op = la_op_lu32i_d; ++ break; ++ } ++ break; ++ case 0x6: ++ switch ((insn >> 25) & 0x1) { ++ case 0x0: ++ op = la_op_pcaddi; ++ break; ++ case 0x1: ++ op = la_op_pcalau12i; ++ break; ++ } ++ break; ++ case 0x7: ++ switch ((insn >> 25) & 0x1) { ++ case 0x0: ++ op = la_op_pcaddu12i; ++ break; ++ case 0x1: ++ op = la_op_pcaddu18i; ++ break; ++ } ++ break; ++ case 0x8: ++ switch ((insn >> 24) & 0x3) { ++ case 0x0: ++ op = la_op_ll_w; ++ break; ++ case 0x1: ++ op = la_op_sc_w; ++ break; ++ case 0x2: ++ op = la_op_ll_d; ++ break; ++ case 0x3: ++ op = la_op_sc_d; ++ break; ++ } ++ break; ++ case 0x9: ++ switch ((insn >> 24) & 0x3) { ++ case 0x0: ++ op = la_op_ldptr_w; ++ break; ++ case 0x1: ++ op = la_op_stptr_w; ++ break; ++ case 0x2: ++ op = la_op_ldptr_d; ++ break; ++ case 0x3: ++ op = la_op_stptr_d; ++ break; ++ } ++ break; ++ case 0xa: ++ switch ((insn >> 22) & 0xf) { ++ case 0x0: ++ op = la_op_ld_b; ++ break; ++ case 0x1: ++ op = la_op_ld_h; ++ break; ++ case 0x2: ++ op = la_op_ld_w; ++ break; ++ case 0x3: ++ op = la_op_ld_d; ++ break; ++ case 0x4: ++ op = la_op_st_b; ++ break; ++ case 0x5: ++ op = la_op_st_h; ++ break; ++ case 0x6: ++ op = la_op_st_w; ++ break; ++ case 0x7: ++ op = la_op_st_d; ++ break; ++ case 0x8: ++ op = la_op_ld_bu; ++ break; ++ case 0x9: ++ op = la_op_ld_hu; ++ break; ++ case 0xa: ++ op = la_op_ld_wu; ++ break; ++ case 0xb: ++ op = la_op_preld; ++ break; ++ case 0xc: ++ op = la_op_fld_s; ++ break; ++ case 0xd: ++ op = la_op_fst_s; ++ break; ++ case 0xe: ++ op = la_op_fld_d; ++ break; ++ case 0xf: ++ op = la_op_fst_d; ++ break; ++ } ++ break; ++ case 0xb: ++ switch ((insn >> 22) & 0xf) { ++ case 0x8: ++ op = la_op_ldl_w; ++ break; ++ case 0x9: ++ op = la_op_ldr_w; ++ break; ++ case 0xa: ++ op = la_op_ldl_d; ++ break; ++ case 0xb: ++ op = la_op_ldr_d; ++ break; ++ case 0xe: ++ op = la_op_stl_d; ++ break; ++ case 0xf: ++ op = la_op_str_d; ++ break; ++ } ++ break; ++ case 0xe: ++ switch ((insn >> 15) & 0x7ff) { ++ case 0x0: ++ op = la_op_ldx_b; ++ break; ++ case 0x8: ++ op = la_op_ldx_h; ++ break; ++ case 0x10: ++ op = la_op_ldx_w; ++ break; ++ case 0x18: ++ op = la_op_ldx_d; ++ break; ++ case 0x20: ++ op = la_op_stx_b; ++ break; ++ case 0x28: ++ op = la_op_stx_h; ++ break; ++ case 0x30: ++ op = la_op_stx_w; ++ break; ++ case 0x38: ++ op = la_op_stx_d; ++ break; ++ case 0x40: ++ op = la_op_ldx_bu; ++ break; ++ case 0x48: ++ op = la_op_ldx_hu; ++ break; ++ case 0x50: ++ op = la_op_ldx_wu; ++ break; ++ case 0x60: ++ op = la_op_fldx_s; ++ break; ++ case 0x68: ++ op = la_op_fldx_d; ++ break; ++ case 0x70: ++ op = la_op_fstx_s; ++ break; ++ case 0x78: ++ op = la_op_fstx_d; ++ break; ++ case 0xc0: ++ op = la_op_amswap_w; ++ break; ++ case 0xc1: ++ op = la_op_amswap_d; ++ break; ++ case 0xc2: ++ op = la_op_amadd_w; ++ break; ++ case 0xc3: ++ op = la_op_amadd_d; ++ break; ++ case 0xc4: ++ op = la_op_amand_w; ++ break; ++ case 0xc5: ++ op = la_op_amand_d; ++ break; ++ case 0xc6: ++ op = la_op_amor_w; ++ break; ++ case 0xc7: ++ op = la_op_amor_d; ++ break; ++ case 0xc8: ++ op = la_op_amxor_w; ++ break; ++ case 0xc9: ++ op = la_op_amxor_d; ++ break; ++ case 0xca: ++ op = la_op_ammax_w; ++ break; ++ case 0xcb: ++ op = la_op_ammax_d; ++ break; ++ case 0xcc: ++ op = la_op_ammin_w; ++ break; ++ case 0xcd: ++ op = la_op_ammin_d; ++ break; ++ case 0xce: ++ op = la_op_ammax_wu; ++ break; ++ case 0xcf: ++ op = la_op_ammax_du; ++ break; ++ case 0xd0: ++ op = la_op_ammin_wu; ++ break; ++ case 0xd1: ++ op = la_op_ammin_du; ++ break; ++ case 0xd2: ++ op = la_op_amswap_db_w; ++ break; ++ case 0xd3: ++ op = la_op_amswap_db_d; ++ break; ++ case 0xd4: ++ op = la_op_amadd_db_w; ++ break; ++ case 0xd5: ++ op = la_op_amadd_db_d; ++ break; ++ case 0xd6: ++ op = la_op_amand_db_w; ++ break; ++ case 0xd7: ++ op = la_op_amand_db_d; ++ break; ++ case 0xd8: ++ op = la_op_amor_db_w; ++ break; ++ case 0xd9: ++ op = la_op_amor_db_d; ++ break; ++ case 0xda: ++ op = la_op_amxor_db_w; ++ break; ++ case 0xdb: ++ op = la_op_amxor_db_d; ++ break; ++ case 0xdc: ++ op = la_op_ammax_db_w; ++ break; ++ case 0xdd: ++ op = la_op_ammax_db_d; ++ break; ++ case 0xde: ++ op = la_op_ammin_db_w; ++ break; ++ case 0xdf: ++ op = la_op_ammin_db_d; ++ break; ++ case 0xe0: ++ op = la_op_ammax_db_wu; ++ break; ++ case 0xe1: ++ op = la_op_ammax_db_du; ++ break; ++ case 0xe2: ++ op = la_op_ammin_db_wu; ++ break; ++ case 0xe3: ++ op = la_op_ammin_db_du; ++ break; ++ case 0xe4: ++ op = la_op_dbar; ++ break; ++ case 0xe5: ++ op = la_op_ibar; ++ break; ++ case 0xe8: ++ op = la_op_fldgt_s; ++ break; ++ case 0xe9: ++ op = la_op_fldgt_d; ++ break; ++ case 0xea: ++ op = la_op_fldle_s; ++ break; ++ case 0xeb: ++ op = la_op_fldle_d; ++ break; ++ case 0xec: ++ op = la_op_fstgt_s; ++ break; ++ case 0xed: ++ op = la_op_fstgt_d; ++ break; ++ case 0xee: ++ op = ls_op_fstle_s; ++ break; ++ case 0xef: ++ op = la_op_fstle_d; ++ break; ++ case 0xf0: ++ op = la_op_ldgt_b; ++ break; ++ case 0xf1: ++ op = la_op_ldgt_h; ++ break; ++ case 0xf2: ++ op = la_op_ldgt_w; ++ break; ++ case 0xf3: ++ op = la_op_ldgt_d; ++ break; ++ case 0xf4: ++ op = la_op_ldle_b; ++ break; ++ case 0xf5: ++ op = la_op_ldle_h; ++ break; ++ case 0xf6: ++ op = la_op_ldle_w; ++ break; ++ case 0xf7: ++ op = la_op_ldle_d; ++ break; ++ case 0xf8: ++ op = la_op_stgt_b; ++ break; ++ case 0xf9: ++ op = la_op_stgt_h; ++ break; ++ case 0xfa: ++ op = la_op_stgt_w; ++ break; ++ case 0xfb: ++ op = la_op_stgt_d; ++ break; ++ case 0xfc: ++ op = la_op_stle_b; ++ break; ++ case 0xfd: ++ op = la_op_stle_h; ++ break; ++ case 0xfe: ++ op = la_op_stle_w; ++ break; ++ case 0xff: ++ op = la_op_stle_d; ++ break; ++ } ++ break; ++ case 0x10: ++ op = la_op_beqz; ++ break; ++ case 0x11: ++ op = la_op_bnez; ++ break; ++ case 0x12: ++ switch ((insn >> 8) & 0x3) { ++ case 0x0: ++ op = la_op_bceqz; ++ break; ++ case 0x1: ++ op = la_op_bcnez; ++ break; ++ } ++ break; ++ case 0x13: ++ op = la_op_jirl; ++ break; ++ case 0x14: ++ op = la_op_b; ++ break; ++ case 0x15: ++ op = la_op_bl; ++ break; ++ case 0x16: ++ op = la_op_beq; ++ break; ++ case 0x17: ++ op = la_op_bne; ++ break; ++ case 0x18: ++ op = la_op_blt; ++ break; ++ case 0x19: ++ op = la_op_bge; ++ break; ++ case 0x1a: ++ op = la_op_bltu; ++ break; ++ case 0x1b: ++ op = la_op_bgeu; ++ break; ++ default: ++ op = la_op_illegal; ++ break; ++ } ++ dec->op = op; ++} ++ ++/* operand extractors */ ++ ++#define IM_5 5 ++#define IM_8 8 ++#define IM_12 12 ++#define IM_14 14 ++#define IM_15 15 ++#define IM_16 16 ++#define IM_20 20 ++#define IM_21 21 ++#define IM_26 26 ++ ++static uint32_t operand_r1(uint32_t insn) ++{ ++ return insn & 0x1f; ++} ++ ++static uint32_t operand_r2(uint32_t insn) ++{ ++ return (insn >> 5) & 0x1f; ++} ++ ++static uint32_t operand_r3(uint32_t insn) ++{ ++ return (insn >> 10) & 0x1f; ++} ++ ++static uint32_t operand_r4(uint32_t insn) ++{ ++ return (insn >> 15) & 0x1f; ++} ++ ++static uint32_t operand_u6(uint32_t insn) ++{ ++ return (insn >> 10) & 0x3f; ++} ++ ++static uint32_t operand_bw1(uint32_t insn) ++{ ++ return (insn >> 10) & 0x1f; ++} ++ ++static uint32_t operand_bw2(uint32_t insn) ++{ ++ return (insn >> 16) & 0x1f; ++} ++ ++static uint32_t operand_bd1(uint32_t insn) ++{ ++ return (insn >> 10) & 0x3f; ++} ++ ++static uint32_t operand_bd2(uint32_t insn) ++{ ++ return (insn >> 16) & 0x3f; ++} ++ ++static uint32_t operand_sa2(uint32_t insn) ++{ ++ return (insn >> 15) & 0x3; ++} ++ ++static uint32_t operand_sa3(uint32_t insn) ++{ ++ return (insn >> 15) & 0x3; ++} ++ ++static int32_t operand_im20(uint32_t insn) ++{ ++ int32_t imm = (int32_t)((insn >> 5) & 0xfffff); ++ return imm > (1 << 19) ? imm - (1 << 20) : imm; ++} ++ ++static int32_t operand_im16(uint32_t insn) ++{ ++ int32_t imm = (int32_t)((insn >> 10) & 0xffff); ++ return imm > (1 << 15) ? imm - (1 << 16) : imm; ++} ++ ++static int32_t operand_im14(uint32_t insn) ++{ ++ int32_t imm = (int32_t)((insn >> 10) & 0x3fff); ++ return imm > (1 << 13) ? imm - (1 << 14) : imm; ++} ++ ++static int32_t operand_im12(uint32_t insn) ++{ ++ int32_t imm = (int32_t)((insn >> 10) & 0xfff); ++ return imm > (1 << 11) ? imm - (1 << 12) : imm; ++} ++ ++static int32_t operand_im8(uint32_t insn) ++{ ++ int32_t imm = (int32_t)((insn >> 10) & 0xff); ++ return imm > (1 << 7) ? imm - (1 << 8) : imm; ++} ++ ++static uint32_t operand_sd(uint32_t insn) ++{ ++ return insn & 0x3; ++} ++ ++static uint32_t operand_sj(uint32_t insn) ++{ ++ return (insn >> 5) & 0x3; ++} ++ ++static uint32_t operand_cd(uint32_t insn) ++{ ++ return insn & 0x7; ++} ++ ++static uint32_t operand_cj(uint32_t insn) ++{ ++ return (insn >> 5) & 0x7; ++} ++ ++static uint32_t operand_code(uint32_t insn) ++{ ++ return insn & 0x7fff; ++} ++ ++static int32_t operand_whint(uint32_t insn) ++{ ++ int32_t imm = (int32_t)(insn & 0x7fff); ++ return imm > (1 << 14) ? imm - (1 << 15) : imm; ++} ++ ++static int32_t operand_invop(uint32_t insn) ++{ ++ int32_t imm = (int32_t)(insn & 0x1f); ++ return imm > (1 << 4) ? imm - (1 << 5) : imm; ++} ++ ++static int32_t operand_ofs21(uint32_t insn) ++{ ++ int32_t imm = (((int32_t)insn & 0x1f) << 16) | ++ ((insn >> 10) & 0xffff); ++ return imm > (1 << 20) ? imm - (1 << 21) : imm; ++} ++ ++static int32_t operand_ofs26(uint32_t insn) ++{ ++ int32_t imm = (((int32_t)insn & 0x3ff) << 16) | ++ ((insn >> 10) & 0xffff); ++ return imm > (1 << 25) ? imm - (1 << 26) : imm; ++} ++ ++static uint32_t operand_fcond(uint32_t insn) ++{ ++ return (insn >> 15) & 0x1f; ++} ++ ++static uint32_t operand_sel(uint32_t insn) ++{ ++ return (insn >> 15) & 0x7; ++} ++ ++/* decode operands */ ++ ++static void decode_insn_operands(la_decode *dec) ++{ ++ uint32_t insn = dec->insn; ++ dec->codec = opcode_data[dec->op].codec; ++ switch (dec->codec) { ++ case la_codec_illegal: ++ case la_codec_empty: ++ break; ++ case la_codec_2r: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ break; ++ case la_codec_2r_u5: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ break; ++ case la_codec_2r_u6: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_u6(insn); ++ break; ++ case la_codec_2r_2bw: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_bw1(insn); ++ dec->r4 = operand_bw2(insn); ++ break; ++ case la_codec_2r_2bd: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_bd1(insn); ++ dec->r4 = operand_bd2(insn); ++ break; ++ case la_codec_3r: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ break; ++ case la_codec_3r_rd0: ++ dec->r1 = 0; ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ break; ++ case la_codec_3r_sa2: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ dec->r4 = operand_sa2(insn); ++ break; ++ case la_codec_3r_sa3: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ dec->r4 = operand_sa3(insn); ++ break; ++ case la_codec_4r: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ dec->r4 = operand_r4(insn); ++ break; ++ case la_codec_r_im20: ++ dec->r1 = operand_r1(insn); ++ dec->imm = operand_im20(insn); ++ dec->bit = IM_20; ++ break; ++ case la_codec_2r_im16: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->imm = operand_im16(insn); ++ dec->bit = IM_16; ++ break; ++ case la_codec_2r_im14: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->imm = operand_im14(insn); ++ dec->bit = IM_14; ++ break; ++ case la_codec_im5_r_im12: ++ dec->imm2 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->imm = operand_im12(insn); ++ dec->bit = IM_12; ++ break; ++ case la_codec_2r_im12: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->imm = operand_im12(insn); ++ dec->bit = IM_12; ++ break; ++ case la_codec_2r_im8: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->imm = operand_im8(insn); ++ dec->bit = IM_8; ++ break; ++ case la_codec_r_sd: ++ dec->r1 = operand_sd(insn); ++ dec->r2 = operand_r2(insn); ++ break; ++ case la_codec_r_sj: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_sj(insn); ++ break; ++ case la_codec_r_cd: ++ dec->r1 = operand_cd(insn); ++ dec->r2 = operand_r2(insn); ++ break; ++ case la_codec_r_cj: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_cj(insn); ++ break; ++ case la_codec_r_seq: ++ dec->r1 = 0; ++ dec->r2 = operand_r1(insn); ++ dec->imm = operand_im8(insn); ++ dec->bit = IM_8; ++ break; ++ case la_codec_code: ++ dec->code = operand_code(insn); ++ break; ++ case la_codec_whint: ++ dec->imm = operand_whint(insn); ++ dec->bit = IM_15; ++ break; ++ case la_codec_invtlb: ++ dec->imm = operand_invop(insn); ++ dec->bit = IM_5; ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ break; ++ case la_codec_r_ofs21: ++ dec->imm = operand_ofs21(insn); ++ dec->bit = IM_21; ++ dec->r2 = operand_r2(insn); ++ break; ++ case la_codec_cj_ofs21: ++ dec->imm = operand_ofs21(insn); ++ dec->bit = IM_21; ++ dec->r2 = operand_cj(insn); ++ break; ++ case la_codec_ofs26: ++ dec->imm = operand_ofs26(insn); ++ dec->bit = IM_26; ++ break; ++ case la_codec_cond: ++ dec->r1 = operand_cd(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ dec->r4 = operand_fcond(insn); ++ break; ++ case la_codec_sel: ++ dec->r1 = operand_r1(insn); ++ dec->r2 = operand_r2(insn); ++ dec->r3 = operand_r3(insn); ++ dec->r4 = operand_sel(insn); ++ break; ++ } ++} ++ ++/* format instruction */ ++ ++static void append(char *s1, const char *s2, size_t n) ++{ ++ size_t l1 = strlen(s1); ++ if (n - l1 - 1 > 0) { ++ strncat(s1, s2, n - l1); ++ } ++} ++ ++static void format_insn(char *buf, size_t buflen, size_t tab, la_decode *dec) ++{ ++ char tmp[16]; ++ const char *fmt; ++ ++ fmt = opcode_data[dec->op].format; ++ while (*fmt) { ++ switch (*fmt) { ++ case 'n': /* name */ ++ append(buf, opcode_data[dec->op].name, buflen); ++ break; ++ case 's': ++ append(buf, "s", buflen); ++ break; ++ case 'd': ++ append(buf, "d", buflen); ++ break; ++ case 'e': /* illegal */ ++ snprintf(tmp, sizeof(tmp), "%x", dec->insn); ++ append(buf, tmp, buflen); ++ break; ++ case 't': ++ while (strlen(buf) < tab) { ++ append(buf, " ", buflen); ++ } ++ break; ++ case '(': ++ append(buf, "(", buflen); ++ break; ++ case ',': ++ append(buf, ",", buflen); ++ break; ++ case '.': ++ append(buf, ".", buflen); ++ break; ++ case ')': ++ append(buf, ")", buflen); ++ break; ++ case '0': /* rd */ ++ append(buf, loongarch_r_normal_name[dec->r1], buflen); ++ break; ++ case '1': /* rj */ ++ append(buf, loongarch_r_normal_name[dec->r2], buflen); ++ break; ++ case '2': /* rk */ ++ append(buf, loongarch_r_normal_name[dec->r3], buflen); ++ break; ++ case '3': /* fd */ ++ append(buf, loongarch_f_normal_name[dec->r1], buflen); ++ break; ++ case '4': /* fj */ ++ append(buf, loongarch_f_normal_name[dec->r2], buflen); ++ break; ++ case '5': /* fk */ ++ append(buf, loongarch_f_normal_name[dec->r3], buflen); ++ break; ++ case '6': /* fa */ ++ append(buf, loongarch_f_normal_name[dec->r4], buflen); ++ break; ++ case 'A': /* sd */ ++ append(buf, loongarch_cr_normal_name[dec->r1], buflen); ++ break; ++ case 'B': /* sj */ ++ append(buf, loongarch_cr_normal_name[dec->r2], buflen); ++ break; ++ case 'C': /* r3 */ ++ snprintf(tmp, sizeof(tmp), "%x", dec->r3); ++ append(buf, tmp, buflen); ++ break; ++ case 'D': /* r4 */ ++ snprintf(tmp, sizeof(tmp), "%x", dec->r4); ++ append(buf, tmp, buflen); ++ break; ++ case 'E': /* r1 */ ++ snprintf(tmp, sizeof(tmp), "%x", dec->r1); ++ append(buf, tmp, buflen); ++ break; ++ case 'F': /* fcsrd */ ++ append(buf, loongarch_r_normal_name[dec->r1], buflen); ++ break; ++ case 'G': /* fcsrs */ ++ append(buf, loongarch_r_normal_name[dec->r2], buflen); ++ break; ++ case 'H': /* cd */ ++ append(buf, loongarch_c_normal_name[dec->r1], buflen); ++ break; ++ case 'I': /* cj */ ++ append(buf, loongarch_c_normal_name[dec->r2], buflen); ++ break; ++ case 'J': /* code */ ++ snprintf(tmp, sizeof(tmp), "0x%x", dec->code); ++ append(buf, tmp, buflen); ++ break; ++ case 'K': /* cond */ ++ switch (dec->r4) { ++ case 0x0: ++ append(buf, "caf", buflen); ++ break; ++ case 0x1: ++ append(buf, "saf", buflen); ++ break; ++ case 0x2: ++ append(buf, "clt", buflen); ++ break; ++ case 0x3: ++ append(buf, "slt", buflen); ++ break; ++ case 0x4: ++ append(buf, "ceq", buflen); ++ break; ++ case 0x5: ++ append(buf, "seq", buflen); ++ break; ++ case 0x6: ++ append(buf, "cle", buflen); ++ break; ++ case 0x7: ++ append(buf, "sle", buflen); ++ break; ++ case 0x8: ++ append(buf, "cun", buflen); ++ break; ++ case 0x9: ++ append(buf, "sun", buflen); ++ break; ++ case 0xA: ++ append(buf, "cult", buflen); ++ break; ++ case 0xB: ++ append(buf, "sult", buflen); ++ break; ++ case 0xC: ++ append(buf, "cueq", buflen); ++ break; ++ case 0xD: ++ append(buf, "sueq", buflen); ++ break; ++ case 0xE: ++ append(buf, "cule", buflen); ++ break; ++ case 0xF: ++ append(buf, "sule", buflen); ++ break; ++ case 0x10: ++ append(buf, "cne", buflen); ++ break; ++ case 0x11: ++ append(buf, "sne", buflen); ++ break; ++ case 0x14: ++ append(buf, "cor", buflen); ++ break; ++ case 0x15: ++ append(buf, "sor", buflen); ++ break; ++ case 0x18: ++ append(buf, "cune", buflen); ++ break; ++ case 0x19: ++ append(buf, "sune", buflen); ++ break; ++ } ++ break; ++ case 'L': /* ca */ ++ append(buf, loongarch_c_normal_name[dec->r4], buflen); ++ break; ++ case 'M': /* cop */ ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm2) & 0x1f); ++ append(buf, tmp, buflen); ++ break; ++ case 'i': /* sixx d */ ++ snprintf(tmp, sizeof(tmp), "%d", dec->imm); ++ append(buf, tmp, buflen); ++ break; ++ case 'o': /* offset */ ++ snprintf(tmp, sizeof(tmp), "%d", (dec->imm) << 2); ++ append(buf, tmp, buflen); ++ break; ++ case 'x': /* sixx x */ ++ switch (dec->bit) { ++ case IM_5: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x1f); ++ append(buf, tmp, buflen); ++ break; ++ case IM_8: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_12: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xfff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_14: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x3fff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_15: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x7fff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_16: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xffff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_20: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xfffff); ++ append(buf, tmp, buflen); ++ break; ++ default: ++ snprintf(tmp, sizeof(tmp), "0x%x", dec->imm); ++ append(buf, tmp, buflen); ++ break; ++ } ++ break; ++ case 'X': /* offset x*/ ++ switch (dec->bit) { ++ case IM_16: ++ snprintf(tmp, sizeof(tmp), "0x%x", ++ ((dec->imm) << 2) & 0xffff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_21: ++ snprintf(tmp, sizeof(tmp), "0x%x", ++ ((dec->imm) << 2) & 0x1fffff); ++ append(buf, tmp, buflen); ++ break; ++ case IM_26: ++ snprintf(tmp, sizeof(tmp), "0x%x", ++ ((dec->imm) << 2) & 0x3ffffff); ++ append(buf, tmp, buflen); ++ break; ++ default: ++ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) << 2); ++ append(buf, tmp, buflen); ++ break; ++ } ++ break; ++ case 'p': /* pc */ ++ snprintf(tmp, sizeof(tmp), " # 0x%"PRIx32"", ++ dec->pc + ((dec->imm) << 2)); ++ append(buf, tmp, buflen); ++ break; ++ default: ++ break; ++ } ++ fmt++; ++ } ++} ++ ++ ++/* disassemble instruction */ ++ ++static void ++disasm_insn(char *buf, size_t buflen, bfd_vma pc, unsigned long int insn) ++{ ++ la_decode dec = { 0 }; ++ dec.pc = pc; ++ dec.insn = insn; ++ decode_insn_opcode(&dec); ++ decode_insn_operands(&dec); ++ format_insn(buf, buflen, 16, &dec); ++} ++ ++int ++print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info) ++{ ++ char buf[128] = { 0 }; ++ bfd_byte buffer[INSNLEN]; ++ unsigned long insn; ++ int status; ++ ++ status = (*info->read_memory_func)(memaddr, buffer, INSNLEN, info); ++ if (status == 0) { ++ insn = (uint32_t) bfd_getl32(buffer); ++ (*info->fprintf_func)(info->stream, "%08" PRIx64 " ", insn); ++ } else { ++ (*info->memory_error_func)(status, memaddr, info); ++ return -1; ++ } ++ disasm_insn(buf, sizeof(buf), memaddr, insn); ++ (*info->fprintf_func)(info->stream, "\t%s", buf); ++ return INSNLEN; ++} +diff --git a/disas/meson.build b/disas/meson.build +index 5c5daa69a..378287b21 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')) ++loongarch_ss.add(when: 'CONFIG_LOONGARCH_DIS', if_true: files('loongarch.c')) + common_ss.add(when: 'CONFIG_NANOMIPS_DIS', if_true: files('nanomips.cpp')) + common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c')) + common_ss.add(when: 'CONFIG_PPC_DIS', if_true: files('ppc.c')) +diff --git a/gdb-xml/loongarch-base32.xml b/gdb-xml/loongarch-base32.xml +new file mode 100644 +index 000000000..04891e023 +--- /dev/null ++++ b/gdb-xml/loongarch-base32.xml +@@ -0,0 +1,43 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb-xml/loongarch-base64.xml b/gdb-xml/loongarch-base64.xml +new file mode 100644 +index 000000000..6308fb6ec +--- /dev/null ++++ b/gdb-xml/loongarch-base64.xml +@@ -0,0 +1,43 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb-xml/loongarch-fpu32.xml b/gdb-xml/loongarch-fpu32.xml +new file mode 100644 +index 000000000..a5b4d80e6 +--- /dev/null ++++ b/gdb-xml/loongarch-fpu32.xml +@@ -0,0 +1,52 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb-xml/loongarch-fpu64.xml b/gdb-xml/loongarch-fpu64.xml +new file mode 100644 +index 000000000..74ab55a01 +--- /dev/null ++++ b/gdb-xml/loongarch-fpu64.xml +@@ -0,0 +1,57 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.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 00000000..0f02e9f3 --- /dev/null +++ b/Add-linux-headers-and-linux-user.patch @@ -0,0 +1,1654 @@ +From 291f6d80e971ed85da7c5e00387c7fb1b25743f8 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Wed, 7 Dec 2022 04:35:07 -0500 +Subject: [PATCH 05/11] Add linux-headers and linux-user. + +Signed-off-by: lixianglai +--- + linux-headers/asm-loongarch64/bitsperlong.h | 9 + + linux-headers/asm-loongarch64/kvm.h | 338 ++++++++++++++++++++ + linux-headers/asm-loongarch64/sgidefs.h | 20 ++ + linux-headers/asm-loongarch64/unistd.h | 23 ++ + linux-user/loongarch64/cpu_loop.c | 193 +++++++++++ + linux-user/loongarch64/meson.build | 6 + + linux-user/loongarch64/signal.c | 212 ++++++++++++ + linux-user/loongarch64/sockbits.h | 1 + + linux-user/loongarch64/syscall_nr.h | 287 +++++++++++++++++ + linux-user/loongarch64/target_cpu.h | 45 +++ + linux-user/loongarch64/target_elf.h | 14 + + linux-user/loongarch64/target_fcntl.h | 13 + + linux-user/loongarch64/target_signal.h | 23 ++ + linux-user/loongarch64/target_structs.h | 62 ++++ + linux-user/loongarch64/target_syscall.h | 44 +++ + linux-user/loongarch64/termbits.h | 224 +++++++++++++ + 16 files changed, 1514 insertions(+) + create mode 100644 linux-headers/asm-loongarch64/bitsperlong.h + create mode 100644 linux-headers/asm-loongarch64/kvm.h + create mode 100644 linux-headers/asm-loongarch64/sgidefs.h + create mode 100644 linux-headers/asm-loongarch64/unistd.h + create mode 100644 linux-user/loongarch64/cpu_loop.c + create mode 100644 linux-user/loongarch64/meson.build + create mode 100644 linux-user/loongarch64/signal.c + create mode 100644 linux-user/loongarch64/sockbits.h + create mode 100644 linux-user/loongarch64/syscall_nr.h + create mode 100644 linux-user/loongarch64/target_cpu.h + create mode 100644 linux-user/loongarch64/target_elf.h + create mode 100644 linux-user/loongarch64/target_fcntl.h + create mode 100644 linux-user/loongarch64/target_signal.h + create mode 100644 linux-user/loongarch64/target_structs.h + create mode 100644 linux-user/loongarch64/target_syscall.h + create mode 100644 linux-user/loongarch64/termbits.h + +diff --git a/linux-headers/asm-loongarch64/bitsperlong.h b/linux-headers/asm-loongarch64/bitsperlong.h +new file mode 100644 +index 000000000..5c2c8779a +--- /dev/null ++++ b/linux-headers/asm-loongarch64/bitsperlong.h +@@ -0,0 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++#ifndef __ASM_LOONGARCH_BITSPERLONG_H ++#define __ASM_LOONGARCH_BITSPERLONG_H ++ ++#define __BITS_PER_LONG _LOONGARCH_SZLONG ++ ++#include ++ ++#endif /* __ASM_LOONGARCH_BITSPERLONG_H */ +diff --git a/linux-headers/asm-loongarch64/kvm.h b/linux-headers/asm-loongarch64/kvm.h +new file mode 100644 +index 000000000..799af7594 +--- /dev/null ++++ b/linux-headers/asm-loongarch64/kvm.h +@@ -0,0 +1,338 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2020 Loongson Technologies, Inc. All rights reserved. ++ * Authors: Sanjay Lal ++ * Authors: Xing Li ++ */ ++ ++#ifndef __LINUX_KVM_LOONGARCH_H ++#define __LINUX_KVM_LOONGARCH_H ++ ++#include ++ ++#define __KVM_HAVE_GUEST_DEBUG ++#define KVM_GUESTDBG_USE_SW_BP 0x00010000 ++#define KVM_GUESTDBG_USE_HW_BP 0x00020000 ++#define KVM_DATA_HW_BREAKPOINT_NUM 8 ++#define KVM_INST_HW_BREAKPOINT_NUM 8 ++ ++/* ++ * KVM Loongarch specific structures and definitions. ++ * ++ * Some parts derived from the x86 version of this file. ++ */ ++ ++#define __KVM_HAVE_READONLY_MEM ++ ++#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 ++ ++#define KVM_LARCH_VCPU_PVTIME_CTRL 2 ++#define KVM_LARCH_VCPU_PVTIME_IPA 0 ++ ++/* ++ * for KVM_GET_REGS and KVM_SET_REGS ++ */ ++struct kvm_regs { ++ /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */ ++ __u64 gpr[32]; ++ __u64 pc; ++}; ++ ++/* ++ * for KVM_GET_CPUCFG ++ */ ++struct kvm_cpucfg { ++ /* out (KVM_GET_CPUCFG) */ ++ __u32 cpucfg[64]; ++}; ++ ++/* ++ * for KVM_GET_FPU and KVM_SET_FPU ++ */ ++struct kvm_fpu { ++ __u32 fcsr; ++ __u32 vcsr; ++ __u64 fcc; /* 8x8 */ ++ struct kvm_fpureg { ++ __u64 val64[4]; //support max 256 bits ++ }fpr[32]; ++}; ++ ++/* ++ * For LOONGARCH, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various ++ * registers. The id field is broken down as follows: ++ * ++ * bits[63..52] - As per linux/kvm.h ++ * bits[51..32] - Must be zero. ++ * bits[31..16] - Register set. ++ * ++ * Register set = 0: GP registers from kvm_regs (see definitions below). ++ * ++ * Register set = 1: 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 000000000..b80960834 +--- /dev/null ++++ b/linux-headers/asm-loongarch64/sgidefs.h +@@ -0,0 +1,20 @@ ++/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ ++/* ++* Copyright (C) 2020 Loongson Technology Corporation Limited ++* ++* Author: Hanlu Li ++*/ ++#ifndef __ASM_SGIDEFS_H ++#define __ASM_SGIDEFS_H ++ ++#define _LOONGARCH_ISA_LOONGARCH32 6 ++#define _LOONGARCH_ISA_LOONGARCH64 7 ++ ++/* ++ * Subprogram calling convention ++ */ ++#define _LOONGARCH_SIM_ABILP32 1 ++#define _LOONGARCH_SIM_ABILPX32 2 ++#define _LOONGARCH_SIM_ABILP64 3 ++ ++#endif /* __ASM_SGIDEFS_H */ +diff --git a/linux-headers/asm-loongarch64/unistd.h b/linux-headers/asm-loongarch64/unistd.h +new file mode 100644 +index 000000000..2a6014562 +--- /dev/null ++++ b/linux-headers/asm-loongarch64/unistd.h +@@ -0,0 +1,23 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ * ++ * Copyright (C) 2020 Loongson Technologies, Inc. ++ * Authors: Jun Yi ++ */ ++ ++#ifdef __LP64__ ++#define __ARCH_WANT_NEW_STAT ++#endif /* __LP64__ */ ++ ++#include +diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c +new file mode 100644 +index 000000000..6d4093e1d +--- /dev/null ++++ b/linux-user/loongarch64/cpu_loop.c +@@ -0,0 +1,193 @@ ++/* ++ * qemu user cpu loop ++ * ++ * Copyright (c) 2003-2008 Fabrice Bellard ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#include "qemu/osdep.h" ++#include "qemu.h" ++#include "cpu_loop-common.h" ++#include "elf.h" ++ ++/* Break codes */ ++enum { ++ BRK_OVERFLOW = 6, ++ BRK_DIVZERO = 7 ++}; ++ ++static int do_break(CPULOONGARCHState *env, target_siginfo_t *info, ++ unsigned int code) ++{ ++ int ret = -1; ++ ++ switch (code) { ++ case BRK_OVERFLOW: ++ case BRK_DIVZERO: ++ info->si_signo = TARGET_SIGFPE; ++ info->si_errno = 0; ++ info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV; ++ queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info); ++ ret = 0; ++ break; ++ default: ++ info->si_signo = TARGET_SIGTRAP; ++ info->si_errno = 0; ++ queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info); ++ ret = 0; ++ break; ++ } ++ ++ return ret; ++} ++ ++void cpu_loop(CPULOONGARCHState *env) ++{ ++ CPUState *cs = CPU(loongarch_env_get_cpu(env)); ++ target_siginfo_t info; ++ int trapnr; ++ abi_long ret; ++ ++ for (;;) { ++ cpu_exec_start(cs); ++ trapnr = cpu_exec(cs); ++ cpu_exec_end(cs); ++ process_queued_cpu_work(cs); ++ ++ switch (trapnr) { ++ case EXCP_SYSCALL: ++ env->active_tc.PC += 4; ++ ret = do_syscall(env, env->active_tc.gpr[11], ++ env->active_tc.gpr[4], env->active_tc.gpr[5], ++ env->active_tc.gpr[6], env->active_tc.gpr[7], ++ env->active_tc.gpr[8], env->active_tc.gpr[9], ++ -1, -1); ++ if (ret == -TARGET_ERESTARTSYS) { ++ env->active_tc.PC -= 4; ++ break; ++ } ++ if (ret == -TARGET_QEMU_ESIGRETURN) { ++ /* Returning from a successful sigreturn syscall. ++ Avoid clobbering register state. */ ++ break; ++ } ++ env->active_tc.gpr[4] = ret; ++ break; ++ case EXCP_TLBL: ++ case EXCP_TLBS: ++ case EXCP_AdEL: ++ case EXCP_AdES: ++ info.si_signo = TARGET_SIGSEGV; ++ info.si_errno = 0; ++ /* XXX: check env->error_code */ ++ info.si_code = TARGET_SEGV_MAPERR; ++ info._sifields._sigfault._addr = env->CSR_BADV; ++ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); ++ break; ++ case EXCP_FPDIS: ++ case EXCP_LSXDIS: ++ case EXCP_LASXDIS: ++ case EXCP_RI: ++ info.si_signo = TARGET_SIGILL; ++ info.si_errno = 0; ++ info.si_code = 0; ++ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); ++ break; ++ case EXCP_INTERRUPT: ++ /* just indicate that signals should be handled asap */ ++ break; ++ case EXCP_DEBUG: ++ info.si_signo = TARGET_SIGTRAP; ++ info.si_errno = 0; ++ info.si_code = TARGET_TRAP_BRKPT; ++ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); ++ break; ++ case EXCP_FPE: ++ info.si_signo = TARGET_SIGFPE; ++ info.si_errno = 0; ++ info.si_code = TARGET_FPE_FLTUNK; ++ if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_INVALID) { ++ info.si_code = TARGET_FPE_FLTINV; ++ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_DIV0) { ++ info.si_code = TARGET_FPE_FLTDIV; ++ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_OVERFLOW) { ++ info.si_code = TARGET_FPE_FLTOVF; ++ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_UNDERFLOW) { ++ info.si_code = TARGET_FPE_FLTUND; ++ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_INEXACT) { ++ info.si_code = TARGET_FPE_FLTRES; ++ } ++ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); ++ break; ++ case EXCP_BREAK: ++ { ++ abi_ulong trap_instr; ++ unsigned int code; ++ ++ ret = get_user_u32(trap_instr, env->active_tc.PC); ++ if (ret != 0) { ++ goto error; ++ } ++ ++ code = trap_instr & 0x7fff; ++ ++ if (do_break(env, &info, code) != 0) { ++ goto error; ++ } ++ } ++ break; ++ case EXCP_TRAP: ++ { ++ abi_ulong trap_instr; ++ unsigned int code = 0; ++ ++ ret = get_user_u32(trap_instr, env->active_tc.PC); ++ ++ if (ret != 0) { ++ goto error; ++ } ++ ++ /* The immediate versions don't provide a code. */ ++ if (!(trap_instr & 0xFC000000)) { ++ code = ((trap_instr >> 6) & ((1 << 10) - 1)); ++ } ++ ++ if (do_break(env, &info, code) != 0) { ++ goto error; ++ } ++ } ++ break; ++ case EXCP_ATOMIC: ++ cpu_exec_step_atomic(cs); ++ break; ++ default: ++error: ++ printf("111111\n"); ++ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr); ++ abort(); ++ } ++ process_pending_signals(env); ++ } ++} ++ ++void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) ++{ ++ int i; ++ ++ for (i = 0; i < 32; i++) { ++ env->active_tc.gpr[i] = regs->regs[i]; ++ } ++ env->active_tc.PC = regs->csr_era & ~(target_ulong)1; ++} +diff --git a/linux-user/loongarch64/meson.build b/linux-user/loongarch64/meson.build +new file mode 100644 +index 000000000..c4c0b4d70 +--- /dev/null ++++ b/linux-user/loongarch64/meson.build +@@ -0,0 +1,6 @@ ++syscall_nr_generators += { ++ 'loongarch64': generator(sh, ++ arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@', ++ '', 'TARGET_SYSCALL_OFFSET' ], ++ output: '@BASENAME@_nr.h') ++} +diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c +new file mode 100644 +index 000000000..6fe685275 +--- /dev/null ++++ b/linux-user/loongarch64/signal.c +@@ -0,0 +1,212 @@ ++/* ++ * Emulation of Linux signals ++ * ++ * Copyright (c) 2003 Fabrice Bellard ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++#include "qemu/osdep.h" ++#include "qemu.h" ++#include "signal-common.h" ++#include "linux-user/trace.h" ++ ++#define FPU_REG_WIDTH 256 ++union fpureg { ++ uint32_t val32[FPU_REG_WIDTH / 32]; ++ uint64_t val64[FPU_REG_WIDTH / 64]; ++}; ++ ++struct target_sigcontext { ++ uint64_t sc_pc; ++ uint64_t sc_regs[32]; ++ uint32_t sc_flags; ++ ++ uint32_t sc_fcsr; ++ uint32_t sc_vcsr; ++ uint64_t sc_fcc; ++ union fpureg sc_fpregs[32] __attribute__((aligned(32))); ++ ++ uint32_t sc_reserved; ++ ++}; ++ ++struct sigframe { ++ uint32_t sf_ass[4]; /* argument save space for o32 */ ++ uint32_t sf_code[2]; /* signal trampoline */ ++ struct target_sigcontext sf_sc; ++ target_sigset_t sf_mask; ++}; ++ ++struct target_ucontext { ++ target_ulong tuc_flags; ++ target_ulong tuc_link; ++ target_stack_t tuc_stack; ++ target_ulong pad0; ++ struct target_sigcontext tuc_mcontext; ++ target_sigset_t tuc_sigmask; ++}; ++ ++struct target_rt_sigframe { ++ uint32_t rs_ass[4]; /* argument save space for o32 */ ++ uint32_t rs_code[2]; /* signal trampoline */ ++ struct target_siginfo rs_info; ++ struct target_ucontext rs_uc; ++}; ++ ++static inline void setup_sigcontext(CPULOONGARCHState *regs, ++ struct target_sigcontext *sc) ++{ ++ int i; ++ ++ __put_user(exception_resume_pc(regs), &sc->sc_pc); ++ regs->hflags &= ~LARCH_HFLAG_BMASK; ++ ++ __put_user(0, &sc->sc_regs[0]); ++ for (i = 1; i < 32; ++i) { ++ __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); ++ } ++ ++ for (i = 0; i < 32; ++i) { ++ __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i].val64[0]); ++ } ++} ++ ++static inline void ++restore_sigcontext(CPULOONGARCHState *regs, struct target_sigcontext *sc) ++{ ++ int i; ++ ++ __get_user(regs->CSR_ERA, &sc->sc_pc); ++ ++ for (i = 1; i < 32; ++i) { ++ __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); ++ } ++ ++ for (i = 0; i < 32; ++i) { ++ __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i].val64[0]); ++ } ++} ++ ++/* ++ * Determine which stack to use.. ++ */ ++static inline abi_ulong ++get_sigframe(struct target_sigaction *ka, CPULOONGARCHState *regs, ++ size_t frame_size) ++{ ++ unsigned long sp; ++ ++ /* ++ * FPU emulator may have its own trampoline active just ++ * above the user stack, 16-bytes before the next lowest ++ * 16 byte boundary. Try to avoid trashing it. ++ */ ++ sp = target_sigsp(get_sp_from_cpustate(regs) - 32, ka); ++ ++ return (sp - frame_size) & ~7; ++} ++ ++void setup_rt_frame(int sig, struct target_sigaction *ka, ++ target_siginfo_t *info, ++ target_sigset_t *set, CPULOONGARCHState *env) ++{ ++ struct target_rt_sigframe *frame; ++ abi_ulong frame_addr; ++ int i; ++ ++ frame_addr = get_sigframe(ka, env, sizeof(*frame)); ++ trace_user_setup_rt_frame(env, frame_addr); ++ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { ++ goto give_sigsegv; ++ } ++ ++ /* ori a7, $r0, TARGET_NR_rt_sigreturn */ ++ /* syscall 0 */ ++ __put_user(0x0380000b + (TARGET_NR_rt_sigreturn << 10), &frame->rs_code[0]); ++ __put_user(0x002b0000, &frame->rs_code[1]); ++ ++ tswap_siginfo(&frame->rs_info, info); ++ ++ __put_user(0, &frame->rs_uc.tuc_flags); ++ __put_user(0, &frame->rs_uc.tuc_link); ++ target_save_altstack(&frame->rs_uc.tuc_stack, env); ++ ++ setup_sigcontext(env, &frame->rs_uc.tuc_mcontext); ++ ++ for (i = 0; i < TARGET_NSIG_WORDS; i++) { ++ __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]); ++ } ++ ++ /* ++ * Arguments to signal handler: ++ * ++ * a0 = signal number ++ * a1 = pointer to siginfo_t ++ * a2 = pointer to ucontext_t ++ * ++ * $25 and PC point to the signal handler, $29 points to the ++ * struct sigframe. ++ */ ++ env->active_tc.gpr[4] = sig; ++ env->active_tc.gpr[5] = frame_addr ++ + offsetof(struct target_rt_sigframe, rs_info); ++ env->active_tc.gpr[6] = frame_addr ++ + offsetof(struct target_rt_sigframe, rs_uc); ++ env->active_tc.gpr[3] = frame_addr; ++ env->active_tc.gpr[1] = frame_addr ++ + offsetof(struct target_rt_sigframe, rs_code); ++ /* The original kernel code sets CP0_ERA to the handler ++ * since it returns to userland using ertn ++ * we cannot do this here, and we must set PC directly */ ++ env->active_tc.PC = env->active_tc.gpr[20] = ka->_sa_handler; ++ unlock_user_struct(frame, frame_addr, 1); ++ return; ++ ++give_sigsegv: ++ unlock_user_struct(frame, frame_addr, 1); ++ force_sigsegv(sig); ++} ++ ++long do_rt_sigreturn(CPULOONGARCHState *env) ++{ ++ struct target_rt_sigframe *frame; ++ abi_ulong frame_addr; ++ sigset_t blocked; ++ ++ frame_addr = env->active_tc.gpr[3]; ++ trace_user_do_rt_sigreturn(env, frame_addr); ++ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { ++ goto badframe; ++ } ++ ++ target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask); ++ set_sigmask(&blocked); ++ ++ restore_sigcontext(env, &frame->rs_uc.tuc_mcontext); ++ ++ if (do_sigaltstack(frame_addr + ++ offsetof(struct target_rt_sigframe, rs_uc.tuc_stack), ++ 0, get_sp_from_cpustate(env)) == -EFAULT) ++ goto badframe; ++ ++ env->active_tc.PC = env->CSR_ERA; ++ /* I am not sure this is right, but it seems to work ++ * maybe a problem with nested signals ? */ ++ env->CSR_ERA = 0; ++ return -TARGET_QEMU_ESIGRETURN; ++ ++badframe: ++ force_sig(TARGET_SIGSEGV); ++ return -TARGET_QEMU_ESIGRETURN; ++} +diff --git a/linux-user/loongarch64/sockbits.h b/linux-user/loongarch64/sockbits.h +new file mode 100644 +index 000000000..0e4c8f012 +--- /dev/null ++++ b/linux-user/loongarch64/sockbits.h +@@ -0,0 +1 @@ ++#include "../generic/sockbits.h" +diff --git a/linux-user/loongarch64/syscall_nr.h b/linux-user/loongarch64/syscall_nr.h +new file mode 100644 +index 000000000..a30aca8d8 +--- /dev/null ++++ b/linux-user/loongarch64/syscall_nr.h +@@ -0,0 +1,287 @@ ++#ifndef LINUX_USER_LOONGARCH_SYSCALL_NR_H ++#define LINUX_USER_LOONGARCH_SYSCALL_NR_H ++ ++#define TARGET_NR_io_setup 0 ++#define TARGET_NR_io_destroy 1 ++#define TARGET_NR_io_submit 2 ++#define TARGET_NR_io_cancel 3 ++#define TARGET_NR_io_getevents 4 ++#define TARGET_NR_setxattr 5 ++#define TARGET_NR_lsetxattr 6 ++#define TARGET_NR_fsetxattr 7 ++#define TARGET_NR_getxattr 8 ++#define TARGET_NR_lgetxattr 9 ++#define TARGET_NR_fgetxattr 10 ++#define TARGET_NR_listxattr 11 ++#define TARGET_NR_llistxattr 12 ++#define TARGET_NR_flistxattr 13 ++#define TARGET_NR_removexattr 14 ++#define TARGET_NR_lremovexattr 15 ++#define TARGET_NR_fremovexattr 16 ++#define TARGET_NR_getcwd 17 ++#define TARGET_NR_lookup_dcookie 18 ++#define TARGET_NR_eventfd2 19 ++#define TARGET_NR_epoll_create1 20 ++#define TARGET_NR_epoll_ctl 21 ++#define TARGET_NR_epoll_pwait 22 ++#define TARGET_NR_dup 23 ++#define TARGET_NR_dup3 24 ++#define TARGET_NR_fcntl 25 ++#define TARGET_NR_inotify_init1 26 ++#define TARGET_NR_inotify_add_watch 27 ++#define TARGET_NR_inotify_rm_watch 28 ++#define TARGET_NR_ioctl 29 ++#define TARGET_NR_ioprio_set 30 ++#define TARGET_NR_ioprio_get 31 ++#define TARGET_NR_flock 32 ++#define TARGET_NR_mknodat 33 ++#define TARGET_NR_mkdirat 34 ++#define TARGET_NR_unlinkat 35 ++#define TARGET_NR_symlinkat 36 ++#define TARGET_NR_linkat 37 ++#define TARGET_NR_renameat 38 ++#define TARGET_NR_umount2 39 ++#define TARGET_NR_mount 40 ++#define TARGET_NR_pivot_root 41 ++#define TARGET_NR_nfsservctl 42 ++#define TARGET_NR_statfs 43 ++#define TARGET_NR_fstatfs 44 ++#define TARGET_NR_truncate 45 ++#define TARGET_NR_ftruncate 46 ++#define TARGET_NR_fallocate 47 ++#define TARGET_NR_faccessat 48 ++#define TARGET_NR_chdir 49 ++#define TARGET_NR_fchdir 50 ++#define TARGET_NR_chroot 51 ++#define TARGET_NR_fchmod 52 ++#define TARGET_NR_fchmodat 53 ++#define TARGET_NR_fchownat 54 ++#define TARGET_NR_fchown 55 ++#define TARGET_NR_openat 56 ++#define TARGET_NR_close 57 ++#define TARGET_NR_vhangup 58 ++#define TARGET_NR_pipe2 59 ++#define TARGET_NR_quotactl 60 ++#define TARGET_NR_getdents64 61 ++#define TARGET_NR_lseek 62 ++#define TARGET_NR_read 63 ++#define TARGET_NR_write 64 ++#define TARGET_NR_readv 65 ++#define TARGET_NR_writev 66 ++#define TARGET_NR_pread64 67 ++#define TARGET_NR_pwrite64 68 ++#define TARGET_NR_preadv 69 ++#define TARGET_NR_pwritev 70 ++#define TARGET_NR_sendfile 71 ++#define TARGET_NR_pselect6 72 ++#define TARGET_NR_ppoll 73 ++#define TARGET_NR_signalfd4 74 ++#define TARGET_NR_vmsplice 75 ++#define TARGET_NR_splice 76 ++#define TARGET_NR_tee 77 ++#define TARGET_NR_readlinkat 78 ++#define TARGET_NR_newfstatat 79 ++#define TARGET_NR_fstat 80 ++#define TARGET_NR_sync 81 ++#define TARGET_NR_fsync 82 ++#define TARGET_NR_fdatasync 83 ++#define TARGET_NR_sync_file_range 84 ++#define TARGET_NR_timerfd_create 85 ++#define TARGET_NR_timerfd_settime 86 ++#define TARGET_NR_timerfd_gettime 87 ++#define TARGET_NR_utimensat 88 ++#define TARGET_NR_acct 89 ++#define TARGET_NR_capget 90 ++#define TARGET_NR_capset 91 ++#define TARGET_NR_personality 92 ++#define TARGET_NR_exit 93 ++#define TARGET_NR_exit_group 94 ++#define TARGET_NR_waitid 95 ++#define TARGET_NR_set_tid_address 96 ++#define TARGET_NR_unshare 97 ++#define TARGET_NR_futex 98 ++#define TARGET_NR_set_robust_list 99 ++#define TARGET_NR_get_robust_list 100 ++#define TARGET_NR_nanosleep 101 ++#define TARGET_NR_getitimer 102 ++#define TARGET_NR_setitimer 103 ++#define TARGET_NR_kexec_load 104 ++#define TARGET_NR_init_module 105 ++#define TARGET_NR_delete_module 106 ++#define TARGET_NR_timer_create 107 ++#define TARGET_NR_timer_gettime 108 ++#define TARGET_NR_timer_getoverrun 109 ++#define TARGET_NR_timer_settime 110 ++#define TARGET_NR_timer_delete 111 ++#define TARGET_NR_clock_settime 112 ++#define TARGET_NR_clock_gettime 113 ++#define TARGET_NR_clock_getres 114 ++#define TARGET_NR_clock_nanosleep 115 ++#define TARGET_NR_syslog 116 ++#define TARGET_NR_ptrace 117 ++#define TARGET_NR_sched_setparam 118 ++#define TARGET_NR_sched_setscheduler 119 ++#define TARGET_NR_sched_getscheduler 120 ++#define TARGET_NR_sched_getparam 121 ++#define TARGET_NR_sched_setaffinity 122 ++#define TARGET_NR_sched_getaffinity 123 ++#define TARGET_NR_sched_yield 124 ++#define TARGET_NR_sched_get_priority_max 125 ++#define TARGET_NR_sched_get_priority_min 126 ++#define TARGET_NR_sched_rr_get_interval 127 ++#define TARGET_NR_restart_syscall 128 ++#define TARGET_NR_kill 129 ++#define TARGET_NR_tkill 130 ++#define TARGET_NR_tgkill 131 ++#define TARGET_NR_sigaltstack 132 ++#define TARGET_NR_rt_sigsuspend 133 ++#define TARGET_NR_rt_sigaction 134 ++#define TARGET_NR_rt_sigprocmask 135 ++#define TARGET_NR_rt_sigpending 136 ++#define TARGET_NR_rt_sigtimedwait 137 ++#define TARGET_NR_rt_sigqueueinfo 138 ++#define TARGET_NR_rt_sigreturn 139 ++#define TARGET_NR_setpriority 140 ++#define TARGET_NR_getpriority 141 ++#define TARGET_NR_reboot 142 ++#define TARGET_NR_setregid 143 ++#define TARGET_NR_setgid 144 ++#define TARGET_NR_setreuid 145 ++#define TARGET_NR_setuid 146 ++#define TARGET_NR_setresuid 147 ++#define TARGET_NR_getresuid 148 ++#define TARGET_NR_setresgid 149 ++#define TARGET_NR_getresgid 150 ++#define TARGET_NR_setfsuid 151 ++#define TARGET_NR_setfsgid 152 ++#define TARGET_NR_times 153 ++#define TARGET_NR_setpgid 154 ++#define TARGET_NR_getpgid 155 ++#define TARGET_NR_getsid 156 ++#define TARGET_NR_setsid 157 ++#define TARGET_NR_getgroups 158 ++#define TARGET_NR_setgroups 159 ++#define TARGET_NR_uname 160 ++#define TARGET_NR_sethostname 161 ++#define TARGET_NR_setdomainname 162 ++#define TARGET_NR_getrlimit 163 ++#define TARGET_NR_setrlimit 164 ++#define TARGET_NR_getrusage 165 ++#define TARGET_NR_umask 166 ++#define TARGET_NR_prctl 167 ++#define TARGET_NR_getcpu 168 ++#define TARGET_NR_gettimeofday 169 ++#define TARGET_NR_settimeofday 170 ++#define TARGET_NR_adjtimex 171 ++#define TARGET_NR_getpid 172 ++#define TARGET_NR_getppid 173 ++#define TARGET_NR_getuid 174 ++#define TARGET_NR_geteuid 175 ++#define TARGET_NR_getgid 176 ++#define TARGET_NR_getegid 177 ++#define TARGET_NR_gettid 178 ++#define TARGET_NR_sysinfo 179 ++#define TARGET_NR_mq_open 180 ++#define TARGET_NR_mq_unlink 181 ++#define TARGET_NR_mq_timedsend 182 ++#define TARGET_NR_mq_timedreceive 183 ++#define TARGET_NR_mq_notify 184 ++#define TARGET_NR_mq_getsetattr 185 ++#define TARGET_NR_msgget 186 ++#define TARGET_NR_msgctl 187 ++#define TARGET_NR_msgrcv 188 ++#define TARGET_NR_msgsnd 189 ++#define TARGET_NR_semget 190 ++#define TARGET_NR_semctl 191 ++#define TARGET_NR_semtimedop 192 ++#define TARGET_NR_semop 193 ++#define TARGET_NR_shmget 194 ++#define TARGET_NR_shmctl 195 ++#define TARGET_NR_shmat 196 ++#define TARGET_NR_shmdt 197 ++#define TARGET_NR_socket 198 ++#define TARGET_NR_socketpair 199 ++#define TARGET_NR_bind 200 ++#define TARGET_NR_listen 201 ++#define TARGET_NR_accept 202 ++#define TARGET_NR_connect 203 ++#define TARGET_NR_getsockname 204 ++#define TARGET_NR_getpeername 205 ++#define TARGET_NR_sendto 206 ++#define TARGET_NR_recvfrom 207 ++#define TARGET_NR_setsockopt 208 ++#define TARGET_NR_getsockopt 209 ++#define TARGET_NR_shutdown 210 ++#define TARGET_NR_sendmsg 211 ++#define TARGET_NR_recvmsg 212 ++#define TARGET_NR_readahead 213 ++#define TARGET_NR_brk 214 ++#define TARGET_NR_munmap 215 ++#define TARGET_NR_mremap 216 ++#define TARGET_NR_add_key 217 ++#define TARGET_NR_request_key 218 ++#define TARGET_NR_keyctl 219 ++#define TARGET_NR_clone 220 ++#define TARGET_NR_execve 221 ++#define TARGET_NR_mmap 222 ++#define TARGET_NR_fadvise64 223 ++#define TARGET_NR_swapon 224 ++#define TARGET_NR_swapoff 225 ++#define TARGET_NR_mprotect 226 ++#define TARGET_NR_msync 227 ++#define TARGET_NR_mlock 228 ++#define TARGET_NR_munlock 229 ++#define TARGET_NR_mlockall 230 ++#define TARGET_NR_munlockall 231 ++#define TARGET_NR_mincore 232 ++#define TARGET_NR_madvise 233 ++#define TARGET_NR_remap_file_pages 234 ++#define TARGET_NR_mbind 235 ++#define TARGET_NR_get_mempolicy 236 ++#define TARGET_NR_set_mempolicy 237 ++#define TARGET_NR_migrate_pages 238 ++#define TARGET_NR_move_pages 239 ++#define TARGET_NR_rt_tgsigqueueinfo 240 ++#define TARGET_NR_perf_event_open 241 ++#define TARGET_NR_accept4 242 ++#define TARGET_NR_recvmmsg 243 ++#define TARGET_NR_arch_specific_syscall 244 ++#define TARGET_NR_wait4 260 ++#define TARGET_NR_prlimit64 261 ++#define TARGET_NR_fanotify_init 262 ++#define TARGET_NR_fanotify_mark 263 ++#define TARGET_NR_name_to_handle_at 264 ++#define TARGET_NR_open_by_handle_at 265 ++#define TARGET_NR_clock_adjtime 266 ++#define TARGET_NR_syncfs 267 ++#define TARGET_NR_setns 268 ++#define TARGET_NR_sendmmsg 269 ++#define TARGET_NR_process_vm_readv 270 ++#define TARGET_NR_process_vm_writev 271 ++#define TARGET_NR_kcmp 272 ++#define TARGET_NR_finit_module 273 ++#define TARGET_NR_sched_setattr 274 ++#define TARGET_NR_sched_getattr 275 ++#define TARGET_NR_renameat2 276 ++#define TARGET_NR_seccomp 277 ++#define TARGET_NR_getrandom 278 ++#define TARGET_NR_memfd_create 279 ++#define TARGET_NR_bpf 280 ++#define TARGET_NR_execveat 281 ++#define TARGET_NR_userfaultfd 282 ++#define TARGET_NR_membarrier 283 ++#define TARGET_NR_mlock2 284 ++#define TARGET_NR_copy_file_range 285 ++#define TARGET_NR_preadv2 286 ++#define TARGET_NR_pwritev2 287 ++#define TARGET_NR_pkey_mprotect 288 ++#define TARGET_NR_pkey_alloc 289 ++#define TARGET_NR_pkey_free 290 ++#define TARGET_NR_statx 291 ++#define TARGET_NR_io_pgetevents 292 ++#define TARGET_NR_rseq 293 ++#define TARGET_NR_kexec_file_load 294 ++ ++#define TARGET_NR_syscalls (TARGET_NR_kexec_file_load + 1) ++ ++#endif +diff --git a/linux-user/loongarch64/target_cpu.h b/linux-user/loongarch64/target_cpu.h +new file mode 100644 +index 000000000..0f6845737 +--- /dev/null ++++ b/linux-user/loongarch64/target_cpu.h +@@ -0,0 +1,45 @@ ++/* ++ * MIPS specific CPU ABI and functions for linux-user ++ * ++ * Copyright (c) 2004-2005 Jocelyn Mayer ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#ifndef LOONGARCH_TARGET_CPU_H ++#define LOONGARCH_TARGET_CPU_H ++ ++static inline void cpu_clone_regs_child(CPULOONGARCHState *env, target_ulong newsp, ++ unsigned flags) ++{ ++ if (newsp) { ++ env->active_tc.gpr[3] = newsp; ++ } ++ env->active_tc.gpr[7] = 0; ++ env->active_tc.gpr[4] = 0; ++} ++ ++static inline void cpu_clone_regs_parent(CPULOONGARCHState *env, unsigned flags) ++{ ++} ++ ++static inline void cpu_set_tls(CPULOONGARCHState *env, target_ulong newtls) ++{ ++ env->active_tc.gpr[2] = newtls; ++} ++ ++static inline abi_ulong get_sp_from_cpustate(CPULOONGARCHState *state) ++{ ++ return state->active_tc.gpr[3]; ++} ++#endif +diff --git a/linux-user/loongarch64/target_elf.h b/linux-user/loongarch64/target_elf.h +new file mode 100644 +index 000000000..6c153d12c +--- /dev/null ++++ b/linux-user/loongarch64/target_elf.h +@@ -0,0 +1,14 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation, or (at your option) any ++ * later version. See the COPYING file in the top-level directory. ++ */ ++ ++#ifndef LOONGARCH_TARGET_ELF_H ++#define LOONGARCH_TARGET_ELF_H ++static inline const char *cpu_get_model(uint32_t eflags) ++{ ++ return "Loongson-3A5000"; ++} ++#endif +diff --git a/linux-user/loongarch64/target_fcntl.h b/linux-user/loongarch64/target_fcntl.h +new file mode 100644 +index 000000000..a3d7b4606 +--- /dev/null ++++ b/linux-user/loongarch64/target_fcntl.h +@@ -0,0 +1,13 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation, or (at your option) any ++ * later version. See the COPYING file in the top-level directory. ++ */ ++ ++#ifndef LOONGARCH_TARGET_FCNTL_H ++#define LOONGARCH_TARGET_FCNTL_H ++ ++#include "../generic/fcntl.h" ++ ++#endif /* LOONGARCH_TARGET_FCNTL_H */ +diff --git a/linux-user/loongarch64/target_signal.h b/linux-user/loongarch64/target_signal.h +new file mode 100644 +index 000000000..e418c8e8f +--- /dev/null ++++ b/linux-user/loongarch64/target_signal.h +@@ -0,0 +1,23 @@ ++#ifndef LOONGARCH_TARGET_SIGNAL_H ++#define LOONGARCH_TARGET_SIGNAL_H ++ ++/* this struct defines a stack used during syscall handling */ ++ ++typedef struct target_sigaltstack { ++ abi_long ss_sp; ++ abi_int ss_flags; ++ abi_ulong ss_size; ++} target_stack_t; ++ ++/* ++ * sigaltstack controls ++ */ ++#define TARGET_SS_ONSTACK 1 ++#define TARGET_SS_DISABLE 2 ++ ++#define TARGET_MINSIGSTKSZ 2048 ++#define TARGET_SIGSTKSZ 8192 ++ ++#include "../generic/signal.h" ++ ++#endif /* LOONGARCH_TARGET_SIGNAL_H */ +diff --git a/linux-user/loongarch64/target_structs.h b/linux-user/loongarch64/target_structs.h +new file mode 100644 +index 000000000..280acd097 +--- /dev/null ++++ b/linux-user/loongarch64/target_structs.h +@@ -0,0 +1,62 @@ ++/* ++ * LOONGARCH specific structures for linux-user ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#ifndef LOONGARCH_TARGET_STRUCTS_H ++#define LOONGARCH_TARGET_STRUCTS_H ++ ++struct target_ipc_perm { ++ abi_int __key; /* Key. */ ++ abi_uint uid; /* Owner's user ID. */ ++ abi_uint gid; /* Owner's group ID. */ ++ abi_uint cuid; /* Creator's user ID. */ ++ abi_uint cgid; /* Creator's group ID. */ ++ abi_uint mode; /* Read/write permission. */ ++ abi_ushort __seq; /* Sequence number. */ ++ abi_ushort __pad1; ++ abi_ulong __unused1; ++ abi_ulong __unused2; ++}; ++ ++struct target_shmid_ds { ++ struct target_ipc_perm shm_perm; /* operation permission struct */ ++ abi_long shm_segsz; /* size of segment in bytes */ ++ abi_ulong shm_atime; /* time of last shmat() */ ++ abi_ulong shm_dtime; /* time of last shmdt() */ ++ abi_ulong shm_ctime; /* time of last change by shmctl() */ ++ abi_int shm_cpid; /* pid of creator */ ++ abi_int shm_lpid; /* pid of last shmop */ ++ abi_ulong shm_nattch; /* number of current attaches */ ++ abi_ulong __unused1; ++ abi_ulong __unused2; ++}; ++ ++#define TARGET_SEMID64_DS ++ ++/* ++ * The semid64_ds structure for the MIPS architecture. ++ * Note extra padding because this structure is passed back and forth ++ * between kernel and user space. ++ */ ++struct target_semid64_ds { ++ struct target_ipc_perm sem_perm; ++ abi_ulong sem_otime; ++ abi_ulong sem_ctime; ++ abi_ulong sem_nsems; ++ abi_ulong __unused1; ++ abi_ulong __unused2; ++}; ++ ++#endif +diff --git a/linux-user/loongarch64/target_syscall.h b/linux-user/loongarch64/target_syscall.h +new file mode 100644 +index 000000000..cb77f0708 +--- /dev/null ++++ b/linux-user/loongarch64/target_syscall.h +@@ -0,0 +1,44 @@ ++#ifndef LOONGARCH_TARGET_SYSCALL_H ++#define LOONGARCH_TARGET_SYSCALL_H ++ ++/* this struct defines the way the registers are stored on the ++ stack during a system call. */ ++ ++struct target_pt_regs { ++ /* Saved main processor registers. */ ++ target_ulong regs[32]; ++ ++ /* Saved special registers. */ ++ /* Saved special registers. */ ++ target_ulong csr_crmd; ++ target_ulong csr_prmd; ++ target_ulong csr_euen; ++ target_ulong csr_ecfg; ++ target_ulong csr_estat; ++ target_ulong csr_era; ++ target_ulong csr_badvaddr; ++ target_ulong orig_a0; ++ target_ulong __last[0]; ++}; ++ ++#define UNAME_MACHINE "loongarch" ++#define UNAME_MINIMUM_RELEASE "2.6.32" ++ ++#define TARGET_CLONE_BACKWARDS ++#define TARGET_MINSIGSTKSZ 2048 ++#define TARGET_MLOCKALL_MCL_CURRENT 1 ++#define TARGET_MLOCKALL_MCL_FUTURE 2 ++ ++#define TARGET_FORCE_SHMLBA ++ ++static inline abi_ulong target_shmlba(CPULOONGARCHState *env) ++{ ++ return 0x40000; ++} ++ ++#define TARGET_PR_SET_FP_MODE 45 ++#define TARGET_PR_GET_FP_MODE 46 ++#define TARGET_PR_FP_MODE_FR (1 << 0) ++#define TARGET_PR_FP_MODE_FRE (1 << 1) ++ ++#endif /* LOONGARCH_TARGET_SYSCALL_H */ +diff --git a/linux-user/loongarch64/termbits.h b/linux-user/loongarch64/termbits.h +new file mode 100644 +index 000000000..6c613a197 +--- /dev/null ++++ b/linux-user/loongarch64/termbits.h +@@ -0,0 +1,224 @@ ++#ifndef LINUX_USER_LOONGARCH_TERMBITS_H ++#define LINUX_USER_LOONGARCH_TERMBITS_H ++ ++#define TARGET_NCCS 19 ++ ++struct target_termios { ++ unsigned int c_iflag; /* input mode flags */ ++ unsigned int c_oflag; /* output mode flags */ ++ unsigned int c_cflag; /* control mode flags */ ++ unsigned int c_lflag; /* local mode flags */ ++ unsigned char c_line; /* line discipline */ ++ unsigned char c_cc[TARGET_NCCS]; /* control characters */ ++}; ++ ++/* c_iflag bits */ ++#define TARGET_IGNBRK 0000001 ++#define TARGET_BRKINT 0000002 ++#define TARGET_IGNPAR 0000004 ++#define TARGET_PARMRK 0000010 ++#define TARGET_INPCK 0000020 ++#define TARGET_ISTRIP 0000040 ++#define TARGET_INLCR 0000100 ++#define TARGET_IGNCR 0000200 ++#define TARGET_ICRNL 0000400 ++#define TARGET_IUCLC 0001000 ++#define TARGET_IXON 0002000 ++#define TARGET_IXANY 0004000 ++#define TARGET_IXOFF 0010000 ++#define TARGET_IMAXBEL 0020000 ++#define TARGET_IUTF8 0040000 ++ ++/* c_oflag bits */ ++#define TARGET_OPOST 0000001 ++#define TARGET_OLCUC 0000002 ++#define TARGET_ONLCR 0000004 ++#define TARGET_OCRNL 0000010 ++#define TARGET_ONOCR 0000020 ++#define TARGET_ONLRET 0000040 ++#define TARGET_OFILL 0000100 ++#define TARGET_OFDEL 0000200 ++#define TARGET_NLDLY 0000400 ++#define TARGET_NL0 0000000 ++#define TARGET_NL1 0000400 ++#define TARGET_CRDLY 0003000 ++#define TARGET_CR0 0000000 ++#define TARGET_CR1 0001000 ++#define TARGET_CR2 0002000 ++#define TARGET_CR3 0003000 ++#define TARGET_TABDLY 0014000 ++#define TARGET_TAB0 0000000 ++#define TARGET_TAB1 0004000 ++#define TARGET_TAB2 0010000 ++#define TARGET_TAB3 0014000 ++#define TARGET_XTABS 0014000 ++#define TARGET_BSDLY 0020000 ++#define TARGET_BS0 0000000 ++#define TARGET_BS1 0020000 ++#define TARGET_VTDLY 0040000 ++#define TARGET_VT0 0000000 ++#define TARGET_VT1 0040000 ++#define TARGET_FFDLY 0100000 ++#define TARGET_FF0 0000000 ++#define TARGET_FF1 0100000 ++ ++/* c_cflag bit meaning */ ++#define TARGET_CBAUD 0010017 ++#define TARGET_B0 0000000 /* hang up */ ++#define TARGET_B50 0000001 ++#define TARGET_B75 0000002 ++#define TARGET_B110 0000003 ++#define TARGET_B134 0000004 ++#define TARGET_B150 0000005 ++#define TARGET_B200 0000006 ++#define TARGET_B300 0000007 ++#define TARGET_B600 0000010 ++#define TARGET_B1200 0000011 ++#define TARGET_B1800 0000012 ++#define TARGET_B2400 0000013 ++#define TARGET_B4800 0000014 ++#define TARGET_B9600 0000015 ++#define TARGET_B19200 0000016 ++#define TARGET_B38400 0000017 ++#define TARGET_EXTA B19200 ++#define TARGET_EXTB B38400 ++#define TARGET_CSIZE 0000060 ++#define TARGET_CS5 0000000 ++#define TARGET_CS6 0000020 ++#define TARGET_CS7 0000040 ++#define TARGET_CS8 0000060 ++#define TARGET_CSTOPB 0000100 ++#define TARGET_CREAD 0000200 ++#define TARGET_PARENB 0000400 ++#define TARGET_PARODD 0001000 ++#define TARGET_HUPCL 0002000 ++#define TARGET_CLOCAL 0004000 ++#define TARGET_CBAUDEX 0010000 ++#define TARGET_B57600 0010001 ++#define TARGET_B115200 0010002 ++#define TARGET_B230400 0010003 ++#define TARGET_B460800 0010004 ++#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */ ++#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ ++#define TARGET_CRTSCTS 020000000000 /* flow control */ ++ ++/* c_lflag bits */ ++#define TARGET_ISIG 0000001 ++#define TARGET_ICANON 0000002 ++#define TARGET_XCASE 0000004 ++#define TARGET_ECHO 0000010 ++#define TARGET_ECHOE 0000020 ++#define TARGET_ECHOK 0000040 ++#define TARGET_ECHONL 0000100 ++#define TARGET_NOFLSH 0000200 ++#define TARGET_TOSTOP 0000400 ++#define TARGET_ECHOCTL 0001000 ++#define TARGET_ECHOPRT 0002000 ++#define TARGET_ECHOKE 0004000 ++#define TARGET_FLUSHO 0010000 ++#define TARGET_PENDIN 0040000 ++#define TARGET_IEXTEN 0100000 ++ ++/* c_cc character offsets */ ++#define TARGET_VINTR 0 ++#define TARGET_VQUIT 1 ++#define TARGET_VERASE 2 ++#define TARGET_VKILL 3 ++#define TARGET_VEOF 4 ++#define TARGET_VTIME 5 ++#define TARGET_VMIN 6 ++#define TARGET_VSWTC 7 ++#define TARGET_VSTART 8 ++#define TARGET_VSTOP 9 ++#define TARGET_VSUSP 10 ++#define TARGET_VEOL 11 ++#define TARGET_VREPRINT 12 ++#define TARGET_VDISCARD 13 ++#define TARGET_VWERASE 14 ++#define TARGET_VLNEXT 15 ++#define TARGET_VEOL2 16 ++ ++/* ioctls */ ++ ++#define TARGET_TCGETS 0x5401 ++#define TARGET_TCSETS 0x5402 ++#define TARGET_TCSETSW 0x5403 ++#define TARGET_TCSETSF 0x5404 ++#define TARGET_TCGETA 0x5405 ++#define TARGET_TCSETA 0x5406 ++#define TARGET_TCSETAW 0x5407 ++#define TARGET_TCSETAF 0x5408 ++#define TARGET_TCSBRK 0x5409 ++#define TARGET_TCXONC 0x540A ++#define TARGET_TCFLSH 0x540B ++ ++#define TARGET_TIOCEXCL 0x540C ++#define TARGET_TIOCNXCL 0x540D ++#define TARGET_TIOCSCTTY 0x540E ++#define TARGET_TIOCGPGRP 0x540F ++#define TARGET_TIOCSPGRP 0x5410 ++#define TARGET_TIOCOUTQ 0x5411 ++#define TARGET_TIOCSTI 0x5412 ++#define TARGET_TIOCGWINSZ 0x5413 ++#define TARGET_TIOCSWINSZ 0x5414 ++#define TARGET_TIOCMGET 0x5415 ++#define TARGET_TIOCMBIS 0x5416 ++#define TARGET_TIOCMBIC 0x5417 ++#define TARGET_TIOCMSET 0x5418 ++#define TARGET_TIOCGSOFTCAR 0x5419 ++#define TARGET_TIOCSSOFTCAR 0x541A ++#define TARGET_FIONREAD 0x541B ++#define TARGET_TIOCINQ TARGET_FIONREAD ++#define TARGET_TIOCLINUX 0x541C ++#define TARGET_TIOCCONS 0x541D ++#define TARGET_TIOCGSERIAL 0x541E ++#define TARGET_TIOCSSERIAL 0x541F ++#define TARGET_TIOCPKT 0x5420 ++#define TARGET_FIONBIO 0x5421 ++#define TARGET_TIOCNOTTY 0x5422 ++#define TARGET_TIOCSETD 0x5423 ++#define TARGET_TIOCGETD 0x5424 ++#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ ++#define TARGET_TIOCTTYGSTRUCT 0x5426 /* For debugging only */ ++#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ ++#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ ++#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */ ++#define TARGET_TIOCGPTN TARGET_IOR('T', 0x30, unsigned int) ++ /* Get Pty Number (of pty-mux device) */ ++#define TARGET_TIOCSPTLCK TARGET_IOW('T', 0x31, int) ++ /* Lock/unlock Pty */ ++#define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41) ++ /* Safely open the slave */ ++ ++#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */ ++#define TARGET_FIOCLEX 0x5451 ++#define TARGET_FIOASYNC 0x5452 ++#define TARGET_TIOCSERCONFIG 0x5453 ++#define TARGET_TIOCSERGWILD 0x5454 ++#define TARGET_TIOCSERSWILD 0x5455 ++#define TARGET_TIOCGLCKTRMIOS 0x5456 ++#define TARGET_TIOCSLCKTRMIOS 0x5457 ++#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */ ++#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */ ++#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */ ++#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */ ++ ++#define TARGET_TIOCMIWAIT 0x545C ++ /* wait for a change on serial input line(s) */ ++#define TARGET_TIOCGICOUNT 0x545D ++ /* read serial port inline interrupt counts */ ++#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ ++#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ ++ ++/* Used for packet mode */ ++#define TARGET_TIOCPKT_DATA 0 ++#define TARGET_TIOCPKT_FLUSHREAD 1 ++#define TARGET_TIOCPKT_FLUSHWRITE 2 ++#define TARGET_TIOCPKT_STOP 4 ++#define TARGET_TIOCPKT_START 8 ++#define TARGET_TIOCPKT_NOSTOP 16 ++#define TARGET_TIOCPKT_DOSTOP 32 ++ ++#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */ ++ ++#endif +-- +2.27.0 + diff --git a/Add-loongarch-machine.patch b/Add-loongarch-machine.patch new file mode 100644 index 00000000..0e34a09e --- /dev/null +++ b/Add-loongarch-machine.patch @@ -0,0 +1,5751 @@ +From 652139a0e47210facb3a66b44cac5162a91e2d50 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Wed, 7 Dec 2022 04:23:48 -0500 +Subject: [PATCH 03/11] Add loongarch machine. + +Signed-off-by: lixianglai +--- + hw/loongarch/Kconfig | 17 + + hw/loongarch/acpi-build.c | 783 ++++++++++++ + hw/loongarch/acpi-build.h | 16 + + hw/loongarch/apic.c | 675 +++++++++++ + hw/loongarch/ioapic.c | 422 +++++++ + hw/loongarch/iocsr.c | 219 ++++ + hw/loongarch/ipi.c | 267 +++++ + hw/loongarch/larch_3a.c | 2026 ++++++++++++++++++++++++++++++++ + hw/loongarch/larch_hotplug.c | 355 ++++++ + hw/loongarch/larch_int.c | 91 ++ + hw/loongarch/ls7a_nb.c | 352 ++++++ + hw/loongarch/meson.build | 15 + + include/hw/loongarch/bios.h | 5 + + include/hw/loongarch/cpudevs.h | 53 + + include/hw/loongarch/larch.h | 163 +++ + include/hw/loongarch/ls7a.h | 152 +++ + 16 files changed, 5611 insertions(+) + create mode 100644 hw/loongarch/Kconfig + create mode 100644 hw/loongarch/acpi-build.c + create mode 100644 hw/loongarch/acpi-build.h + create mode 100644 hw/loongarch/apic.c + create mode 100644 hw/loongarch/ioapic.c + create mode 100644 hw/loongarch/iocsr.c + create mode 100644 hw/loongarch/ipi.c + create mode 100644 hw/loongarch/larch_3a.c + create mode 100644 hw/loongarch/larch_hotplug.c + create mode 100644 hw/loongarch/larch_int.c + create mode 100644 hw/loongarch/ls7a_nb.c + create mode 100644 hw/loongarch/meson.build + create mode 100644 include/hw/loongarch/bios.h + create mode 100644 include/hw/loongarch/cpudevs.h + create mode 100644 include/hw/loongarch/larch.h + create mode 100644 include/hw/loongarch/ls7a.h + +diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig +new file mode 100644 +index 000000000..3fe2677fd +--- /dev/null ++++ b/hw/loongarch/Kconfig +@@ -0,0 +1,17 @@ ++config LS7A_APIC ++ bool ++ ++config LS7A_RTC ++ bool ++ ++config LOONGSON3A ++ bool ++ ++config MEM_HOTPLUG ++ bool ++ ++config ACPI_LOONGARCH ++ bool ++ ++config E1000E_PCI ++ bool +diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c +new file mode 100644 +index 000000000..6ba637be5 +--- /dev/null ++++ b/hw/loongarch/acpi-build.c +@@ -0,0 +1,783 @@ ++/* Support for generating ACPI tables and passing them to Guests ++ * ++ * Copyright (C) 2008-2010 Kevin O'Connor ++ * Copyright (C) 2006 Fabrice Bellard ++ * Copyright (C) 2013 Red Hat Inc ++ * ++ * Author: Michael S. Tsirkin ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, see . ++ */ ++ ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include "qapi/qmp/qnum.h" ++#include "acpi-build.h" ++#include "qemu-common.h" ++#include "qemu/bitmap.h" ++#include "qemu/error-report.h" ++#include "hw/pci/pci.h" ++#include "hw/boards.h" ++#include "hw/core/cpu.h" ++#include "target/loongarch64/cpu.h" ++#include "hw/misc/pvpanic.h" ++#include "hw/timer/hpet.h" ++#include "hw/acpi/acpi-defs.h" ++#include "hw/acpi/acpi.h" ++#include "hw/acpi/cpu.h" ++#include "hw/nvram/fw_cfg.h" ++#include "hw/acpi/bios-linker-loader.h" ++#include "hw/loader.h" ++#include "hw/isa/isa.h" ++#include "hw/block/fdc.h" ++#include "hw/acpi/memory_hotplug.h" ++#include "sysemu/tpm.h" ++#include "hw/acpi/tpm.h" ++#include "hw/acpi/vmgenid.h" ++#include "sysemu/tpm_backend.h" ++#include "hw/rtc/mc146818rtc_regs.h" ++#include "sysemu/numa.h" ++#include "sysemu/runstate.h" ++#include "sysemu/reset.h" ++#include "migration/vmstate.h" ++#include "hw/mem/memory-device.h" ++#include "hw/acpi/utils.h" ++#include "hw/acpi/pci.h" ++/* Supported chipsets: */ ++#include "hw/acpi/aml-build.h" ++#include "hw/loongarch/larch.h" ++#include "hw/loongarch/ls7a.h" ++ ++#include "hw/acpi/ipmi.h" ++#include "hw/acpi/ls7a.h" ++ ++/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and ++ * -M pc-i440fx-2.0. Even if the actual amount of AML generated grows ++ * a little bit, there should be plenty of free space since the DSDT ++ * shrunk by ~1.5k between QEMU 2.0 and QEMU 2.1. ++ */ ++#define ACPI_BUILD_ALIGN_SIZE 0x1000 ++ ++#define ACPI_BUILD_TABLE_SIZE 0x20000 ++ ++/* #define DEBUG_ACPI_BUILD */ ++#ifdef DEBUG_ACPI_BUILD ++#define ACPI_BUILD_DPRINTF(fmt, ...) \ ++ do {printf("ACPI_BUILD: " fmt, ## __VA_ARGS__); } while (0) ++#else ++#define ACPI_BUILD_DPRINTF(fmt, ...) ++#endif ++ ++/* Default IOAPIC ID */ ++#define ACPI_BUILD_IOAPIC_ID 0x0 ++ ++/* PCI fw r3.0 MCFG table. */ ++/* Subtable */ ++ ++typedef struct AcpiMiscInfo { ++ bool is_piix4; ++ bool has_hpet; ++ TPMVersion tpm_version; ++ const unsigned char *dsdt_code; ++ unsigned dsdt_size; ++ uint16_t pvpanic_port; ++ uint16_t applesmc_io_base; ++} AcpiMiscInfo; ++ ++typedef struct AcpiBuildPciBusHotplugState { ++ GArray *device_table; ++ GArray *notify_table; ++ struct AcpiBuildPciBusHotplugState *parent; ++ bool pcihp_bridge_en; ++} AcpiBuildPciBusHotplugState; ++ ++static void init_common_fadt_data(AcpiFadtData *data) ++{ ++ AmlAddressSpace as = AML_AS_SYSTEM_MEMORY; ++ uint64_t base = LS7A_ACPI_REG_BASE; ++ AcpiFadtData fadt = { ++ .rev = 3, ++ .flags = ++ (1 << ACPI_FADT_F_WBINVD) | ++ (1 << ACPI_FADT_F_PROC_C1) | ++ (1 << ACPI_FADT_F_SLP_BUTTON) | ++ (1 << ACPI_FADT_F_TMR_VAL_EXT) | ++ (1 << ACPI_FADT_F_RESET_REG_SUP) , ++ .plvl2_lat = 0xfff /* C2 state not supported */, ++ .plvl3_lat = 0xfff /* C3 state not supported */, ++ .smi_cmd = 0x00, ++ .sci_int = ACPI_SCI_IRQ, ++ .acpi_enable_cmd = 0x00, ++ .acpi_disable_cmd = 0x00, ++ .pm1a_evt = { .space_id = as, .bit_width = 8 * 8, ++ .address = base + LS7A_PM_EVT_BLK }, ++ .pm1a_cnt = { .space_id = as, .bit_width = 4 * 8, ++ .address = base + LS7A_PM_CNT_BLK }, ++ .pm_tmr = { .space_id = as, .bit_width = 4 * 8, ++ .address = base + LS7A_PM_TMR_BLK }, ++ .gpe0_blk = { .space_id = as, .bit_width = 8 * 8, ++ .address = base + LS7A_GPE0_STS_REG}, ++ .reset_reg = { .space_id = as, .bit_width = 4 * 8, ++ .address = base + LS7A_GPE0_RESET_REG}, ++ .reset_val = 0x1, ++ }; ++ *data = fadt; ++} ++ ++static void acpi_align_size(GArray *blob, unsigned align) ++{ ++ /* Align size to multiple of given size. This reduces the chance ++ * we need to change size in the future (breaking cross version migration). ++ */ ++ g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align)); ++} ++ ++/* FACS */ ++static void ++build_facs(GArray *table_data) ++{ ++ const char *sig = "FACS"; ++ const uint8_t reserved[40] = {}; ++ ++ g_array_append_vals(table_data, sig, 4); /* Signature */ ++ build_append_int_noprefix(table_data, 64, 4); /* Length */ ++ build_append_int_noprefix(table_data, 0, 4); /* Hardware Signature */ ++ build_append_int_noprefix(table_data, 0, 4); /* Firmware Waking Vector */ ++ build_append_int_noprefix(table_data, 0, 4); /* Global Lock */ ++ build_append_int_noprefix(table_data, 0, 4); /* Flags */ ++ g_array_append_vals(table_data, reserved, 40); /* Reserved */ ++} ++ ++void ls7a_madt_cpu_entry(AcpiDeviceIf *adev, int uid, ++ const CPUArchIdList *apic_ids, GArray *entry, bool force_enabled) ++{ ++ uint32_t apic_id = apic_ids->cpus[uid].arch_id; ++ /* Flags – Local APIC Flags */ ++ uint32_t flags = apic_ids->cpus[uid].cpu != NULL || force_enabled ? ++ 1 /* Enabled */ : 0; ++ ++ /* Rev 1.0b, Table 5-13 Processor Local APIC Structure */ ++ build_append_int_noprefix(entry, 0, 1); /* Type */ ++ build_append_int_noprefix(entry, 8, 1); /* Length */ ++ build_append_int_noprefix(entry, uid, 1); /* ACPI Processor ID */ ++ build_append_int_noprefix(entry, apic_id, 1); /* APIC ID */ ++ build_append_int_noprefix(entry, flags, 4); /* Flags */ ++} ++static void build_ioapic(GArray *entry, uint8_t id, uint32_t addr, uint32_t irq) ++{ ++ /* Rev 1.0b, 5.2.8.2 IO APIC */ ++ build_append_int_noprefix(entry, 1, 1); /* Type */ ++ build_append_int_noprefix(entry, 12, 1); /* Length */ ++ build_append_int_noprefix(entry, id, 1); /* IO APIC ID */ ++ build_append_int_noprefix(entry, 0, 1); /* Reserved */ ++ build_append_int_noprefix(entry, addr, 4); /* IO APIC Address */ ++ build_append_int_noprefix(entry, irq, 4); /* System Vector Base */ ++} ++ ++static void ++build_madt(GArray *table_data, BIOSLinker *linker, LoongarchMachineState *lsms) ++{ ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ MachineClass *mc = MACHINE_GET_CLASS(lsms); ++ const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(lsms)); ++ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(lsms->acpi_dev); ++ AcpiDeviceIf *adev = ACPI_DEVICE_IF(lsms->acpi_dev); ++ int i; ++ AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lsms->oem_id, ++ .oem_table_id = lsms->oem_table_id}; ++ ++ acpi_table_begin(&table, table_data); ++ ++ /* Local APIC Address */ ++ build_append_int_noprefix(table_data, 0, 4); ++ build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */ ++ ++ ++ for (i = 0; i < apic_ids->len; i++) { ++ adevc->madt_cpu(adev, i, apic_ids, table_data, false); ++ } ++ ++ ++ build_ioapic(table_data, ACPI_BUILD_IOAPIC_ID, lsmc->ls7a_ioapic_reg_base, LOONGARCH_PCH_IRQ_BASE); ++ ++ /* Rev 1.0b, 5.2.8.3.3 Local APIC NMI */ ++ build_append_int_noprefix(table_data, 3, 1); /* Type */ ++ build_append_int_noprefix(table_data, 6, 1); /* Length */ ++ /* ACPI Processor ID */ ++ build_append_int_noprefix(table_data, 0xFF /* all processors */, 1); ++ build_append_int_noprefix(table_data, 0, 2); /* Flags */ ++ /* Local APIC INTI# */ ++ build_append_int_noprefix(table_data, 1 /* ACPI_LINT1 */, 1); ++ ++ /* Rev 1.0b, 5.2.8.3.3 Local APIC NMI */ ++ build_append_int_noprefix(table_data, 4, 1); /* Type */ ++ build_append_int_noprefix(table_data, 6, 1); /* Length */ ++ /* ACPI Processor ID */ ++ build_append_int_noprefix(table_data, 0xFF /* all processors */, 1); ++ build_append_int_noprefix(table_data, 0, 2); /* Flags */ ++ /* Local APIC INTI# */ ++ build_append_int_noprefix(table_data, 1 /* ACPI_LINT1 */, 1); ++ ++ ++ acpi_table_end(linker, &table); ++} ++ ++static void ++build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) ++{ ++ uint64_t i, mem_len, mem_base; ++ MachineClass *mc = MACHINE_GET_CLASS(machine); ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine); ++ int nb_numa_nodes = machine->numa_state->num_nodes; ++ NodeInfo *numa_info = machine->numa_state->nodes; ++ AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lsms->oem_id, ++ .oem_table_id = lsms->oem_table_id}; ++ ++ acpi_table_begin(&table, table_data); ++ build_append_int_noprefix(table_data, 1, 4); /* Reserved */ ++ build_append_int_noprefix(table_data, 0, 8); /* Reserved */ ++ ++ for (i = 0; i < apic_ids->len; ++i) { ++ /* 5.2.15.1 Processor Local APIC/SAPIC Affinity Structure */ ++ build_append_int_noprefix(table_data, 0, 1); /* Type */ ++ build_append_int_noprefix(table_data, 16, 1); /* Length */ ++ /* Proximity Domain [7:0] */ ++ build_append_int_noprefix(table_data, apic_ids->cpus[i].props.node_id, 1); ++ build_append_int_noprefix(table_data, apic_ids->cpus[i].arch_id, 1); /* APIC ID */ ++ /* Flags, Table 5-36 */ ++ build_append_int_noprefix(table_data, 1, 4); ++ build_append_int_noprefix(table_data, 0, 1); /* Local SAPIC EID */ ++ /* Proximity Domain [31:8] */ ++ build_append_int_noprefix(table_data, 0, 3); ++ build_append_int_noprefix(table_data, 0, 4); /* Reserved */ ++ } ++ ++ /* node0 */ ++ mem_base = (uint64_t)0; ++ mem_len = 0x10000000; ++ build_srat_memory(table_data, mem_base, mem_len, ++ 0, MEM_AFFINITY_ENABLED); ++ mem_base = 0x90000000; ++ if (!nb_numa_nodes) { ++ mem_len = machine->ram_size - 0x10000000; ++ } else { ++ mem_len = numa_info[0].node_mem - 0x10000000; ++ } ++ ++ build_srat_memory(table_data, mem_base, mem_len, ++ 0, MEM_AFFINITY_ENABLED); ++ mem_base += mem_len; ++ ++ /* node1 ~ nodemax */ ++ for (i = 1; i < nb_numa_nodes; ++i) { ++ mem_len = numa_info[i].node_mem; ++ build_srat_memory(table_data, mem_base, mem_len, ++ i, MEM_AFFINITY_ENABLED); ++ mem_base += mem_len; ++ } ++ ++ if (lsms->hotplug_memory_size) { ++ build_srat_memory(table_data, machine->device_memory->base, ++ lsms->hotplug_memory_size, 0, ++ MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); ++ } ++ ++ acpi_table_end(linker, &table); ++ ++} ++ ++typedef ++struct AcpiBuildState { ++ /* Copy of table in RAM (for patching). */ ++ MemoryRegion *table_mr; ++ /* Is table patched? */ ++ uint8_t patched; ++ void *rsdp; ++ MemoryRegion *rsdp_mr; ++ MemoryRegion *linker_mr; ++} AcpiBuildState; ++ ++static void build_ls7a_pci0_int(Aml *table) ++{ ++ Aml *sb_scope = aml_scope("_SB"); ++ Aml *pci0_scope = aml_scope("PCI0"); ++ Aml *prt_pkg = aml_varpackage(128); ++ int slot, pin; ++ ++ for (slot = 0; slot < PCI_SLOT_MAX; slot++) { ++ for (pin = 0; pin < PCI_NUM_PINS; pin++) { ++ Aml *pkg = aml_package(4); ++ aml_append(pkg, aml_int((slot << 16) | 0xFFFF)); ++ aml_append(pkg, aml_int(pin)); ++ aml_append(pkg, aml_int(0)); ++ aml_append(pkg, aml_int(LOONGARCH_PCH_IRQ_BASE + 16 + (slot * 4 + pin) % 16)); ++ aml_append(prt_pkg, pkg); ++ } ++ } ++ aml_append(pci0_scope, ++ aml_name_decl("_PRT", prt_pkg)); ++ ++ aml_append(sb_scope, pci0_scope); ++ ++ aml_append(table, sb_scope); ++} ++ ++static void build_dbg_aml(Aml *table) ++{ ++ Aml *field; ++ Aml *method; ++ Aml *while_ctx; ++ Aml *scope = aml_scope("\\"); ++ Aml *buf = aml_local(0); ++ Aml *len = aml_local(1); ++ Aml *idx = aml_local(2); ++ ++ aml_append(scope, ++ aml_operation_region("DBG", AML_SYSTEM_IO, aml_int(0x0402), 0x01)); ++ field = aml_field("DBG", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); ++ aml_append(field, aml_named_field("DBGB", 8)); ++ aml_append(scope, field); ++ ++ method = aml_method("DBUG", 1, AML_NOTSERIALIZED); ++ ++ aml_append(method, aml_to_hexstring(aml_arg(0), buf)); ++ aml_append(method, aml_to_buffer(buf, buf)); ++ aml_append(method, aml_subtract(aml_sizeof(buf), aml_int(1), len)); ++ aml_append(method, aml_store(aml_int(0), idx)); ++ ++ while_ctx = aml_while(aml_lless(idx, len)); ++ aml_append(while_ctx, ++ aml_store(aml_derefof(aml_index(buf, idx)), aml_name("DBGB"))); ++ aml_append(while_ctx, aml_increment(idx)); ++ aml_append(method, while_ctx); ++ ++ aml_append(method, aml_store(aml_int(0x0A), aml_name("DBGB"))); ++ aml_append(scope, method); ++ ++ aml_append(table, scope); ++} ++ ++static Aml *build_ls7a_osc_method(void) ++{ ++ Aml *if_ctx; ++ Aml *if_ctx2; ++ Aml *else_ctx; ++ Aml *method; ++ Aml *a_cwd1 = aml_name("CDW1"); ++ Aml *a_ctrl = aml_local(0); ++ ++ method = aml_method("_OSC", 4, AML_NOTSERIALIZED); ++ aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1")); ++ ++ if_ctx = aml_if(aml_equal( ++ aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766"))); ++ aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2")); ++ aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3")); ++ ++ aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl)); ++ ++ /* ++ * Always allow native PME, AER (no dependencies) ++ * Allow SHPC (PCI bridges can have SHPC controller) ++ */ ++ aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl)); ++ ++ if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1)))); ++ /* Unknown revision */ ++ aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1)); ++ aml_append(if_ctx, if_ctx2); ++ ++ if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl))); ++ /* Capabilities bits were masked */ ++ aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1)); ++ aml_append(if_ctx, if_ctx2); ++ ++ /* Update DWORD3 in the buffer */ ++ aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3"))); ++ aml_append(method, if_ctx); ++ ++ else_ctx = aml_else(); ++ /* Unrecognized UUID */ ++ aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1)); ++ aml_append(method, else_ctx); ++ ++ aml_append(method, aml_return(aml_arg(3))); ++ return method; ++} ++ ++static void build_ls7a_rtc_device_aml(Aml *table) ++{ ++ Aml *dev; ++ Aml *crs; ++ uint32_t rtc_irq = LS7A_RTC_IRQ; ++ ++ Aml *scope = aml_scope("_SB"); ++ dev = aml_device("RTC"); ++ aml_append(dev, aml_name_decl("_HID", aml_string("LOON0001"))); ++ crs = aml_resource_template(); ++ aml_append(crs, ++ aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, ++ AML_NON_CACHEABLE, AML_READ_WRITE, ++ 0, LS7A_RTC_REG_BASE, ++ LS7A_RTC_REG_BASE + LS7A_RTC_LEN - 1, 0, LS7A_RTC_LEN)); ++ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, ++ AML_EXCLUSIVE, &rtc_irq, 1)); ++ ++ aml_append(dev, aml_name_decl("_CRS", crs)); ++ aml_append(scope, dev); ++ aml_append(table, scope); ++} ++ ++static void build_ls7a_uart_device_aml(Aml *table) ++{ ++ Aml *dev; ++ Aml *crs; ++ Aml *pkg0, *pkg1, *pkg2; ++ uint32_t uart_irq = LS7A_UART_IRQ; ++ ++ Aml *scope = aml_scope("_SB"); ++ dev = aml_device("COMA"); ++ aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501"))); ++ aml_append(dev, aml_name_decl("_UID", aml_int(0))); ++ aml_append(dev, aml_name_decl("_CCA", aml_int(1))); ++ crs = aml_resource_template(); ++ aml_append(crs, ++ aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, ++ AML_NON_CACHEABLE, AML_READ_WRITE, ++ 0, LS7A_UART_BASE, LS7A_UART_BASE + LS7A_UART_LEN - 1, 0, 0x8)); ++ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, ++ AML_EXCLUSIVE, &uart_irq, 1)); ++ aml_append(dev, aml_name_decl("_CRS", crs)); ++ pkg0 = aml_package(0x2); ++ aml_append(pkg0, aml_int(0x01F78A40)); ++ aml_append(pkg0, aml_string("clock-frenquency")); ++ pkg1 = aml_package(0x1); ++ aml_append(pkg1, pkg0); ++ pkg2 = aml_package(0x2); ++ aml_append(pkg2, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301")); ++ aml_append(pkg2, pkg1); ++ ++ aml_append(dev, aml_name_decl("_DSD", pkg2)); ++ ++ aml_append(scope, dev); ++ aml_append(table, scope); ++} ++ ++static void ++build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) ++{ ++ Aml *dsdt, *sb_scope, *scope, *dev, *crs, *pkg; ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ uint32_t nr_mem = machine->ram_slots; ++ uint64_t base = LS7A_ACPI_REG_BASE; ++ int root_bus_limit = PCIE_MMCFG_BUS(LS_PCIECFG_SIZE - 1); ++ AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lsms->oem_id, ++ .oem_table_id = lsms->oem_table_id}; ++ ++ acpi_table_begin(&table, table_data); ++ dsdt = init_aml_allocator(); ++ ++ build_dbg_aml(dsdt); ++ ++ sb_scope = aml_scope("_SB"); ++ dev = aml_device("PCI0"); ++ aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); ++ aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); ++ aml_append(dev, aml_name_decl("_ADR", aml_int(0))); ++ aml_append(dev, aml_name_decl("_BBN", aml_int(0))); ++ aml_append(dev, aml_name_decl("_UID", aml_int(1))); ++ aml_append(dev, build_ls7a_osc_method()); ++ aml_append(sb_scope, dev); ++ aml_append(dsdt, sb_scope); ++ ++ build_ls7a_pci0_int(dsdt); ++ build_ls7a_rtc_device_aml(dsdt); ++ build_ls7a_uart_device_aml(dsdt); ++ ++ if (lsms->acpi_dev) { ++ CPUHotplugFeatures opts = { ++ .acpi_1_compatible = true, .has_legacy_cphp = false ++ }; ++ build_cpus_aml(dsdt, machine, opts, CPU_HOTPLUG_BASE, ++ "\\_SB.PCI0", "\\_GPE._E02"); ++ ++ build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0", ++ "\\_GPE._E03", AML_SYSTEM_MEMORY, ++ MEMORY_HOTPLUG_BASE); ++ } ++ ++ scope = aml_scope("_GPE"); ++ { ++ aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006"))); ++ } ++ aml_append(dsdt, scope); ++ ++ scope = aml_scope("\\_SB.PCI0"); ++ /* build PCI0._CRS */ ++ crs = aml_resource_template(); ++ aml_append(crs, ++ aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE, ++ 0x0000, 0x0, root_bus_limit, ++ 0x0000, root_bus_limit + 1)); ++ aml_append(crs, ++ aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED, ++ AML_POS_DECODE, AML_ENTIRE_RANGE, ++ 0x0000, 0x4000, 0xFFFF, 0x0000, 0xC000)); ++ aml_append(crs, ++ aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, ++ AML_CACHEABLE, AML_READ_WRITE, ++ 0, 0x40000000, 0x7FFFFFFF, 0, 0x40000000)); ++ aml_append(scope, aml_name_decl("_CRS", crs)); ++ ++ /* reserve GPE0 block resources */ ++ dev = aml_device("GPE0"); ++ aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06"))); ++ aml_append(dev, aml_name_decl("_UID", aml_string("GPE0 resources"))); ++ /* device present, functioning, decoding, not shown in UI */ ++ aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); ++ crs = aml_resource_template(); ++ aml_append(crs, ++ aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, ++ AML_CACHEABLE, AML_READ_WRITE, ++ 0, base + LS7A_GPE0_STS_REG, ++ base + LS7A_GPE0_STS_REG + 0x3, 0, 0x4)); ++ aml_append(dev, aml_name_decl("_CRS", crs)); ++ aml_append(scope, dev); ++ aml_append(dsdt, scope); ++ ++ scope = aml_scope("\\"); ++ pkg = aml_package(4); ++ aml_append(pkg, aml_int(7)); /* PM1a_CNT.SLP_TYP */ ++ aml_append(pkg, aml_int(7)); /* PM1b_CNT.SLP_TYP not impl. */ ++ aml_append(pkg, aml_int(0)); /* reserved */ ++ aml_append(pkg, aml_int(0)); /* reserved */ ++ aml_append(scope, aml_name_decl("_S5", pkg)); ++ aml_append(dsdt, scope); ++ ++ /* copy AML table into ACPI tables blob and patch header there */ ++ g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len); ++ acpi_table_end(linker, &table); ++ free_aml_allocator(); ++} ++ ++ ++static ++void acpi_build(AcpiBuildTables *tables, MachineState *machine) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ GArray *table_offsets; ++ AcpiFadtData fadt_data; ++ unsigned facs, rsdt, fadt, dsdt; ++ uint8_t *u; ++ size_t aml_len = 0; ++ GArray *tables_blob = tables->table_data; ++ ++ init_common_fadt_data(&fadt_data); ++ ++ table_offsets = g_array_new(false, true /* clear */, ++ sizeof(uint32_t)); ++ ACPI_BUILD_DPRINTF("init ACPI tables\n"); ++ ++ bios_linker_loader_alloc(tables->linker, ++ ACPI_BUILD_TABLE_FILE, tables_blob, ++ 64 /* Ensure FACS is aligned */, ++ false /* high memory */); ++ ++ /* ++ * FACS is pointed to by FADT. ++ * We place it first since it's the only table that has alignment ++ * requirements. ++ */ ++ facs = tables_blob->len; ++ build_facs(tables_blob); ++ ++ /* DSDT is pointed to by FADT */ ++ dsdt = tables_blob->len; ++ build_dsdt(tables_blob, tables->linker, MACHINE(qdev_get_machine())); ++ ++ /* Count the size of the DSDT and SSDT, we will need it for legacy ++ * sizing of ACPI tables. ++ */ ++ aml_len += tables_blob->len - dsdt; ++ ++ /* ACPI tables pointed to by RSDT */ ++ fadt = tables_blob->len; ++ acpi_add_table(table_offsets, tables_blob); ++ fadt_data.facs_tbl_offset = &facs; ++ fadt_data.dsdt_tbl_offset = &dsdt; ++ fadt_data.xdsdt_tbl_offset = &dsdt; ++ build_fadt(tables_blob, tables->linker, &fadt_data, ++ "LOONGS", "TP-R00"); ++ aml_len += tables_blob->len - fadt; ++ ++ acpi_add_table(table_offsets, tables_blob); ++ build_madt(tables_blob, tables->linker, lsms); ++ ++ acpi_add_table(table_offsets, tables_blob); ++ build_srat(tables_blob, tables->linker, machine); ++ if (machine->numa_state->have_numa_distance) { ++ acpi_add_table(table_offsets, tables_blob); ++ build_slit(tables_blob, tables->linker, machine, lsms->oem_id, ++ lsms->oem_table_id); ++ } ++ ++ /* Build mcfg */ ++ acpi_add_table(table_offsets, tables_blob); ++ { ++ AcpiMcfgInfo mcfg = { ++ .base = LS_PCIECFG_BASE, ++ .size = LS_PCIECFG_SIZE, ++ }; ++ build_mcfg(tables_blob, tables->linker, &mcfg, lsms->oem_id, ++ lsms->oem_table_id); ++ } ++ ++ /* Add tables supplied by user (if any) */ ++ for (u = acpi_table_first(); u; u = acpi_table_next(u)) { ++ unsigned len = acpi_table_len(u); ++ ++ acpi_add_table(table_offsets, tables_blob); ++ g_array_append_vals(tables_blob, u, len); ++ } ++ ++ /* RSDT is pointed to by RSDP */ ++ rsdt = tables_blob->len; ++ build_rsdt(tables_blob, tables->linker, table_offsets, ++ "LOONGS", "TP-R00"); ++ ++ /* RSDP is in FSEG memory, so allocate it separately */ ++ { ++ AcpiRsdpData rsdp_data = { ++ .revision = 0, ++ .oem_id = lsms->oem_id, ++ .xsdt_tbl_offset = NULL, ++ .rsdt_tbl_offset = &rsdt, ++ }; ++ build_rsdp(tables->rsdp, tables->linker, &rsdp_data); ++ } ++ acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE); ++ ++ /* Cleanup memory that's no longer used. */ ++ g_array_free(table_offsets, true); ++} ++ ++static void acpi_ram_update(MemoryRegion *mr, GArray *data) ++{ ++ uint32_t size = acpi_data_len(data); ++ ++ /* Make sure RAM size is correct - ++ in case it got changed e.g. by migration */ ++ memory_region_ram_resize(mr, size, &error_abort); ++ ++ memcpy(memory_region_get_ram_ptr(mr), data->data, size); ++ memory_region_set_dirty(mr, 0, size); ++} ++ ++static void acpi_build_update(void *build_opaque) ++{ ++ AcpiBuildState *build_state = build_opaque; ++ AcpiBuildTables tables; ++ ++ /* No state to update or already patched? Nothing to do. */ ++ if (!build_state || build_state->patched) { ++ return; ++ } ++ build_state->patched = 1; ++ ++ acpi_build_tables_init(&tables); ++ ++ acpi_build(&tables, MACHINE(qdev_get_machine())); ++ ++ acpi_ram_update(build_state->table_mr, tables.table_data); ++ ++ if (build_state->rsdp) { ++ memcpy(build_state->rsdp, tables.rsdp->data, ++ acpi_data_len(tables.rsdp)); ++ } else { ++ acpi_ram_update(build_state->rsdp_mr, tables.rsdp); ++ } ++ ++ acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob); ++ acpi_build_tables_cleanup(&tables, true); ++} ++ ++static void acpi_build_reset(void *build_opaque) ++{ ++ AcpiBuildState *build_state = build_opaque; ++ build_state->patched = 0; ++} ++ ++static const VMStateDescription vmstate_acpi_build = { ++ .name = "acpi_build", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT8(patched, AcpiBuildState), ++ VMSTATE_END_OF_LIST() ++ }, ++}; ++ ++void loongarch_acpi_setup(void) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); ++ AcpiBuildTables tables; ++ AcpiBuildState *build_state; ++ ++ if (!lsms->fw_cfg) { ++ ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n"); ++ return; ++ } ++ ++ if (!lsms->acpi_build_enabled) { ++ ACPI_BUILD_DPRINTF("ACPI build disabled. Bailing out.\n"); ++ return; ++ } ++ ++ if (!loongarch_is_acpi_enabled(lsms)) { ++ ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n"); ++ return; ++ } ++ ++ build_state = g_malloc0(sizeof *build_state); ++ ++ acpi_build_tables_init(&tables); ++ acpi_build(&tables, MACHINE(lsms)); ++ ++ /* Now expose it all to Guest */ ++ build_state->table_mr = acpi_add_rom_blob(acpi_build_update, build_state, ++ tables.table_data, ++ ACPI_BUILD_TABLE_FILE); ++ assert(build_state->table_mr != NULL); ++ ++ build_state->linker_mr = ++ acpi_add_rom_blob(acpi_build_update, build_state, tables.linker->cmd_blob, ++ "etc/table-loader"); ++ ++ fw_cfg_add_file(lsms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, ++ tables.tcpalog->data, acpi_data_len(tables.tcpalog)); ++ ++ build_state->rsdp = NULL; ++ build_state->rsdp_mr = acpi_add_rom_blob(acpi_build_update, build_state, tables.rsdp, ++ ACPI_BUILD_RSDP_FILE); ++ ++ qemu_register_reset(acpi_build_reset, build_state); ++ acpi_build_reset(build_state); ++ vmstate_register(NULL, 0, &vmstate_acpi_build, build_state); ++ ++ /* Cleanup tables but don't free the memory: we track it ++ * in build_state. ++ */ ++ acpi_build_tables_cleanup(&tables, false); ++} +diff --git a/hw/loongarch/acpi-build.h b/hw/loongarch/acpi-build.h +new file mode 100644 +index 000000000..a914268bb +--- /dev/null ++++ b/hw/loongarch/acpi-build.h +@@ -0,0 +1,16 @@ ++ ++#ifndef HW_LARCH_ACPI_BUILD_H ++#define HW_LARCH_ACPI_BUILD_H ++ ++#define EFI_ACPI_OEM_ID "LARCH" ++#define EFI_ACPI_OEM_TABLE_ID "LARCH" /* OEM table id 8 bytes long */ ++#define EFI_ACPI_OEM_REVISION 0x00000002 ++#define EFI_ACPI_CREATOR_ID "LINUX" ++#define EFI_ACPI_CREATOR_REVISION 0x01000013 ++ ++#define ACPI_COMPATIBLE_1_0 0 ++#define ACPI_COMPATIBLE_2_0 1 ++ ++void loongarch_acpi_setup(void); ++ ++#endif +diff --git a/hw/loongarch/apic.c b/hw/loongarch/apic.c +new file mode 100644 +index 000000000..d6ba2a2ce +--- /dev/null ++++ b/hw/loongarch/apic.c +@@ -0,0 +1,675 @@ ++/* ++ * Loongarch 3A5000 interrupt controller emulation ++ * ++ * Copyright (C) 2020 Lu Zeng ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ */ ++ ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include "hw/boards.h" ++#include "hw/irq.h" ++#include "hw/loongarch/cpudevs.h" ++#include "hw/sysbus.h" ++#include "qemu/host-utils.h" ++#include "qemu/error-report.h" ++#include "sysemu/kvm.h" ++#include "hw/hw.h" ++#include "hw/irq.h" ++#include "target/loongarch64/cpu.h" ++#include "exec/address-spaces.h" ++#include "hw/loongarch/larch.h" ++#include "migration/vmstate.h" ++ ++#define DEBUG_APIC 0 ++ ++#define DPRINTF(fmt, ...) \ ++do { \ ++ if (DEBUG_APIC) { \ ++ fprintf(stderr, "APIC: " fmt , ## __VA_ARGS__); \ ++ } \ ++} while (0) ++ ++#define APIC_OFFSET 0x400 ++#define APIC_BASE (0x1f010000ULL) ++#define EXTIOI_NODETYPE_START (0x4a0 - APIC_OFFSET) ++#define EXTIOI_NODETYPE_END (0x4c0 - APIC_OFFSET) ++#define EXTIOI_IPMAP_START (0x4c0 - APIC_OFFSET) ++#define EXTIOI_IPMAP_END (0x4c8 - APIC_OFFSET) ++#define EXTIOI_ENABLE_START (0x600 - APIC_OFFSET) ++#define EXTIOI_ENABLE_END (0x620 - APIC_OFFSET) ++#define EXTIOI_BOUNCE_START (0x680 - APIC_OFFSET) ++#define EXTIOI_BOUNCE_END (0x6a0 - APIC_OFFSET) ++#define EXTIOI_ISR_START (0x700 - APIC_OFFSET) ++#define EXTIOI_ISR_END (0x720 - APIC_OFFSET) ++#define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET) ++#define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET) ++#define EXTIOI_COREISR_START (0x10000) ++#define EXTIOI_COREISR_END (EXTIOI_COREISR_START + 0x10000) ++ ++static int ext_irq_pre_save(void *opaque) ++{ ++#ifdef CONFIG_KVM ++ apicState *apic = opaque; ++ struct loongarch_kvm_irqchip *chip; ++ struct kvm_loongarch_ls3a_extirq_state *kstate; ++ int ret, length, i, vcpuid; ++#endif ++ if (!kvm_irqchip_in_kernel()) { ++ return 0; ++ } ++#ifdef CONFIG_KVM ++ length = sizeof(struct loongarch_kvm_irqchip) + ++ sizeof(struct kvm_loongarch_ls3a_extirq_state); ++ chip = g_malloc0(length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS3A_EXTIRQ; ++ chip->len = length; ++ ++ ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); ++ abort(); ++ } ++ ++ kstate = (struct kvm_loongarch_ls3a_extirq_state *)chip->data; ++ for (i = 0; i < EXTIOI_IRQS_BITMAP_SIZE; i++) { ++ apic->ext_en[i] = kstate->ext_en_r.reg_u8[i]; ++ apic->ext_bounce[i] = kstate->bounce_r.reg_u8[i]; ++ apic->ext_isr[i] = kstate->ext_isr_r.reg_u8[i]; ++ for (vcpuid = 0; vcpuid < MAX_CORES; vcpuid++) { ++ apic->ext_coreisr[vcpuid][i] = kstate->ext_core_isr_r.reg_u8[vcpuid][i]; ++ } ++ } ++ for (i = 0; i < EXTIOI_IRQS_IPMAP_SIZE; i++) { ++ apic->ext_ipmap[i] = kstate->ip_map_r.reg_u8[i]; ++ } ++ for (i = 0; i < EXTIOI_IRQS; i++) { ++ apic->ext_coremap[i] = kstate->core_map_r.reg_u8[i];; ++ } ++ for (i = 0; i < 16; i++) { ++ apic->ext_nodetype[i] = kstate->node_type_r.reg_u16[i]; ++ } ++ g_free(chip); ++#endif ++ return 0; ++} ++ ++static int ext_irq_post_load(void *opaque, int version) ++{ ++#ifdef CONFIG_KVM ++ apicState *apic = opaque; ++ struct loongarch_kvm_irqchip *chip; ++ struct kvm_loongarch_ls3a_extirq_state *kstate; ++ int ret, length, i, vcpuid; ++#endif ++ if (!kvm_irqchip_in_kernel()) { ++ return 0; ++ } ++#ifdef CONFIG_KVM ++ length = sizeof(struct loongarch_kvm_irqchip) + ++ sizeof(struct kvm_loongarch_ls3a_extirq_state); ++ chip = g_malloc0(length); ++ ++ chip->chip_id = KVM_IRQCHIP_LS3A_EXTIRQ; ++ chip->len = length; ++ ++ kstate = (struct kvm_loongarch_ls3a_extirq_state *)chip->data; ++ for (i = 0; i < EXTIOI_IRQS_BITMAP_SIZE; i++) { ++ kstate->ext_en_r.reg_u8[i] = apic->ext_en[i]; ++ kstate->bounce_r.reg_u8[i] = apic->ext_bounce[i]; ++ kstate->ext_isr_r.reg_u8[i] = apic->ext_isr[i]; ++ for (vcpuid = 0; vcpuid < MAX_CORES; vcpuid++) { ++ kstate->ext_core_isr_r.reg_u8[vcpuid][i] = apic->ext_coreisr[vcpuid][i]; ++ } ++ } ++ for (i = 0; i < EXTIOI_IRQS_IPMAP_SIZE; i++) { ++ kstate->ip_map_r.reg_u8[i] = apic->ext_ipmap[i]; ++ } ++ for (i = 0; i < EXTIOI_IRQS; i++) { ++ kstate->core_map_r.reg_u8[i] = apic->ext_coremap[i]; ++ } ++ for (i = 0; i < 16; i++) { ++ kstate->node_type_r.reg_u16[i] = apic->ext_nodetype[i]; ++ } ++ ++ ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_SET_IRQCHIP failed: %s\n", strerror(ret)); ++ abort(); ++ } ++ g_free(chip); ++#endif ++ return 0; ++} ++typedef struct nodeApicState { ++ unsigned long addr; ++ int nodeid; ++ apicState *apic; ++} nodeApicState; ++ ++static void ioapic_update_irq(void *opaque, int irq, int level) ++{ ++ apicState *s = opaque; ++ uint8_t ipnum, cpu, cpu_ipnum; ++ unsigned long found1, found2; ++ uint8_t reg_count, reg_bit; ++ ++ reg_count = irq / 32; ++ reg_bit = irq % 32; ++ ++ ipnum = s->ext_sw_ipmap[irq]; ++ cpu = s->ext_sw_coremap[irq]; ++ cpu_ipnum = cpu * LS3A_INTC_IP + ipnum; ++ if (level == 1) { ++ if (test_bit(reg_bit, ((void *)s->ext_en + 0x4 * reg_count)) == false) { ++ return; ++ } ++ ++ if (test_bit(reg_bit, ((void *)s->ext_isr + 0x4 * reg_count)) == false) { ++ return; ++ } ++ bitmap_set(((void *)s->ext_coreisr[cpu] + 0x4 * reg_count), reg_bit, 1); ++ found1 = find_next_bit(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), ++ EXTIOI_IRQS, 0); ++ bitmap_set(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), reg_bit, 1); ++ if (found1 >= EXTIOI_IRQS) { ++ qemu_set_irq(s->parent_irq[cpu][ipnum], level); ++ } ++ } else { ++ bitmap_clear(((void *)s->ext_isr + 0x4 * reg_count), reg_bit, 1); ++ bitmap_clear(((void *)s->ext_coreisr[cpu] + 0x4 * reg_count), reg_bit, 1); ++ found1 = find_next_bit(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), ++ EXTIOI_IRQS, 0); ++ found1 += reg_count * 32; ++ bitmap_clear(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), reg_bit, 1); ++ found2 = find_next_bit(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), ++ EXTIOI_IRQS, 0); ++ if ((found1 < EXTIOI_IRQS) && (found2 >= EXTIOI_IRQS)) { ++ qemu_set_irq(s->parent_irq[cpu][ipnum], level); ++ } ++ } ++} ++ ++static void ioapic_setirq(void *opaque, int irq, int level) ++{ ++ apicState *s = opaque; ++ uint8_t reg_count, reg_bit; ++ ++ reg_count = irq / 32; ++ reg_bit = irq % 32; ++ ++ if (level) { ++ bitmap_set(((void *)s->ext_isr + 0x4 * reg_count), reg_bit, 1); ++ } else { ++ bitmap_clear(((void *)s->ext_isr + 0x4 * reg_count), reg_bit, 1); ++ } ++ ++ ioapic_update_irq(s, irq, level); ++} ++ ++static uint32_t apic_readb(void *opaque, hwaddr addr) ++{ ++ nodeApicState *node; ++ apicState *state; ++ unsigned long off; ++ uint8_t ret; ++ int cpu; ++ ++ node = (nodeApicState *)opaque; ++ state = node->apic; ++ off = addr & 0xfffff; ++ ret = 0; ++ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { ++ off -= EXTIOI_ENABLE_START; ++ ret = *(uint8_t *)((void *)state->ext_en + off); ++ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { ++ off -= EXTIOI_BOUNCE_START; ++ ret = *(uint8_t *)((void *)state->ext_bounce + off); ++ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { ++ off -= EXTIOI_ISR_START; ++ ret = *(uint8_t *)((void *)state->ext_isr + off); ++ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { ++ off -= EXTIOI_COREISR_START; ++ cpu = (off >> 8) & 0xff; ++ ret = *(uint8_t *)((void *)state->ext_coreisr[cpu] + (off & 0x1f)); ++ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { ++ off -= EXTIOI_IPMAP_START; ++ ret = *(uint8_t *)((void *)state->ext_ipmap + off); ++ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { ++ off -= EXTIOI_COREMAP_START; ++ ret = *(uint8_t *)((void *)state->ext_coremap + off); ++ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { ++ off -= EXTIOI_NODETYPE_START; ++ ret = *(uint8_t *)((void *)state->ext_nodetype + off); ++ } ++ ++ DPRINTF("readb reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, ret); ++ return ret; ++} ++ ++static uint32_t apic_readw(void *opaque, hwaddr addr) ++{ ++ nodeApicState *node; ++ apicState *state; ++ unsigned long off; ++ uint16_t ret; ++ int cpu; ++ ++ node = (nodeApicState *)opaque; ++ state = node->apic; ++ off = addr & 0xfffff; ++ ret = 0; ++ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { ++ off -= EXTIOI_ENABLE_START; ++ ret = *(uint16_t *)((void *)state->ext_en + off); ++ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { ++ off -= EXTIOI_BOUNCE_START; ++ ret = *(uint16_t *)((void *)state->ext_bounce + off); ++ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { ++ off -= EXTIOI_ISR_START; ++ ret = *(uint16_t *)((void *)state->ext_isr + off); ++ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { ++ off -= EXTIOI_COREISR_START; ++ cpu = (off >> 8) & 0xff; ++ ret = *(uint16_t *)((void *)state->ext_coreisr[cpu] + (off & 0x1f)); ++ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { ++ off -= EXTIOI_IPMAP_START; ++ ret = *(uint16_t *)((void *)state->ext_ipmap + off); ++ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { ++ off -= EXTIOI_COREMAP_START; ++ ret = *(uint16_t *)((void *)state->ext_coremap + off); ++ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { ++ off -= EXTIOI_NODETYPE_START; ++ ret = *(uint16_t *)((void *)state->ext_nodetype + off); ++ } ++ ++ DPRINTF("readw reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, ret); ++ return ret; ++} ++ ++static uint32_t apic_readl(void *opaque, hwaddr addr) ++{ ++ nodeApicState *node; ++ apicState *state; ++ unsigned long off; ++ uint32_t ret; ++ int cpu; ++ ++ node = (nodeApicState *)opaque; ++ state = node->apic; ++ off = addr & 0xfffff; ++ ret = 0; ++ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { ++ off -= EXTIOI_ENABLE_START; ++ ret = *(uint32_t *)((void *)state->ext_en + off); ++ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { ++ off -= EXTIOI_BOUNCE_START; ++ ret = *(uint32_t *)((void *)state->ext_bounce + off); ++ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { ++ off -= EXTIOI_ISR_START; ++ ret = *(uint32_t *)((void *)state->ext_isr + off); ++ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { ++ off -= EXTIOI_COREISR_START; ++ cpu = (off >> 8) & 0xff; ++ ret = *(uint32_t *)((void *)state->ext_coreisr[cpu] + (off & 0x1f)); ++ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { ++ off -= EXTIOI_IPMAP_START; ++ ret = *(uint32_t *)((void *)state->ext_ipmap + off); ++ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { ++ off -= EXTIOI_COREMAP_START; ++ ret = *(uint32_t *)((void *)state->ext_coremap + off); ++ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { ++ off -= EXTIOI_NODETYPE_START; ++ ret = *(uint32_t *)((void *)state->ext_nodetype + off); ++ } ++ ++ DPRINTF("readl reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, ret); ++ return ret; ++ ++} ++ ++static void apic_writeb(void *opaque, hwaddr addr, uint32_t val) ++{ ++ nodeApicState *node; ++ apicState *state; ++ unsigned long off; ++ uint8_t old; ++ int cpu, i, ipnum, level, mask; ++ ++ node = (nodeApicState *)opaque; ++ state = node->apic; ++ off = addr & 0xfffff; ++ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { ++ off -= EXTIOI_ENABLE_START; ++ old = *(uint8_t *)((void *)state->ext_en + off); ++ if (old != val) { ++ *(uint8_t *)((void *)state->ext_en + off) = val; ++ old = old ^ val; ++ mask = 0x1; ++ for (i = 0; i < 8; i++) { ++ if (old & mask) { ++ level = !!(val & (0x1 << i)); ++ ioapic_update_irq(state, i + off * 8, level); ++ } ++ mask = mask << 1; ++ } ++ } ++ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { ++ off -= EXTIOI_BOUNCE_START; ++ *(uint8_t *)((void *)state->ext_bounce + off) = val; ++ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { ++ off -= EXTIOI_ISR_START; ++ old = *(uint8_t *)((void *)state->ext_isr + off); ++ *(uint8_t *)((void *)state->ext_isr + off) = old & ~val; ++ mask = 0x1; ++ for (i = 0; i < 8; i++) { ++ if ((old & mask) && (val & mask)) { ++ ioapic_update_irq(state, i + off * 8, 0); ++ } ++ mask = mask << 1; ++ } ++ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { ++ off -= EXTIOI_COREISR_START; ++ cpu = (off >> 8) & 0xff; ++ off = off & 0x1f; ++ old = *(uint8_t *)((void *)state->ext_coreisr[cpu] + off); ++ *(uint8_t *)((void *)state->ext_coreisr[cpu] + off) = old & ~val; ++ mask = 0x1; ++ for (i = 0; i < 8; i++) { ++ if ((old & mask) && (val & mask)) { ++ ioapic_update_irq(state, i + off * 8, 0); ++ } ++ mask = mask << 1; ++ } ++ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { ++ off -= EXTIOI_IPMAP_START; ++ val = val & 0xf; ++ *(uint8_t *)((void *)state->ext_ipmap + off) = val; ++ ipnum = 0; ++ for (i = 0; i < 4; i++) { ++ if (val & (0x1 << i)) { ++ ipnum = i; ++ break; ++ } ++ } ++ if (val) { ++ for (i = 0; i < 32; i++) { ++ cpu = off * 32 + i; ++ state->ext_sw_ipmap[cpu] = ipnum; ++ } ++ } ++ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { ++ off -= EXTIOI_COREMAP_START; ++ val = val & 0xff; ++ *(uint8_t *)((void *)state->ext_coremap + off) = val; ++ state->ext_sw_coremap[off] = val; ++ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { ++ off -= EXTIOI_NODETYPE_START; ++ *(uint8_t *)((void *)state->ext_nodetype + off) = val; ++ } ++ ++ DPRINTF("writeb reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, val); ++} ++ ++static void apic_writew(void *opaque, hwaddr addr, uint32_t val) ++{ ++ nodeApicState *node; ++ apicState *state; ++ unsigned long off; ++ uint16_t old; ++ int cpu, i, level, mask; ++ ++ node = (nodeApicState *)opaque; ++ state = node->apic; ++ off = addr & 0xfffff; ++ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { ++ off -= EXTIOI_ENABLE_START; ++ old = *(uint16_t *)((void *)state->ext_en + off); ++ if (old != val) { ++ *(uint16_t *)((void *)state->ext_en + off) = val; ++ old = old ^ val; ++ mask = 0x1; ++ for (i = 0; i < 16; i++) { ++ if (old & mask) { ++ level = !!(val & (0x1 << i)); ++ ioapic_update_irq(state, i + off * 8, level); ++ } ++ mask = mask << 1; ++ } ++ } ++ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { ++ off -= EXTIOI_BOUNCE_START; ++ *(uint16_t *)((void *)state->ext_bounce + off) = val; ++ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { ++ off -= EXTIOI_ISR_START; ++ old = *(uint16_t *)((void *)state->ext_isr + off); ++ *(uint16_t *)((void *)state->ext_isr + off) = old & ~val; ++ mask = 0x1; ++ for (i = 0; i < 16; i++) { ++ if ((old & mask) && (val & mask)) { ++ ioapic_update_irq(state, i + off * 8, 0); ++ } ++ mask = mask << 1; ++ } ++ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { ++ off -= EXTIOI_COREISR_START; ++ cpu = (off >> 8) & 0xff; ++ off = off & 0x1f; ++ old = *(uint16_t *)((void *)state->ext_coreisr[cpu] + off); ++ *(uint16_t *)((void *)state->ext_coreisr[cpu] + off) = old & ~val; ++ mask = 0x1; ++ for (i = 0; i < 16; i++) { ++ if ((old & mask) && (val & mask)) { ++ ioapic_update_irq(state, i + off * 8, 0); ++ } ++ mask = mask << 1; ++ } ++ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { ++ apic_writeb(opaque, addr, val & 0xff); ++ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); ++ ++ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { ++ apic_writeb(opaque, addr, val & 0xff); ++ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); ++ ++ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { ++ off -= EXTIOI_NODETYPE_START; ++ *(uint16_t *)((void *)state->ext_nodetype + off) = val; ++ } ++ ++ DPRINTF("writew reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, val); ++} ++ ++static void apic_writel(void *opaque, hwaddr addr, uint32_t val) ++{ ++ nodeApicState *node; ++ apicState *state; ++ unsigned long off; ++ uint32_t old; ++ int cpu, i, level, mask; ++ ++ node = (nodeApicState *)opaque; ++ state = node->apic; ++ off = addr & 0xfffff; ++ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { ++ off -= EXTIOI_ENABLE_START; ++ old = *(uint32_t *)((void *)state->ext_en + off); ++ if (old != val) { ++ *(uint32_t *)((void *)state->ext_en + off) = val; ++ old = old ^ val; ++ mask = 0x1; ++ for (i = 0; i < 32; i++) { ++ if (old & mask) { ++ level = !!(val & (0x1 << i)); ++ ioapic_update_irq(state, i + off * 8, level); ++ } ++ mask = mask << 1; ++ } ++ } ++ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { ++ off -= EXTIOI_BOUNCE_START; ++ *(uint32_t *)((void *)state->ext_bounce + off) = val; ++ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { ++ off -= EXTIOI_ISR_START; ++ old = *(uint32_t *)((void *)state->ext_isr + off); ++ *(uint32_t *)((void *)state->ext_isr + off) = old & ~val; ++ mask = 0x1; ++ for (i = 0; i < 32; i++) { ++ if ((old & mask) && (val & mask)) { ++ ioapic_update_irq(state, i + off * 8, 0); ++ } ++ mask = mask << 1; ++ } ++ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { ++ off -= EXTIOI_COREISR_START; ++ cpu = (off >> 8) & 0xff; ++ off = off & 0x1f; ++ old = *(uint32_t *)((void *)state->ext_coreisr[cpu] + off); ++ *(uint32_t *)((void *)state->ext_coreisr[cpu] + off) = old & ~val; ++ mask = 0x1; ++ for (i = 0; i < 32; i++) { ++ if ((old & mask) && (val & mask)) { ++ ioapic_update_irq(state, i + off * 8, 0); ++ } ++ mask = mask << 1; ++ } ++ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { ++ apic_writeb(opaque, addr, val & 0xff); ++ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); ++ apic_writeb(opaque, addr + 2, (val >> 16) & 0xff); ++ apic_writeb(opaque, addr + 3, (val >> 24) & 0xff); ++ ++ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { ++ apic_writeb(opaque, addr, val & 0xff); ++ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); ++ apic_writeb(opaque, addr + 2, (val >> 16) & 0xff); ++ apic_writeb(opaque, addr + 3, (val >> 24) & 0xff); ++ ++ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { ++ off -= EXTIOI_NODETYPE_START; ++ *(uint32_t *)((void *)state->ext_nodetype + off) = val; ++ } ++ ++ DPRINTF("writel reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, val); ++} ++ ++static uint64_t apic_readfn(void *opaque, hwaddr addr, ++ unsigned size) ++{ ++ switch (size) { ++ case 1: ++ return apic_readb(opaque, addr); ++ case 2: ++ return apic_readw(opaque, addr); ++ case 4: ++ return apic_readl(opaque, addr); ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static void apic_writefn(void *opaque, hwaddr addr, ++ uint64_t value, unsigned size) ++{ ++ switch (size) { ++ case 1: ++ apic_writeb(opaque, addr, value); ++ break; ++ case 2: ++ apic_writew(opaque, addr, value); ++ break; ++ case 4: ++ apic_writel(opaque, addr, value); ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static const VMStateDescription vmstate_apic = { ++ .name = "apic", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .pre_save = ext_irq_pre_save, ++ .post_load = ext_irq_post_load, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT8_ARRAY(ext_en, apicState, EXTIOI_IRQS_BITMAP_SIZE), ++ VMSTATE_UINT8_ARRAY(ext_bounce, apicState, EXTIOI_IRQS_BITMAP_SIZE), ++ VMSTATE_UINT8_ARRAY(ext_isr, apicState, EXTIOI_IRQS_BITMAP_SIZE), ++ VMSTATE_UINT8_2DARRAY(ext_coreisr, apicState, MAX_CORES, ++ EXTIOI_IRQS_BITMAP_SIZE), ++ VMSTATE_UINT8_ARRAY(ext_ipmap, apicState, EXTIOI_IRQS_IPMAP_SIZE), ++ VMSTATE_UINT8_ARRAY(ext_coremap, apicState, EXTIOI_IRQS), ++ VMSTATE_UINT16_ARRAY(ext_nodetype, apicState, 16), ++ VMSTATE_UINT64(ext_control, apicState), ++ VMSTATE_UINT8_ARRAY(ext_sw_ipmap, apicState, EXTIOI_IRQS), ++ VMSTATE_UINT8_ARRAY(ext_sw_coremap, apicState, EXTIOI_IRQS), ++ VMSTATE_UINT8_2DARRAY(ext_ipisr, apicState, MAX_CORES * LS3A_INTC_IP, ++ EXTIOI_IRQS_BITMAP_SIZE), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static const MemoryRegionOps apic_ops = { ++ .read = apic_readfn, ++ .write = apic_writefn, ++ .impl.min_access_size = 1, ++ .impl.max_access_size = 4, ++ .valid.min_access_size = 1, ++ .valid.max_access_size = 4, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++}; ++ ++int cpu_init_apic(LoongarchMachineState *ms, CPULOONGARCHState *env, int cpu) ++{ ++ apicState *apic; ++ nodeApicState *node; ++ MemoryRegion *iomem; ++ unsigned long base; ++ int pin; ++ char str[32]; ++ ++ if (ms->apic == NULL) { ++ apic = g_malloc0(sizeof(apicState)); ++ vmstate_register(NULL, 0, &vmstate_apic, apic); ++ apic->irq = qemu_allocate_irqs(ioapic_setirq, apic, EXTIOI_IRQS); ++ ++ for (pin = 0; pin < LS3A_INTC_IP; pin++) { ++ /* cpu_pin[9:2] <= intc_pin[7:0] */ ++ apic->parent_irq[cpu][pin] = env->irq[pin + 2]; ++ } ++ ms->apic = apic; ++ ++ if (cpu == 0) { ++ base = APIC_BASE; ++ node = g_malloc0(sizeof(nodeApicState)); ++ node->apic = ms->apic; ++ node->addr = base; ++ ++ iomem = g_new(MemoryRegion, 1); ++ sprintf(str, "apic%d", cpu); ++ /* extioi addr 0x1f010000~0x1f02ffff */ ++ memory_region_init_io(iomem, NULL, &apic_ops, node, str, 0x20000); ++ memory_region_add_subregion(get_system_memory(), base, iomem); ++ } ++ ++ } else { ++ if (cpu != 0) { ++ for (pin = 0; pin < LS3A_INTC_IP; pin++) { ++ ms->apic->parent_irq[cpu][pin] = env->irq[pin + 2]; ++ } ++ } ++ } ++ return 0; ++} ++ +diff --git a/hw/loongarch/ioapic.c b/hw/loongarch/ioapic.c +new file mode 100644 +index 000000000..3de0ed88d +--- /dev/null ++++ b/hw/loongarch/ioapic.c +@@ -0,0 +1,422 @@ ++/* ++ * LS7A1000 Northbridge IOAPIC support ++ * ++ * Copyright (c) 2019 Loongarch Technology ++ * Authors: ++ * Zhu Chen ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ ++#include "qemu/osdep.h" ++#include "hw/sysbus.h" ++#include "hw/irq.h" ++#include "qemu/log.h" ++#include "sysemu/kvm.h" ++#include "linux/kvm.h" ++#include "migration/vmstate.h" ++ ++#define DEBUG_LS7A_APIC 0 ++ ++#define DPRINTF(fmt, ...) \ ++do { \ ++ if (DEBUG_LS7A_APIC) { \ ++ fprintf(stderr, "IOAPIC: " fmt , ## __VA_ARGS__); \ ++ } \ ++} while (0) ++ ++#define TYPE_LS7A_APIC "ioapic" ++#define LS7A_APIC(obj) OBJECT_CHECK(LS7AApicState, (obj), TYPE_LS7A_APIC) ++ ++#define LS7A_IOAPIC_ROUTE_ENTRY_OFFSET 0x100 ++#define LS7A_IOAPIC_INT_ID_OFFSET 0x00 ++#define LS7A_INT_ID_VAL 0x7000000UL ++#define LS7A_INT_ID_VER 0x1f0001UL ++#define LS7A_IOAPIC_INT_MASK_OFFSET 0x20 ++#define LS7A_IOAPIC_INT_EDGE_OFFSET 0x60 ++#define LS7A_IOAPIC_INT_CLEAR_OFFSET 0x80 ++#define LS7A_IOAPIC_INT_STATUS_OFFSET 0x3a0 ++#define LS7A_IOAPIC_INT_POL_OFFSET 0x3e0 ++#define LS7A_IOAPIC_HTMSI_EN_OFFSET 0x40 ++#define LS7A_IOAPIC_HTMSI_VEC_OFFSET 0x200 ++#define LS7A_AUTO_CTRL0_OFFSET 0xc0 ++#define LS7A_AUTO_CTRL1_OFFSET 0xe0 ++ ++typedef struct LS7AApicState { ++ SysBusDevice parent_obj; ++ qemu_irq parent_irq[257]; ++ uint64_t int_id; ++ uint64_t int_mask; /*0x020 interrupt mask register*/ ++ uint64_t htmsi_en;/*0x040 1=msi*/ ++ uint64_t intedge; /*0x060 edge=1 level =0*/ ++ uint64_t intclr; /*0x080 for clean edge int,set 1 clean,set 0 is noused*/ ++ uint64_t auto_crtl0; /*0x0c0*/ ++ uint64_t auto_crtl1; /*0x0e0*/ ++ uint8_t route_entry[64]; /*0x100 - 0x140*/ ++ uint8_t htmsi_vector[64]; /*0x200 - 0x240*/ ++ uint64_t intisr_chip0; /*0x300*/ ++ uint64_t intisr_chip1;/*0x320*/ ++ uint64_t last_intirr; /* edge detection */ ++ uint64_t intirr; /* 0x380 interrupt request register */ ++ uint64_t intisr; /* 0x3a0 interrupt service register */ ++ uint64_t int_polarity; /*0x3e0 interrupt level polarity ++ selection register 0 for high level tirgger*/ ++ MemoryRegion iomem; ++} LS7AApicState; ++ ++static void update_irq(LS7AApicState *s) ++{ ++ int i; ++ if ((s->intirr & (~s->int_mask)) & (~s->htmsi_en)) { ++ DPRINTF("7a update irqline up\n"); ++ s->intisr = (s->intirr & (~s->int_mask) & (~s->htmsi_en)); ++ qemu_set_irq(s->parent_irq[256], 1); ++ } else { ++ DPRINTF("7a update irqline down\n"); ++ s->intisr &= (~s->htmsi_en); ++ qemu_set_irq(s->parent_irq[256], 0); ++ } ++ if (s->htmsi_en) { ++ for (i = 0; i < 64; i++) { ++ if ((((~s->intisr) & s->intirr) & s->htmsi_en) & (1ULL << i)) { ++ s->intisr |= 1ULL << i; ++ qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], 1); ++ } else if (((~(s->intisr | s->intirr)) & s->htmsi_en) & ++ (1ULL << i)) { ++ qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], 0); ++ } ++ } ++ } ++} ++ ++static void irq_handler(void *opaque, int irq, int level) ++{ ++ LS7AApicState *s = opaque; ++ ++ assert(irq < 64); ++ uint64_t mask = 1ULL << irq; ++ DPRINTF("------ %s irq %d %d\n", __func__, irq, level); ++ ++ if (s->intedge & mask) { ++ /* edge triggered */ ++ /*TODO*/ ++ } else { ++ /* level triggered */ ++ if (level) { ++ s->intirr |= mask; ++ } else { ++ s->intirr &= ~mask; ++ } ++ ++ } ++ update_irq(s); ++ ++} ++ ++static uint64_t ls7a_apic_reg_read(void *opaque, hwaddr addr, unsigned size) ++{ ++ LS7AApicState *a = opaque; ++ uint64_t val = 0; ++ uint64_t offset; ++ int64_t offset_tmp; ++ offset = addr & 0xfff; ++ if (8 == size) { ++ switch (offset) { ++ case LS7A_IOAPIC_INT_ID_OFFSET: ++ val = LS7A_INT_ID_VER; ++ val = (val << 32) + LS7A_INT_ID_VAL; ++ break; ++ case LS7A_IOAPIC_INT_MASK_OFFSET: ++ val = a->int_mask; ++ break; ++ case LS7A_IOAPIC_INT_STATUS_OFFSET: ++ val = a->intisr & (~a->int_mask); ++ break; ++ case LS7A_IOAPIC_INT_EDGE_OFFSET: ++ val = a->intedge; ++ break; ++ case LS7A_IOAPIC_INT_POL_OFFSET: ++ val = a->int_polarity; ++ break; ++ case LS7A_IOAPIC_HTMSI_EN_OFFSET: ++ val = a->htmsi_en; ++ break; ++ case LS7A_AUTO_CTRL0_OFFSET: ++ case LS7A_AUTO_CTRL1_OFFSET: ++ break; ++ default: ++ break; ++ } ++ } else if (1 == size) { ++ if (offset >= LS7A_IOAPIC_HTMSI_VEC_OFFSET) { ++ offset_tmp = offset - LS7A_IOAPIC_HTMSI_VEC_OFFSET; ++ if (offset_tmp >= 0 && offset_tmp < 64) { ++ val = a->htmsi_vector[offset_tmp]; ++ } ++ } else if (offset >= LS7A_IOAPIC_ROUTE_ENTRY_OFFSET) { ++ offset_tmp = offset - LS7A_IOAPIC_ROUTE_ENTRY_OFFSET; ++ if (offset_tmp >= 0 && offset_tmp < 64) { ++ val = a->route_entry[offset_tmp]; ++ DPRINTF("addr %lx val %lx\n", addr, val); ++ } ++ } ++ } ++ DPRINTF(TARGET_FMT_plx" val %lx\n", addr, val); ++ return val; ++} ++ ++static void ls7a_apic_reg_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) ++{ ++ LS7AApicState *a = opaque; ++ int64_t offset_tmp; ++ uint64_t offset; ++ offset = addr & 0xfff; ++ DPRINTF(TARGET_FMT_plx" size %d val %lx\n", addr, size, data); ++ if (8 == size) { ++ switch (offset) { ++ case LS7A_IOAPIC_INT_MASK_OFFSET: ++ a->int_mask = data; ++ update_irq(a); ++ break; ++ case LS7A_IOAPIC_INT_STATUS_OFFSET: ++ a->intisr = data; ++ break; ++ case LS7A_IOAPIC_INT_EDGE_OFFSET: ++ a->intedge = data; ++ break; ++ case LS7A_IOAPIC_INT_CLEAR_OFFSET: ++ a->intisr &= (~data); ++ update_irq(a); ++ break; ++ case LS7A_IOAPIC_INT_POL_OFFSET: ++ a->int_polarity = data; ++ break; ++ case LS7A_IOAPIC_HTMSI_EN_OFFSET: ++ a->htmsi_en = data; ++ break; ++ case LS7A_AUTO_CTRL0_OFFSET: ++ case LS7A_AUTO_CTRL1_OFFSET: ++ break; ++ default: ++ break; ++ } ++ } else if (1 == size) { ++ if (offset >= LS7A_IOAPIC_HTMSI_VEC_OFFSET) { ++ offset_tmp = offset - LS7A_IOAPIC_HTMSI_VEC_OFFSET; ++ if (offset_tmp >= 0 && offset_tmp < 64) { ++ a->htmsi_vector[offset_tmp] = (uint8_t)(data & 0xff); ++ } ++ } else if (offset >= LS7A_IOAPIC_ROUTE_ENTRY_OFFSET) { ++ offset_tmp = offset - LS7A_IOAPIC_ROUTE_ENTRY_OFFSET; ++ if (offset_tmp >= 0 && offset_tmp < 64) { ++ a->route_entry[offset_tmp] = (uint8_t)(data & 0xff); ++ } ++ } ++ } ++} ++ ++static const MemoryRegionOps ls7a_apic_ops = { ++ .read = ls7a_apic_reg_read, ++ .write = ls7a_apic_reg_write, ++ .valid = { ++ .min_access_size = 1, ++ .max_access_size = 8, ++ }, ++ .impl = { ++ .min_access_size = 1, ++ .max_access_size = 8, ++ }, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++}; ++ ++static int kvm_ls7a_pre_save(void *opaque) ++{ ++#ifdef CONFIG_KVM ++ LS7AApicState *s = opaque; ++ struct loongarch_kvm_irqchip *chip; ++ struct ls7a_ioapic_state *state; ++ int ret, i, length; ++ ++ if (!kvm_irqchip_in_kernel()) { ++ return 0; ++ } ++ ++ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct ls7a_ioapic_state); ++ chip = g_malloc0(length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS7A_IOAPIC; ++ chip->len = length; ++ ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); ++ abort(); ++ } ++ state = (struct ls7a_ioapic_state *)chip->data; ++ s->int_id = state->int_id; ++ s->int_mask = state->int_mask; ++ s->htmsi_en = state->htmsi_en; ++ s->intedge = state->intedge; ++ s->intclr = state->intclr; ++ s->auto_crtl0 = state->auto_crtl0; ++ s->auto_crtl1 = state->auto_crtl1; ++ for (i = 0; i < 64; i++) { ++ s->route_entry[i] = state->route_entry[i]; ++ s->htmsi_vector[i] = state->htmsi_vector[i]; ++ } ++ s->intisr_chip0 = state->intisr_chip0; ++ s->intisr_chip1 = state->intisr_chip1; ++ s->intirr = state->intirr; ++ s->intisr = state->intisr; ++ s->int_polarity = state->int_polarity; ++ g_free(chip); ++#endif ++ return 0; ++} ++ ++static int kvm_ls7a_post_load(void *opaque, int version) ++{ ++#ifdef CONFIG_KVM ++ LS7AApicState *s = opaque; ++ struct loongarch_kvm_irqchip *chip; ++ struct ls7a_ioapic_state *state; ++ int ret, i, length; ++ ++ if (!kvm_irqchip_in_kernel()) { ++ return 0; ++ } ++ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct ls7a_ioapic_state); ++ chip = g_malloc0(length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS7A_IOAPIC; ++ chip->len = length; ++ ++ state = (struct ls7a_ioapic_state *)chip->data; ++ state->int_id = s->int_id; ++ state->int_mask = s->int_mask; ++ state->htmsi_en = s->htmsi_en; ++ state->intedge = s->intedge; ++ state->intclr = s->intclr; ++ state->auto_crtl0 = s->auto_crtl0; ++ state->auto_crtl1 = s->auto_crtl1; ++ for (i = 0; i < 64; i++) { ++ state->route_entry[i] = s->route_entry[i]; ++ state->htmsi_vector[i] = s->htmsi_vector[i]; ++ } ++ state->intisr_chip0 = s->intisr_chip0; ++ state->intisr_chip1 = s->intisr_chip1; ++ state->last_intirr = 0; ++ state->intirr = s->intirr; ++ state->intisr = s->intisr; ++ state->int_polarity = s->int_polarity; ++ ++ ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); ++ abort(); ++ } ++ g_free(chip); ++#endif ++ return 0; ++} ++ ++static void ls7a_apic_reset(DeviceState *d) ++{ ++ LS7AApicState *s = LS7A_APIC(d); ++ int i; ++ ++ s->int_id = 0x001f000107000000; ++ s->int_mask = 0xffffffffffffffff; ++ s->htmsi_en = 0x0; ++ s->intedge = 0x0; ++ s->intclr = 0x0; ++ s->auto_crtl0 = 0x0; ++ s->auto_crtl1 = 0x0; ++ for (i = 0; i < 64; i++) { ++ s->route_entry[i] = 0x1; ++ s->htmsi_vector[i] = 0x0; ++ } ++ s->intisr_chip0 = 0x0; ++ s->intisr_chip1 = 0x0; ++ s->intirr = 0x0; ++ s->intisr = 0x0; ++ s->int_polarity = 0x0; ++ kvm_ls7a_post_load(s, 0); ++} ++ ++static void ls7a_apic_init(Object *obj) ++{ ++ DeviceState *dev = DEVICE(obj); ++ LS7AApicState *s = LS7A_APIC(obj); ++ SysBusDevice *sbd = SYS_BUS_DEVICE(obj); ++ int tmp; ++ memory_region_init_io(&s->iomem, obj, &ls7a_apic_ops, s, TYPE_LS7A_APIC, 0x1000); ++ sysbus_init_mmio(sbd, &s->iomem); ++ for (tmp = 0; tmp < 257; tmp++) { ++ sysbus_init_irq(sbd, &s->parent_irq[tmp]); ++ } ++ qdev_init_gpio_in(dev, irq_handler, 64); ++} ++ ++static const VMStateDescription vmstate_ls7a_apic = { ++ .name = TYPE_LS7A_APIC, ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .pre_save = kvm_ls7a_pre_save, ++ .post_load = kvm_ls7a_post_load, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT64(int_mask, LS7AApicState), ++ VMSTATE_UINT64(htmsi_en, LS7AApicState), ++ VMSTATE_UINT64(intedge, LS7AApicState), ++ VMSTATE_UINT64(intclr, LS7AApicState), ++ VMSTATE_UINT64(auto_crtl0, LS7AApicState), ++ VMSTATE_UINT64(auto_crtl1, LS7AApicState), ++ VMSTATE_UINT8_ARRAY(route_entry, LS7AApicState, 64), ++ VMSTATE_UINT8_ARRAY(htmsi_vector, LS7AApicState, 64), ++ VMSTATE_UINT64(intisr_chip0, LS7AApicState), ++ VMSTATE_UINT64(intisr_chip1, LS7AApicState), ++ VMSTATE_UINT64(last_intirr, LS7AApicState), ++ VMSTATE_UINT64(intirr, LS7AApicState), ++ VMSTATE_UINT64(intisr, LS7AApicState), ++ VMSTATE_UINT64(int_polarity, LS7AApicState), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static void ls7a_apic_class_init(ObjectClass *klass, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(klass); ++ ++ dc->reset = ls7a_apic_reset; ++ dc->vmsd = &vmstate_ls7a_apic; ++} ++ ++static const TypeInfo ls7a_apic_info = { ++ .name = TYPE_LS7A_APIC, ++ .parent = TYPE_SYS_BUS_DEVICE, ++ .instance_size = sizeof(LS7AApicState), ++ .instance_init = ls7a_apic_init, ++ .class_init = ls7a_apic_class_init, ++}; ++ ++static void ls7a_apic_register_types(void) ++{ ++ type_register_static(&ls7a_apic_info); ++} ++ ++type_init(ls7a_apic_register_types) +diff --git a/hw/loongarch/iocsr.c b/hw/loongarch/iocsr.c +new file mode 100644 +index 000000000..14521c2d5 +--- /dev/null ++++ b/hw/loongarch/iocsr.c +@@ -0,0 +1,219 @@ ++/* ++ * LOONGARCH IOCSR support ++ * ++ * Copyright (c) 2021 Loongarch Technology ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ ++#include "qemu/osdep.h" ++#include "hw/sysbus.h" ++#include "qemu/log.h" ++#include "sysemu/kvm.h" ++#include "linux/kvm.h" ++#include "migration/vmstate.h" ++#include "hw/boards.h" ++#include "hw/loongarch/larch.h" ++ ++#define BIT_ULL(nr) (1ULL << (nr)) ++#define LOONGARCH_IOCSR_FEATURES 0x8 ++#define IOCSRF_TEMP BIT_ULL(0) ++#define IOCSRF_NODECNT BIT_ULL(1) ++#define IOCSRF_MSI BIT_ULL(2) ++#define IOCSRF_EXTIOI BIT_ULL(3) ++#define IOCSRF_CSRIPI BIT_ULL(4) ++#define IOCSRF_FREQCSR BIT_ULL(5) ++#define IOCSRF_FREQSCALE BIT_ULL(6) ++#define IOCSRF_DVFSV1 BIT_ULL(7) ++#define IOCSRF_GMOD BIT_ULL(9) ++#define IOCSRF_VM BIT_ULL(11) ++#define LOONGARCH_IOCSR_VENDOR 0x10 ++#define LOONGARCH_IOCSR_CPUNAME 0x20 ++#define LOONGARCH_IOCSR_NODECNT 0x408 ++#define LOONGARCH_IOCSR_MISC_FUNC 0x420 ++#define IOCSR_MISC_FUNC_TIMER_RESET BIT_ULL(21) ++#define IOCSR_MISC_FUNC_EXT_IOI_EN BIT_ULL(48) ++ ++enum { ++ IOCSR_FEATURES, ++ IOCSR_VENDOR, ++ IOCSR_CPUNAME, ++ IOCSR_NODECNT, ++ IOCSR_MISC_FUNC, ++ IOCSR_MAX ++}; ++ ++static uint32_t iocsr_array[IOCSR_MAX] = { ++ [IOCSR_FEATURES] = LOONGARCH_IOCSR_FEATURES, ++ [IOCSR_VENDOR] = LOONGARCH_IOCSR_VENDOR, ++ [IOCSR_CPUNAME] = LOONGARCH_IOCSR_CPUNAME, ++ [IOCSR_NODECNT] = LOONGARCH_IOCSR_NODECNT, ++ [IOCSR_MISC_FUNC] = LOONGARCH_IOCSR_MISC_FUNC, ++}; ++ ++ ++#define TYPE_IOCSR "iocsr" ++#define IOCSR(obj) OBJECT_CHECK(IOCSRState, (obj), TYPE_IOCSR) ++ ++typedef struct IOCSRState { ++ SysBusDevice parent_obj; ++ uint64_t iocsr_val[IOCSR_MAX]; ++} IOCSRState; ++ ++IOCSRState iocsr_init = { ++ .iocsr_val = { ++ IOCSRF_NODECNT | IOCSRF_MSI | IOCSRF_EXTIOI ++ | IOCSRF_CSRIPI | IOCSRF_GMOD | IOCSRF_VM, ++ 0x6e6f73676e6f6f4c, /* Loongson */ ++ 0x303030354133, /*3A5000*/ ++ 0x4, ++ 0x0, ++ } ++}; ++ ++static int kvm_iocsr_pre_save(void *opaque) ++{ ++#ifdef CONFIG_KVM ++ IOCSRState *s = opaque; ++ struct kvm_iocsr_entry entry; ++ int i = 0; ++ for (i = 0; i < IOCSR_MAX; i++) { ++ entry.addr = iocsr_array[i]; ++ kvm_vm_ioctl(kvm_state, KVM_LOONGARCH_GET_IOCSR, &entry); ++ s->iocsr_val[i] = entry.data; ++ } ++#endif ++ return 0; ++} ++ ++static int kvm_iocsr_post_load(void *opaque, int version) ++{ ++#ifdef CONFIG_KVM ++ IOCSRState *s = opaque; ++ struct kvm_iocsr_entry entry; ++ int i = 0; ++ ++ if (!kvm_enabled()) { ++ return 0; ++ } ++ ++ for (i = 0; i < IOCSR_MAX; i++) { ++ entry.addr = iocsr_array[i]; ++ entry.data = s->iocsr_val[i]; ++ kvm_vm_ioctl(kvm_state, KVM_LOONGARCH_SET_IOCSR, &entry); ++ } ++#endif ++ return 0; ++} ++ ++static void iocsr_reset(DeviceState *d) ++{ ++ IOCSRState *s = IOCSR(d); ++ int i; ++ ++ for (i = 0; i < IOCSR_MAX; i++) { ++ s->iocsr_val[i] = iocsr_init.iocsr_val[i]; ++ } ++ kvm_iocsr_post_load(s, 0); ++} ++static void init_vendor_cpuname(uint64_t *vendor, ++ uint64_t *cpu_name, char *cpuname) ++{ ++ int i = 0, len = 0; ++ char *index = NULL, *index_end = NULL; ++ char *vendor_c = (char *)vendor; ++ char *cpu_name_c = (char *)cpu_name; ++ ++ index = strstr(cpuname, "-"); ++ len = strlen(cpuname); ++ if ((index == NULL) || (len <= 0)) { ++ return ; ++ } ++ ++ *vendor = 0; ++ *cpu_name = 0; ++ index_end = cpuname + len; ++ ++ while (((cpuname + i) < index) && (i < sizeof(uint64_t))) { ++ vendor_c[i] = cpuname[i]; ++ i++; ++ } ++ ++ index += 1; ++ i = 0; ++ ++ while (((index + i) < index_end) && (i < sizeof(uint64_t))) { ++ cpu_name_c[i] = index[i]; ++ i++; ++ } ++ ++ return ; ++} ++ ++static void iocsr_instance_init(Object *obj) ++{ ++ IOCSRState *s = IOCSR(obj); ++ int i; ++ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ ++ init_vendor_cpuname((uint64_t *)&iocsr_init.iocsr_val[IOCSR_VENDOR], ++ (uint64_t *)&iocsr_init.iocsr_val[IOCSR_CPUNAME], ++ lsmc->cpu_name); ++ ++ for (i = 0; i < IOCSR_MAX; i++) { ++ s->iocsr_val[i] = iocsr_init.iocsr_val[i]; ++ } ++} ++ ++static const VMStateDescription vmstate_iocsr = { ++ .name = TYPE_IOCSR, ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .pre_save = kvm_iocsr_pre_save, ++ .post_load = kvm_iocsr_post_load, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT64_ARRAY(iocsr_val, IOCSRState, IOCSR_MAX), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static void iocsr_class_init(ObjectClass *klass, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(klass); ++ ++ dc->reset = iocsr_reset; ++ dc->vmsd = &vmstate_iocsr; ++ ++} ++ ++static const TypeInfo iocsr_info = { ++ .name = TYPE_IOCSR, ++ .parent = TYPE_SYS_BUS_DEVICE, ++ .instance_size = sizeof(IOCSRState), ++ .instance_init = iocsr_instance_init, ++ .class_init = iocsr_class_init, ++}; ++ ++static void iocsr_register_types(void) ++{ ++ type_register_static(&iocsr_info); ++} ++ ++type_init(iocsr_register_types) +diff --git a/hw/loongarch/ipi.c b/hw/loongarch/ipi.c +new file mode 100644 +index 000000000..ade182abc +--- /dev/null ++++ b/hw/loongarch/ipi.c +@@ -0,0 +1,267 @@ ++#include "qemu/osdep.h" ++#include "qemu/units.h" ++#include "qapi/error.h" ++#include "hw/hw.h" ++#include "hw/irq.h" ++#include "hw/loongarch/cpudevs.h" ++#include "sysemu/sysemu.h" ++#include "sysemu/cpus.h" ++#include "sysemu/kvm.h" ++#include "hw/core/cpu.h" ++#include "qemu/log.h" ++#include "hw/loongarch/bios.h" ++#include "elf.h" ++#include "linux/kvm.h" ++#include "hw/loongarch/larch.h" ++#include "hw/loongarch/ls7a.h" ++#include "migration/vmstate.h" ++ ++static int gipi_pre_save(void *opaque) ++{ ++#ifdef CONFIG_KVM ++ gipiState *state = opaque; ++ struct loongarch_gipiState *kstate; ++ struct loongarch_kvm_irqchip *chip; ++ int ret, i, j, length; ++#endif ++ ++ if (!kvm_irqchip_in_kernel()) { ++ return 0; ++ } ++ ++#ifdef CONFIG_KVM ++ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct loongarch_gipiState); ++ chip = g_malloc0(length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS3A_GIPI; ++ chip->len = length; ++ ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); ++ abort(); ++ } ++ ++ kstate = (struct loongarch_gipiState *)chip->data; ++ ++ for (i = 0; i < MAX_GIPI_CORE_NUM; i++) { ++ state->core[i].status = kstate->core[i].status; ++ state->core[i].en = kstate->core[i].en; ++ state->core[i].set = kstate->core[i].set; ++ state->core[i].clear = kstate->core[i].clear; ++ for (j = 0; j < MAX_GIPI_MBX_NUM; j++) { ++ state->core[i].buf[j] = kstate->core[i].buf[j]; ++ } ++ } ++ g_free(chip); ++#endif ++ ++ return 0; ++} ++ ++static int gipi_post_load(void *opaque, int version) ++{ ++#ifdef CONFIG_KVM ++ gipiState *state = opaque; ++ struct loongarch_gipiState *kstate; ++ struct loongarch_kvm_irqchip *chip; ++ int ret, i, j, length; ++#endif ++ ++ if (!kvm_irqchip_in_kernel()) { ++ return 0; ++ } ++ ++#ifdef CONFIG_KVM ++ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct loongarch_gipiState); ++ chip = g_malloc0(length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS3A_GIPI; ++ chip->len = length; ++ kstate = (struct loongarch_gipiState *)chip->data; ++ ++ for (i = 0; i < MAX_GIPI_CORE_NUM; i++) { ++ kstate->core[i].status = state->core[i].status; ++ kstate->core[i].en = state->core[i].en; ++ kstate->core[i].set = state->core[i].set; ++ kstate->core[i].clear = state->core[i].clear; ++ for (j = 0; j < MAX_GIPI_MBX_NUM; j++) { ++ kstate->core[i].buf[j] = state->core[i].buf[j]; ++ } ++ } ++ ++ ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); ++ if (ret < 0) { ++ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); ++ abort(); ++ } ++ g_free(chip); ++#endif ++ ++ return 0; ++} ++ ++static const VMStateDescription vmstate_gipi_core = { ++ .name = "gipi-single", ++ .version_id = 0, ++ .minimum_version_id = 0, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT32(status, gipi_core), ++ VMSTATE_UINT32(en, gipi_core), ++ VMSTATE_UINT32(set, gipi_core), ++ VMSTATE_UINT32(clear, gipi_core), ++ VMSTATE_UINT64_ARRAY(buf, gipi_core, MAX_GIPI_MBX_NUM), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static const VMStateDescription vmstate_gipi = { ++ .name = "gipi", ++ .pre_save = gipi_pre_save, ++ .post_load = gipi_post_load, ++ .version_id = 0, ++ .minimum_version_id = 0, ++ .fields = (VMStateField[]) { ++ VMSTATE_STRUCT_ARRAY(core, gipiState, MAX_GIPI_CORE_NUM, 0, ++ vmstate_gipi_core, gipi_core), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++ ++static void gipi_writel(void *opaque, hwaddr addr, uint64_t val, unsigned size) ++{ ++ gipi_core *s = opaque; ++ gipi_core *ss; ++ void *pbuf; ++ uint32_t cpu, action_data, mailaddr; ++ LoongarchMachineState *ms = LoongarchMACHINE(qdev_get_machine()); ++ ++ if ((size != 4) && (size != 8)) { ++ hw_error("size not 4 and not 8"); ++ } ++ addr &= 0xff; ++ switch (addr) { ++ case CORE0_STATUS_OFF: ++ hw_error("CORE0_STATUS_OFF Can't be write\n"); ++ break; ++ case CORE0_EN_OFF: ++ s->en = val; ++ break; ++ case CORE0_IPI_SEND: ++ cpu = (val >> 16) & 0x3ff; ++ action_data = 1UL << (val & 0x1f); ++ ss = &ms->gipi->core[cpu]; ++ ss->status |= action_data; ++ if (ss->status != 0) { ++ qemu_irq_raise(ss->irq); ++ } ++ break; ++ case CORE0_MAIL_SEND: ++ cpu = (val >> 16) & 0x3ff; ++ mailaddr = (val >> 2) & 0x7; ++ ss = &ms->gipi->core[cpu]; ++ pbuf = (void *)ss->buf + mailaddr * 4; ++ *(unsigned int *)pbuf = (val >> 32); ++ break; ++ case CORE0_SET_OFF: ++ hw_error("CORE0_SET_OFF Can't be write\n"); ++ break; ++ case CORE0_CLEAR_OFF: ++ s->status ^= val; ++ if (s->status == 0) { ++ qemu_irq_lower(s->irq); ++ } ++ break; ++ case 0x20 ... 0x3c: ++ pbuf = (void *)s->buf + (addr - 0x20); ++ if (size == 1) { ++ *(unsigned char *)pbuf = (unsigned char)val; ++ } else if (size == 2) { ++ *(unsigned short *)pbuf = (unsigned short)val; ++ } else if (size == 4) { ++ *(unsigned int *)pbuf = (unsigned int)val; ++ } else if (size == 8) { ++ *(unsigned long *)pbuf = (unsigned long)val; ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static uint64_t gipi_readl(void *opaque, hwaddr addr, unsigned size) ++{ ++ gipi_core *s = opaque; ++ uint64_t ret = 0; ++ void *pbuf; ++ ++ addr &= 0xff; ++ if ((size != 4) && (size != 8)) { ++ hw_error("size not 4 and not 8 size:%d\n", size); ++ } ++ switch (addr) { ++ case CORE0_STATUS_OFF: ++ ret = s->status; ++ break; ++ case CORE0_EN_OFF: ++ ret = s->en; ++ break; ++ case CORE0_SET_OFF: ++ ret = 0; ++ break; ++ case CORE0_CLEAR_OFF: ++ ret = 0; ++ break; ++ case 0x20 ... 0x3c: ++ pbuf = (void *)s->buf + (addr - 0x20); ++ if (size == 1) { ++ ret = *(unsigned char *)pbuf; ++ } else if (size == 2) { ++ ret = *(unsigned short *)pbuf; ++ } else if (size == 4) { ++ ret = *(unsigned int *)pbuf; ++ } else if (size == 8) { ++ ret = *(unsigned long *)pbuf; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++static const MemoryRegionOps gipi_ops = { ++ .read = gipi_readl, ++ .write = gipi_writel, ++ .valid = { ++ .min_access_size = 4, ++ .max_access_size = 8, ++ }, ++ .impl = { ++ .min_access_size = 4, ++ .max_access_size = 8, ++ }, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++}; ++ ++int cpu_init_ipi(LoongarchMachineState *ms, qemu_irq parent, int cpu) ++{ ++ hwaddr addr; ++ MemoryRegion *region; ++ char str[32]; ++ ++ if (ms->gipi == NULL) { ++ ms->gipi = g_malloc0(sizeof(gipiState)); ++ vmstate_register(NULL, 0, &vmstate_gipi, ms->gipi); ++ } ++ ++ ms->gipi->core[cpu].irq = parent; ++ ++ addr = SMP_GIPI_MAILBOX | (cpu << 8); ++ region = g_new(MemoryRegion, 1); ++ sprintf(str, "gipi%d", cpu); ++ memory_region_init_io(region, NULL, &gipi_ops, &ms->gipi->core[cpu], str, 0x100); ++ memory_region_add_subregion(get_system_memory(), addr, region); ++ return 0; ++} +diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c +new file mode 100644 +index 000000000..3db269274 +--- /dev/null ++++ b/hw/loongarch/larch_3a.c +@@ -0,0 +1,2026 @@ ++/* ++ * QEMU loongarch 3a develop board emulation ++ * ++ * Copyright (C) 2013-2014 qiaochong ++ * Copyright (C) 2016-2017 zhangshuangshuang ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++#include "qemu/osdep.h" ++#include "qemu/units.h" ++#include "qapi/error.h" ++#include "qemu/datadir.h" ++#include "hw/hw.h" ++#include "hw/loongarch/cpudevs.h" ++#include "hw/i386/pc.h" ++#include "hw/char/serial.h" ++#include "hw/isa/isa.h" ++#include "hw/qdev-core.h" ++#include "sysemu/sysemu.h" ++#include "sysemu/runstate.h" ++#include "sysemu/reset.h" ++#include "migration/vmstate.h" ++#include "sysemu/cpus.h" ++#include "hw/boards.h" ++#include "qemu/log.h" ++#include "hw/loongarch/bios.h" ++#include "hw/loader.h" ++#include "elf.h" ++#include "exec/address-spaces.h" ++#include "hw/ide.h" ++#include "hw/pci/pci_host.h" ++#include "hw/pci/msi.h" ++#include "linux/kvm.h" ++#include "sysemu/kvm.h" ++#include "sysemu/numa.h" ++#include "hw/rtc/mc146818rtc.h" ++#include "hw/irq.h" ++#include "net/net.h" ++#include "hw/timer/i8254.h" ++#include "hw/loongarch/larch.h" ++#include "hw/loongarch/ls7a.h" ++#include "hw/nvram/fw_cfg.h" ++#include "hw/firmware/smbios.h" ++#include "acpi-build.h" ++#include ++#include ++#include "sysemu/block-backend.h" ++#include "hw/block/flash.h" ++#include "sysemu/device_tree.h" ++#include "qapi/visitor.h" ++#include "qapi/qapi-visit-common.h" ++ ++#include ++ ++#define DMA64_SUPPORTED 0x2 ++#define MAX_IDE_BUS 2 ++ ++#define BOOTPARAM_PHYADDR 0x0ff00000ULL ++#define BOOTPARAM_ADDR (0x9000000000000000ULL + BOOTPARAM_PHYADDR) ++#define SMBIOS_PHYSICAL_ADDRESS 0x0fe00000 ++#define SMBIOS_SIZE_LIMIT 0x200000 ++#define RESERVED_SIZE_LIMIT 0x1100000 ++#define COMMAND_LINE_SIZE 4096 ++#define FW_CONF_ADDR 0x0fff0000 ++ ++#define PHYS_TO_VIRT(x) ((x) | 0x9000000000000000ULL) ++ ++#define TARGET_REALPAGE_MASK (TARGET_PAGE_MASK << 2) ++ ++#ifdef CONFIG_KVM ++#define LS_ISA_IO_SIZE 0x02000000 ++#define LS_ISA_MEM_SIZE 0x40000000 ++#else ++#define LS_ISA_IO_SIZE 0x00010000 ++#define LS_ISA_MEM_SIZE 0x01000000 ++#endif ++ ++#ifdef CONFIG_KVM ++#define align(x) (((x) + 63) & ~63) ++#else ++#define align(x) (((x) + 15) & ~15) ++#endif ++ ++#define DEBUG_LOONGARCH3A 0 ++#define FLASH_SECTOR_SIZE 4096 ++ ++#define DPRINTF(fmt, ...) \ ++ do { if (DEBUG_LOONGARCH3A) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0) ++ ++#define DEFINE_LS3A5K_MACHINE(suffix, name, optionfn) \ ++ static void ls3a5k_init_##suffix(MachineState *machine) \ ++ { \ ++ ls3a5k_init(machine); \ ++ } \ ++ DEFINE_LOONGARCH_MACHINE(suffix, name, ls3a5k_init_##suffix, optionfn) ++ ++struct efi_memory_map_loongarch { ++ uint16_t vers; /* version of efi_memory_map */ ++ uint32_t nr_map; /* number of memory_maps */ ++ uint32_t mem_freq; /* memory frequence */ ++ struct mem_map { ++ uint32_t node_id; /* node_id which memory attached to */ ++ uint32_t mem_type; /* system memory, pci memory, pci io, etc. */ ++ uint64_t mem_start; /* memory map start address */ ++ uint32_t mem_size; /* each memory_map size, not the total size */ ++ } map[128]; ++} __attribute__((packed)); ++ ++enum loongarch_cpu_type { ++ Loongson3 = 0x1, ++ Loongson3_comp = 0x2 ++}; ++ ++struct GlobalProperty loongarch_compat[] = { ++ { ++ .driver = "rtl8139", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "e1000", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "virtio-net-pci", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "qxl-vga", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "VGA", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "cirrus-vga", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "virtio-vga", ++ .property = "romfile", ++ .value = "", ++ },{ ++ .driver = "vmware-svga", ++ .property = "romfile", ++ .value = "", ++ }, ++}; ++const size_t loongarch_compat_len = G_N_ELEMENTS(loongarch_compat); ++ ++/* ++ * Capability and feature descriptor structure for LOONGARCH CPU ++ */ ++struct efi_cpuinfo_loongarch { ++ uint16_t vers; /* version of efi_cpuinfo_loongarch */ ++ uint32_t processor_id; /* PRID, e.g. 6305, 6306 */ ++ enum loongarch_cpu_type cputype; /* 3A, 3B, etc. */ ++ uint32_t total_node; /* num of total numa nodes */ ++ uint16_t cpu_startup_core_id; /* Core id */ ++ uint16_t reserved_cores_mask; ++ uint32_t cpu_clock_freq; /* cpu_clock */ ++ uint32_t nr_cpus; ++} __attribute__((packed)); ++ ++#define MAX_UARTS 64 ++struct uart_device { ++ uint32_t iotype; /* see include/linux/serial_core.h */ ++ uint32_t uartclk; ++ uint32_t int_offset; ++ uint64_t uart_base; ++} __attribute__((packed)); ++ ++#define MAX_SENSORS 64 ++#define SENSOR_TEMPER 0x00000001 ++#define SENSOR_VOLTAGE 0x00000002 ++#define SENSOR_FAN 0x00000004 ++struct sensor_device { ++ char name[32]; /* a formal name */ ++ char label[64]; /* a flexible description */ ++ uint32_t type; /* SENSOR_* */ ++ uint32_t id; /* instance id of a sensor-class */ ++ uint32_t fan_policy; /* see arch/loongarch/include/ ++ asm/mach-loongarch/loongarch_hwmon.h */ ++ uint32_t fan_percent;/* only for constant speed policy */ ++ uint64_t base_addr; /* base address of device registers */ ++} __attribute__((packed)); ++ ++struct system_loongarch { ++ uint16_t vers; /* version of system_loongarch */ ++ uint32_t ccnuma_smp; /* 0: no numa; 1: has numa */ ++ uint32_t sing_double_channel;/* 1:single; 2:double */ ++ uint32_t nr_uarts; ++ struct uart_device uarts[MAX_UARTS]; ++ uint32_t nr_sensors; ++ struct sensor_device sensors[MAX_SENSORS]; ++ char has_ec; ++ char ec_name[32]; ++ uint64_t ec_base_addr; ++ char has_tcm; ++ char tcm_name[32]; ++ uint64_t tcm_base_addr; ++ uint64_t workarounds; /* see workarounds.h */ ++} __attribute__((packed)); ++ ++struct irq_source_routing_table { ++ uint16_t vers; ++ uint16_t size; ++ uint16_t rtr_bus; ++ uint16_t rtr_devfn; ++ uint32_t vendor; ++ uint32_t device; ++ uint32_t PIC_type; /* conform use HT or PCI to route to CPU-PIC */ ++ uint64_t ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ ++ uint64_t ht_enable; /* irqs used in this PIC */ ++ uint32_t node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */ ++ uint64_t pci_mem_start_addr; ++ uint64_t pci_mem_end_addr; ++ uint64_t pci_io_start_addr; ++ uint64_t pci_io_end_addr; ++ uint64_t pci_config_addr; ++ uint32_t dma_mask_bits; ++ uint16_t dma_noncoherent; ++} __attribute__((packed)); ++ ++struct interface_info { ++ uint16_t vers; /* version of the specificition */ ++ uint16_t size; ++ uint8_t flag; ++ char description[64]; ++} __attribute__((packed)); ++ ++#define MAX_RESOURCE_NUMBER 128 ++struct resource_loongarch { ++ uint64_t start; /* resource start address */ ++ uint64_t end; /* resource end address */ ++ char name[64]; ++ uint32_t flags; ++}; ++ ++struct archdev_data {}; /* arch specific additions */ ++ ++struct board_devices { ++ char name[64]; /* hold the device name */ ++ uint32_t num_resources; /* number of device_resource */ ++ /* for each device's resource */ ++ struct resource_loongarch resource[MAX_RESOURCE_NUMBER]; ++ /* arch specific additions */ ++ struct archdev_data archdata; ++}; ++ ++struct loongarch_special_attribute { ++ uint16_t vers; /* version of this special */ ++ char special_name[64]; /* special_atribute_name */ ++ uint32_t loongarch_special_type; /* type of special device */ ++ /* for each device's resource */ ++ struct resource_loongarch resource[MAX_RESOURCE_NUMBER]; ++}; ++ ++struct loongarch_params { ++ uint64_t memory_offset; /* efi_memory_map_loongarch struct offset */ ++ uint64_t cpu_offset; /* efi_cpuinfo_loongarch struct offset */ ++ uint64_t system_offset; /* system_loongarch struct offset */ ++ uint64_t irq_offset; /* irq_source_routing_table struct offset */ ++ uint64_t interface_offset; /* interface_info struct offset */ ++ uint64_t special_offset; /* loongarch_special_attribute struct offset */ ++ uint64_t boarddev_table_offset; /* board_devices offset */ ++}; ++ ++struct smbios_tables { ++ uint16_t vers; /* version of smbios */ ++ uint64_t vga_bios; /* vga_bios address */ ++ struct loongarch_params lp; ++}; ++ ++struct efi_reset_system_t { ++ uint64_t ResetCold; ++ uint64_t ResetWarm; ++ uint64_t ResetType; ++ uint64_t Shutdown; ++ uint64_t DoSuspend; /* NULL if not support */ ++}; ++ ++struct efi_loongarch { ++ uint64_t mps; /* MPS table */ ++ uint64_t acpi; /* ACPI table (IA64 ext 0.71) */ ++ uint64_t acpi20; /* ACPI table (ACPI 2.0) */ ++ struct smbios_tables smbios; /* SM BIOS table */ ++ uint64_t sal_systab; /* SAL system table */ ++ uint64_t boot_info; /* boot info table */ ++}; ++ ++struct boot_params { ++ struct efi_loongarch efi; ++ struct efi_reset_system_t reset_system; ++}; ++ ++static struct _loaderparams { ++ unsigned long ram_size; ++ const char *kernel_filename; ++ const char *kernel_cmdline; ++ const char *initrd_filename; ++ unsigned long a0, a1, a2; ++} loaderparams; ++ ++static struct _firmware_config { ++ unsigned long ram_size; ++ unsigned int mem_freq; ++ unsigned int cpu_nr; ++ unsigned int cpu_clock_freq; ++} fw_config; ++ ++struct la_memmap_entry { ++ uint64_t address; ++ uint64_t length; ++ uint32_t type; ++ uint32_t reserved; ++} ; ++ ++static void *boot_params_buf; ++static void *boot_params_p; ++static struct la_memmap_entry *la_memmap_table; ++static unsigned la_memmap_entries; ++ ++CPULOONGARCHState *cpu_states[LOONGARCH_MAX_VCPUS]; ++ ++struct kvm_cpucfg ls3a5k_cpucfgs = { ++ .cpucfg[LOONGARCH_CPUCFG0] = CPUCFG0_3A5000_PRID, ++ .cpucfg[LOONGARCH_CPUCFG1] = CPUCFG1_ISGR64 | CPUCFG1_PAGING | ++ CPUCFG1_IOCSR | CPUCFG1_PABITS | CPUCFG1_VABITS | CPUCFG1_UAL | ++ CPUCFG1_RI | CPUCFG1_XI | CPUCFG1_RPLV | CPUCFG1_HUGEPG | ++ CPUCFG1_IOCSRBRD, ++ .cpucfg[LOONGARCH_CPUCFG2] = CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP | ++ CPUCFG2_FPVERS | CPUCFG2_LSX | CPUCFG2_LASX | CPUCFG2_COMPLEX | ++ CPUCFG2_CRYPTO | CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | CPUCFG2_LSPW | ++ CPUCFG2_LAM, ++ .cpucfg[LOONGARCH_CPUCFG3] = CPUCFG3_CCDMA | CPUCFG3_SFB | CPUCFG3_UCACC | ++ CPUCFG3_LLEXC | CPUCFG3_SCDLY | CPUCFG3_LLDBAR | CPUCFG3_ITLBT | ++ CPUCFG3_ICACHET | CPUCFG3_SPW_LVL | CPUCFG3_SPW_HG_HF | CPUCFG3_RVA | ++ CPUCFG3_RVAMAX, ++ .cpucfg[LOONGARCH_CPUCFG4] = CCFREQ_100M, ++ .cpucfg[LOONGARCH_CPUCFG5] = CPUCFG5_CCMUL | CPUCFG5_CCDIV, ++ .cpucfg[LOONGARCH_CPUCFG6] = CPUCFG6_PMP | CPUCFG6_PAMVER | CPUCFG6_PMNUM | ++ CPUCFG6_PMBITS | CPUCFG6_UPM, ++ .cpucfg[LOONGARCH_CPUCFG16] = CPUCFG16_L1_IUPRE | CPUCFG16_L1_DPRE | ++ CPUCFG16_L2_IUPRE | CPUCFG16_L2_IUUNIFY | CPUCFG16_L2_IUPRIV | ++ CPUCFG16_L3_IUPRE | CPUCFG16_L3_IUUNIFY | CPUCFG16_L3_IUINCL, ++ .cpucfg[LOONGARCH_CPUCFG17] = CPUCFG17_L1I_WAYS_M | CPUCFG17_L1I_SETS_M | ++ CPUCFG17_L1I_SIZE_M, ++ .cpucfg[LOONGARCH_CPUCFG18] = CPUCFG18_L1D_WAYS_M | CPUCFG18_L1D_SETS_M | ++ CPUCFG18_L1D_SIZE_M, ++ .cpucfg[LOONGARCH_CPUCFG19] = CPUCFG19_L2_WAYS_M | CPUCFG19_L2_SETS_M | ++ CPUCFG19_L2_SIZE_M, ++ .cpucfg[LOONGARCH_CPUCFG20] = CPUCFG20_L3_WAYS_M | CPUCFG20_L3_SETS_M | ++ CPUCFG20_L3_SIZE_M, ++}; ++ ++bool loongarch_is_acpi_enabled(LoongarchMachineState *vms) ++{ ++ if (vms->acpi == ON_OFF_AUTO_OFF) { ++ return false; ++ } ++ return true; ++} ++static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(obj); ++ OnOffAuto acpi = lsms->acpi; ++ ++ visit_type_OnOffAuto(v, name, &acpi, errp); ++} ++ ++static void loongarch_set_acpi(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(obj); ++ ++ visit_type_OnOffAuto(v, name, &lsms->acpi, errp); ++} ++int la_memmap_add_entry(uint64_t address, uint64_t length, uint32_t type) ++{ ++ int i; ++ ++ for (i = 0; i < la_memmap_entries; i++) { ++ if (la_memmap_table[i].address == address) { ++ fprintf(stderr, "%s address:0x%lx length:0x%lx already exists\n", ++ __func__, address, length); ++ return 0; ++ } ++ } ++ ++ la_memmap_table = g_renew(struct la_memmap_entry, la_memmap_table, ++ la_memmap_entries + 1); ++ la_memmap_table[la_memmap_entries].address = cpu_to_le64(address); ++ la_memmap_table[la_memmap_entries].length = cpu_to_le64(length); ++ la_memmap_table[la_memmap_entries].type = cpu_to_le32(type); ++ la_memmap_entries++; ++ ++ return la_memmap_entries; ++} ++ ++static ram_addr_t get_hotplug_membase(ram_addr_t ram_size) ++{ ++ ram_addr_t sstart; ++ ++ if (ram_size <= 0x10000000) { ++ sstart = 0x90000000; ++ } else { ++ sstart = 0x90000000 + ROUND_UP((ram_size - 0x10000000), ++ LOONGARCH_HOTPLUG_MEM_ALIGN); ++ } ++ return sstart; ++} ++ ++static struct efi_memory_map_loongarch *init_memory_map(void *g_map) ++{ ++ struct efi_memory_map_loongarch *emap = g_map; ++ ++ emap->nr_map = 4; ++ emap->mem_freq = 266000000; ++ ++ emap->map[0].node_id = 0; ++ emap->map[0].mem_type = 1; ++ emap->map[0].mem_start = 0x0; ++#ifdef CONFIG_KVM ++ emap->map[0].mem_size = (loaderparams.ram_size > 0x10000000 ++ ? 256 : (loaderparams.ram_size >> 20)) - 18; ++#else ++ emap->map[0].mem_size = atoi(getenv("memsize")); ++#endif ++ ++ emap->map[1].node_id = 0; ++ emap->map[1].mem_type = 2; ++ emap->map[1].mem_start = 0x90000000; ++#ifdef CONFIG_KVM ++ emap->map[1].mem_size = (loaderparams.ram_size > 0x10000000 ++ ? (loaderparams.ram_size >> 20) - 256 : 0); ++#else ++ emap->map[1].mem_size = atoi(getenv("highmemsize")); ++#endif ++ ++ /* support for smbios */ ++ emap->map[2].node_id = 0; ++ emap->map[2].mem_type = 10; ++ emap->map[2].mem_start = SMBIOS_PHYSICAL_ADDRESS; ++ emap->map[2].mem_size = SMBIOS_SIZE_LIMIT >> 20; ++ ++ emap->map[3].node_id = 0; ++ emap->map[3].mem_type = 3; ++ emap->map[3].mem_start = 0xee00000; ++ emap->map[3].mem_size = RESERVED_SIZE_LIMIT >> 20; ++ ++ return emap; ++} ++ ++static uint64_t get_host_cpu_freq(void) ++{ ++ int fd = 0; ++ char buf[1024]; ++ uint64_t freq = 0, size = 0; ++ char *buf_p; ++ ++ fd = open("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", O_RDONLY); ++ if (fd == -1) { ++ fprintf(stderr, "/sys/devices/system/cpu/cpu0/cpufreq/ \ ++ cpuinfo_max_freq not exist!\n"); ++ fprintf(stderr, "Trying /proc/cpuinfo...\n"); ++ } else { ++ size = read(fd, buf, 16); ++ if (size == -1) { ++ fprintf(stderr, "read err...\n"); ++ } ++ close(fd); ++ freq = (uint64_t)atoi(buf); ++ return freq * 1000; ++ } ++ ++ fd = open("/proc/cpuinfo", O_RDONLY); ++ if (fd == -1) { ++ fprintf(stderr, "Failed to open /proc/cpuinfo!\n"); ++ return 0; ++ } ++ ++ size = read(fd, buf, 1024); ++ if (size == -1) { ++ fprintf(stderr, "read err...\n"); ++ } ++ close(fd); ++ ++ buf_p = strstr(buf, "MHz"); ++ if (buf_p) { ++ while (*buf_p != ':') { ++ buf_p++; ++ } ++ buf_p += 2; ++ } else { ++ buf_p = strstr(buf, "name"); ++ while (*buf_p != '@') { ++ buf_p++; ++ } ++ buf_p += 2; ++ } ++ ++ memcpy(buf, buf_p, 12); ++ buf_p = buf; ++ while ((*buf_p >= '0') && (*buf_p <= '9')) { ++ buf_p++; ++ } ++ *buf_p = '\0'; ++ ++ freq = (uint64_t)atoi(buf); ++ return freq * 1000 * 1000; ++} ++ ++static char *get_host_cpu_model_name(void) ++{ ++ int fd = 0; ++ int size = 0; ++ static char buf[1024]; ++ char *buf_p; ++ ++ fd = open("/proc/cpuinfo", O_RDONLY); ++ if (fd == -1) { ++ fprintf(stderr, "Failed to open /proc/cpuinfo!\n"); ++ return 0; ++ } ++ ++ size = read(fd, buf, 1024); ++ if (size == -1) { ++ fprintf(stderr, "read err...\n"); ++ } ++ close(fd); ++ buf_p = strstr(buf, "name"); ++ ++ while (*buf_p != ':') { ++ buf_p++; ++ } ++ buf_p = buf_p + 2; ++ memcpy(buf, buf_p, 40); ++ buf_p = buf; ++ while (*buf_p != '\n') { ++ buf_p++; ++ } ++ ++ *(buf_p) = '\0'; ++ ++ return buf; ++} ++ ++static void fw_conf_init(unsigned long ramsize) ++{ ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ int smp_cpus = ms->smp.cpus; ++ fw_config.ram_size = ramsize; ++ fw_config.mem_freq = 266000000; ++ fw_config.cpu_nr = smp_cpus ; ++ fw_config.cpu_clock_freq = get_host_cpu_freq(); ++} ++ ++static struct efi_cpuinfo_loongarch *init_cpu_info(void *g_cpuinfo_loongarch) ++{ ++ struct efi_cpuinfo_loongarch *c = g_cpuinfo_loongarch; ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ int smp_cpus = ms->smp.cpus; ++ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ ++ if (strstr(lsmc->cpu_name, "5000")) { ++ c->processor_id = 0x14c010; ++ } ++ c->cputype = Loongson3_comp; ++ c->cpu_clock_freq = get_host_cpu_freq(); ++ if (!c->cpu_clock_freq) { ++ c->cpu_clock_freq = 200000000; ++ } ++ c->total_node = 1; ++ c->nr_cpus = smp_cpus; ++ c->cpu_startup_core_id = 0; ++ c->reserved_cores_mask = 0xffff & (0xffff << smp_cpus); ++ ++ return c; ++} ++ ++static struct system_loongarch *init_system_loongarch(void *g_sysitem) ++{ ++ struct system_loongarch *s = g_sysitem; ++ ++ s->ccnuma_smp = 1; ++ s->ccnuma_smp = 0; ++ s->sing_double_channel = 1; ++ ++ return s; ++} ++ ++enum loongarch_irq_source_enum { ++ HT, I8259, UNKNOWN ++}; ++ ++static struct irq_source_routing_table *init_irq_source(void *g_irq_source) ++{ ++ struct irq_source_routing_table *irq_info = g_irq_source; ++ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ ++ irq_info->PIC_type = HT; ++ irq_info->ht_int_bit = 1 << 24; ++ irq_info->ht_enable = 0x0000d17b; ++ irq_info->node_id = 0; ++ ++ irq_info->pci_mem_start_addr = LS_ISA_MEM_BASE; ++ irq_info->pci_mem_end_addr = irq_info->pci_mem_start_addr + LS_ISA_MEM_SIZE - 1; ++ ++ if (strstr(lsmc->cpu_name, "5000")) { ++ irq_info->pci_io_start_addr = LS3A5K_ISA_IO_BASE; ++ } ++ irq_info->dma_noncoherent = 1; ++ return irq_info; ++} ++ ++static struct interface_info *init_interface_info(void *g_interface) ++{ ++ struct interface_info *inter = g_interface; ++ int flashsize = 0x80000; ++ ++ inter->vers = 0x0001; ++ inter->size = flashsize / 0x400; ++ inter->flag = 1; ++ ++ strcpy(inter->description, "PMON_Version_v2.1"); ++ ++ return inter; ++} ++ ++static struct board_devices *board_devices_info(void *g_board) ++{ ++ struct board_devices *bd = g_board; ++ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ ++ if (!strcmp(lsmc->bridge_name, "ls7a")) { ++ strcpy(bd->name, "Loongarch-3A-7A-1w-V1.03-demo"); ++ } ++ bd->num_resources = 10; ++ ++ return bd; ++} ++ ++static struct loongarch_special_attribute *init_special_info(void *g_special) ++{ ++ struct loongarch_special_attribute *special = g_special; ++ char update[11] = "2013-01-01"; ++ int VRAM_SIZE = 0x20000; ++ ++ strcpy(special->special_name, update); ++ special->resource[0].flags = 0; ++ special->resource[0].start = 0; ++ special->resource[0].end = VRAM_SIZE; ++ strcpy(special->resource[0].name, "SPMODULE"); ++ special->resource[0].flags |= DMA64_SUPPORTED; ++ ++ return special; ++} ++ ++static void init_loongarch_params(struct loongarch_params *lp) ++{ ++ void *p = boot_params_p; ++ ++ lp->memory_offset = (unsigned long long)init_memory_map(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct efi_memory_map_loongarch)); ++ ++ lp->cpu_offset = (unsigned long long)init_cpu_info(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct efi_cpuinfo_loongarch)); ++ ++ lp->system_offset = (unsigned long long)init_system_loongarch(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct system_loongarch)); ++ ++ lp->irq_offset = (unsigned long long)init_irq_source(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct irq_source_routing_table)); ++ ++ lp->interface_offset = (unsigned long long)init_interface_info(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct interface_info)); ++ ++ lp->boarddev_table_offset = (unsigned long long)board_devices_info(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct board_devices)); ++ ++ lp->special_offset = (unsigned long long)init_special_info(p) ++ - (unsigned long long)lp; ++ p += align(sizeof(struct loongarch_special_attribute)); ++ ++ boot_params_p = p; ++} ++ ++static void init_smbios(struct smbios_tables *smbios) ++{ ++ smbios->vers = 1; ++ smbios->vga_bios = 1; ++ init_loongarch_params(&(smbios->lp)); ++} ++ ++static void init_efi(struct efi_loongarch *efi) ++{ ++ init_smbios(&(efi->smbios)); ++} ++ ++static int init_boot_param(struct boot_params *bp) ++{ ++ init_efi(&(bp->efi)); ++ ++ return 0; ++} ++ ++static unsigned int ls3a5k_aui_boot_code[] = { ++ 0x0380200d, /* ori $r13,$r0,0x8 */ ++ 0x0400002d, /* csrwr $r13,0x0 */ ++ 0x0401000e, /* csrrd $r14,0x40 */ ++ 0x0343fdce, /* andi $r14,$r14,0xff */ ++ 0x143fc02c, /* lu12i.w $r12,261889(0x1fe01) */ ++ 0x1600000c, /* lu32i.d $r12,0 */ ++ 0x0320018c, /* lu52i.d $r12,$r12,-1792(0x800) */ ++ 0x03400dcf, /* andi $r15,$r14,0x3 */ ++ 0x004121ef, /* slli.d $r15,$r15,0x8 */ ++ 0x00153d8c, /* or $r12,$r12,$r15 */ ++ 0x034031d0, /* andi $r16,$r14,0xc */ ++ 0x0041aa10, /* slli.d $r16,$r16,0x2a */ ++ 0x0015418c, /* or $r12,$r12,$r16 */ ++ 0x28808184, /* ld.w $r4,$r12,32(0x20) */ ++ 0x43fffc9f, /* beqz $r4,0 -4 */ ++ 0x28c08184, /* ld.d $r4,$r12,32(0x20) */ ++ 0x28c0a183, /* ld.d $r3,$r12,40(0x28) */ ++ 0x28c0c182, /* ld.d $r2,$r12,48(0x30) */ ++ 0x28c0e185, /* ld.d $r5,$r12,56(0x38) */ ++ 0x4c000080, /* jirl $r0,$r4,0 */ ++}; ++ ++static int set_bootparam_uefi(ram_addr_t initrd_offset, long initrd_size) ++{ ++ long params_size; ++ char memenv[32]; ++ char highmemenv[32]; ++ void *params_buf; ++ unsigned long *parg_env; ++ int ret = 0; ++ ++ /* Allocate params_buf for command line. */ ++ params_size = 0x100000; ++ params_buf = g_malloc0(params_size); ++ ++ /* ++ * Layout of params_buf looks like this: ++ * argv[0], argv[1], 0, env[0], env[1], ...env[i], 0, ++ * argv[0]'s data, argv[1]'s data, env[0]'data, ..., env[i]'s data, 0 ++ */ ++ parg_env = (void *)params_buf; ++ ++ ret = (3 + 1) * sizeof(target_ulong); ++ *parg_env++ = (BOOTPARAM_ADDR + ret); ++ ret += (1 + snprintf(params_buf + ret, COMMAND_LINE_SIZE - ret, "g")); ++ ++ /* argv1 */ ++ *parg_env++ = BOOTPARAM_ADDR + ret; ++ if (initrd_size > 0) ++ ret += (1 + snprintf(params_buf + ret, COMMAND_LINE_SIZE - ret, ++ "rd_start=0x%llx rd_size=%li %s", ++ PHYS_TO_VIRT((uint32_t)initrd_offset), ++ initrd_size, loaderparams.kernel_cmdline)); ++ else ++ ret += (1 + snprintf(params_buf + ret, COMMAND_LINE_SIZE - ret, "%s", ++ loaderparams.kernel_cmdline)); ++ ++ /* argv2 */ ++ *parg_env++ = 0; ++ ++ /* env */ ++ sprintf(memenv, "%lu", loaderparams.ram_size > 0x10000000 ++ ? 256 : (loaderparams.ram_size >> 20)); ++ sprintf(highmemenv, "%lu", loaderparams.ram_size > 0x10000000 ++ ? (loaderparams.ram_size >> 20) - 256 : 0); ++ ++ setenv("memsize", memenv, 1); ++ setenv("highmemsize", highmemenv, 1); ++ ++ ret = ((ret + 32) & ~31); ++ ++ boot_params_buf = (void *)(params_buf + ret); ++ boot_params_p = boot_params_buf + align(sizeof(struct boot_params)); ++ init_boot_param(boot_params_buf); ++ rom_add_blob_fixed("params", params_buf, params_size, ++ BOOTPARAM_PHYADDR); ++ loaderparams.a0 = 2; ++ loaderparams.a1 = BOOTPARAM_ADDR; ++ loaderparams.a2 = BOOTPARAM_ADDR + ret; ++ ++ return 0; ++} ++ ++static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) ++{ ++ return addr & 0x1fffffffll; ++} ++ ++static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg, ++ uint64_t highram_size, ++ uint64_t phyAddr_initrd) ++{ ++ int64_t entry, kernel_low, kernel_high; ++ long initrd_size = 0; ++ uint64_t initrd_offset = 0; ++ void *cmdline_buf; ++ int ret = 0; ++ ++ ret = load_elf(loaderparams.kernel_filename, NULL, cpu_loongarch_virt_to_phys, NULL, ++ (uint64_t *)&entry, (uint64_t *)&kernel_low, ++ (uint64_t *)&kernel_high, NULL, 0, EM_LOONGARCH, 1, 0); ++ ++ if(0 > ret) { ++ error_report("kernel image load error"); ++ exit(1); ++ } ++ ++ fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ENTRY, entry); ++ ++ if (loaderparams.initrd_filename) { ++ initrd_size = get_image_size(loaderparams.initrd_filename); ++ if (0 < initrd_size) { ++ if (initrd_size > highram_size) { ++ error_report("initrd size is too big, should below %ld MB", ++ highram_size / S_1MiB); ++ /*prevent write io memory address space*/ ++ exit(1); ++ } ++ initrd_offset = (phyAddr_initrd - initrd_size) & TARGET_REALPAGE_MASK; ++ initrd_size = load_image_targphys(loaderparams.initrd_filename, ++ initrd_offset, ++ loaderparams.ram_size - initrd_offset); ++ fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_offset); ++ fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); ++ } else { ++ error_report("initrd image size is error"); ++ } ++ } ++ ++ cmdline_buf = g_malloc0(COMMAND_LINE_SIZE); ++ if (initrd_size > 0) ++ ret = (1 + snprintf(cmdline_buf, COMMAND_LINE_SIZE, ++ "rd_start=0x%llx rd_size=%li %s", ++ PHYS_TO_VIRT(initrd_offset), ++ initrd_size, loaderparams.kernel_cmdline)); ++ else ++ ret = (1 + snprintf(cmdline_buf, COMMAND_LINE_SIZE, "%s", ++ loaderparams.kernel_cmdline)); ++ ++ fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, ret); ++ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, (const char *)cmdline_buf); ++ ++ return ; ++} ++ ++static int64_t load_kernel(void) ++{ ++ int64_t entry, kernel_low, kernel_high; ++ long initrd_size = 0; ++ ram_addr_t initrd_offset = 0; ++ ++ load_elf(loaderparams.kernel_filename, NULL, cpu_loongarch_virt_to_phys, NULL, ++ (uint64_t *)&entry, (uint64_t *)&kernel_low, ++ (uint64_t *)&kernel_high, NULL, 0, EM_LOONGARCH, 1, 0); ++ ++ if (loaderparams.initrd_filename) { ++ initrd_size = get_image_size(loaderparams.initrd_filename); ++ ++ if (initrd_size > 0) { ++ initrd_offset = (kernel_high * 4 + ~TARGET_REALPAGE_MASK) ++ & TARGET_REALPAGE_MASK; ++ initrd_size = load_image_targphys(loaderparams.initrd_filename, ++ initrd_offset, ++ loaderparams.ram_size - initrd_offset); ++ } ++ } ++ set_bootparam_uefi(initrd_offset, initrd_size); ++ ++ return entry; ++} ++ ++static void main_cpu_reset(void *opaque) ++{ ++ ResetData *s = (ResetData *)opaque; ++ CPULOONGARCHState *env = &s->cpu->env; ++ ++ cpu_reset(CPU(s->cpu)); ++ env->active_tc.PC = s->vector; ++ env->active_tc.gpr[4] = loaderparams.a0; ++ env->active_tc.gpr[5] = loaderparams.a1; ++ env->active_tc.gpr[6] = loaderparams.a2; ++} ++ ++void slave_cpu_reset(void *opaque) ++{ ++ ResetData *s = (ResetData *)opaque; ++ ++ cpu_reset(CPU(s->cpu)); ++} ++ ++ ++/* KVM_IRQ_LINE irq field index values */ ++#define KVM_LOONGARCH_IRQ_TYPE_SHIFT 24 ++#define KVM_LOONGARCH_IRQ_TYPE_MASK 0xff ++#define KVM_LOONGARCH_IRQ_VCPU_SHIFT 16 ++#define KVM_LOONGARCH_IRQ_VCPU_MASK 0xff ++#define KVM_LOONGARCH_IRQ_NUM_SHIFT 0 ++#define KVM_LOONGARCH_IRQ_NUM_MASK 0xffff ++ ++/* irq_type field */ ++#define KVM_LOONGARCH_IRQ_TYPE_CPU_IP 0 ++#define KVM_LOONGARCH_IRQ_TYPE_CPU_IO 1 ++#define KVM_LOONGARCH_IRQ_TYPE_HT 2 ++#define KVM_LOONGARCH_IRQ_TYPE_MSI 3 ++#define KVM_LOONGARCH_IRQ_TYPE_IOAPIC 4 ++ ++static void legacy_set_irq(void *opaque, int irq, int level) ++{ ++ qemu_irq *pic = opaque; ++ ++ qemu_set_irq(pic[irq], level); ++} ++ ++typedef struct ls3a_intctlstate { ++ uint8_t nodecounter_reg[0x100]; ++ uint8_t pm_reg[0x100]; ++ uint8_t msi_reg[0x8]; ++ CPULOONGARCHState **env; ++ DeviceState *apicdev; ++ qemu_irq *ioapic_irq; ++#ifdef CONFIG_KVM ++ struct loongarch_kvm_irqchip chip; ++#endif ++} ls3a_intctlstate; ++ ++typedef struct ls3a_func_args { ++ ls3a_intctlstate *state; ++ uint64_t base; ++ uint32_t mask; ++ uint8_t *mem; ++} ls3a_func_args; ++ ++static uint64_t ls3a_msi_mem_read(void *opaque, hwaddr addr, unsigned size) ++{ ++ return 0; ++} ++ ++static void ls3a_msi_mem_write(void *opaque, hwaddr addr, ++ uint64_t val, unsigned size) ++{ ++ struct kvm_msi msi; ++ apicState *apic; ++ ++ apic = (apicState *)opaque; ++ msi.address_lo = 0; ++ msi.address_hi = 0; ++ msi.data = val & 0xff; ++ msi.flags = 0; ++ memset(msi.pad, 0, sizeof(msi.pad)); ++ ++ if (kvm_irqchip_in_kernel()) { ++ kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi); ++ } else { ++ qemu_set_irq(apic->irq[msi.data], 1); ++ } ++} ++ ++ ++static const MemoryRegionOps ls3a_msi_ops = { ++ .read = ls3a_msi_mem_read, ++ .write = ls3a_msi_mem_write, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++}; ++ ++ ++static const VMStateDescription vmstate_ls3a_msi = { ++ .name = "ls3a-msi", ++ .version_id = 0, ++ .minimum_version_id = 0, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT8_ARRAY(msi_reg, ls3a_intctlstate, 0x8), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static void ioapic_handler(void *opaque, int irq, int level) ++{ ++ apicState *apic; ++ int kvm_irq; ++ ++ apic = (apicState *)opaque; ++ ++ if (kvm_irqchip_in_kernel()) { ++ kvm_irq = (KVM_LOONGARCH_IRQ_TYPE_IOAPIC << KVM_LOONGARCH_IRQ_TYPE_SHIFT) ++ | (0 << KVM_LOONGARCH_IRQ_VCPU_SHIFT) | irq; ++ kvm_set_irq(kvm_state, kvm_irq, !!level); ++ } else { ++ qemu_set_irq(apic->irq[irq], level); ++ } ++} ++ ++static void *ls3a_intctl_init(MachineState *machine, CPULOONGARCHState *env[]) ++{ ++ qemu_irq *irqhandler; ++ ls3a_intctlstate *s; ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ LoongarchMachineClass *mc = LoongarchMACHINE_GET_CLASS(lsms); ++ DeviceState *dev; ++ SysBusDevice *busdev; ++ MemoryRegion *address_space_mem = get_system_memory(); ++ MemoryRegion *iomem = NULL; ++ int i; ++ ++ s = g_malloc0(sizeof(ls3a_intctlstate)); ++ ++ if (!s) { ++ return NULL; ++ } ++ ++ /*Add MSI mmio memory*/ ++ iomem = g_new(MemoryRegion, 1); ++ memory_region_init_io(iomem, NULL, &ls3a_msi_ops, lsms->apic, ++ "ls3a_msi", 0x8); ++ memory_region_add_subregion(address_space_mem, ++ MSI_ADDR_LOW, iomem); ++ vmstate_register(NULL, 0, &vmstate_ls3a_msi, s); ++ ++ s->env = env; ++ ++ if (!strcmp(mc->bridge_name, "ls7a")) { ++ if (lsms->apic_xrupt_override) { ++ DPRINTF("irqchip in kernel %d\n", kvm_irqchip_in_kernel()); ++#ifdef CONFIG_KVM ++ if (kvm_has_gsi_routing()) { ++ for (i = 0; i < 32; ++i) { ++ kvm_irqchip_add_irq_route(kvm_state, i, 0, i); ++ } ++ kvm_gsi_routing_allowed = true; ++ } ++ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled(); ++#endif ++ } ++ ++ irqhandler = qemu_allocate_irqs(ioapic_handler, lsms->apic, 64); ++ dev = qdev_new("ioapic"); ++ busdev = SYS_BUS_DEVICE(dev); ++ sysbus_realize_and_unref(busdev, &error_fatal); ++ sysbus_mmio_map(busdev, 0, mc->ls7a_ioapic_reg_base); ++ s->ioapic_irq = irqhandler; ++ s->apicdev = dev; ++ return s->ioapic_irq; ++ } ++ return NULL; ++} ++ ++/* Network support */ ++static void network_init(PCIBus *pci_bus) ++{ ++ int i; ++ ++ for (i = 0; i < nb_nics; i++) { ++ NICInfo *nd = &nd_table[i]; ++ ++ if (!nd->model) { ++ nd->model = g_strdup("virtio-net-pci"); ++ } ++ ++ pci_nic_init_nofail(nd, pci_bus, nd->model, NULL); ++ } ++} ++ ++void loongarch_cpu_destroy(MachineState *machine, LOONGARCHCPU *cpu) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ unsigned int id; ++ int smp_cpus = machine->smp.cpus; ++ id = cpu->id; ++ qemu_unregister_reset(slave_cpu_reset, lsms->reset_info[id]); ++ g_free(lsms->reset_info[id]); ++ lsms->reset_info[id] = NULL; ++ ++ smp_cpus -= 1; ++ if (lsms->fw_cfg) { ++ fw_cfg_modify_i16(lsms->fw_cfg, FW_CFG_NB_CPUS, ++ (uint16_t)smp_cpus); ++ } ++ ++ qemu_del_vm_change_state_handler(cpu->cpuStateEntry); ++} ++ ++LOONGARCHCPU *loongarch_cpu_create(MachineState *machine, ++ LOONGARCHCPU *cpu, Error **errp) ++{ ++ CPULOONGARCHState *env; ++ unsigned int id; ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ int smp_cpus = machine->smp.cpus; ++ id = cpu->id; ++ env = &cpu->env; ++ cpu_states[id] = env; ++ env->CSR_TMID |= id; ++ ++ lsms = LoongarchMACHINE(machine); ++ lsms->reset_info[id] = g_malloc0(sizeof(ResetData)); ++ lsms->reset_info[id]->cpu = cpu; ++ lsms->reset_info[id]->vector = env->active_tc.PC; ++ qemu_register_reset(slave_cpu_reset, lsms->reset_info[id]); ++ ++ /* Init CPU internal devices */ ++ cpu_init_irq(cpu); ++ cpu_loongarch_clock_init(cpu); ++ ++ smp_cpus += 1; ++ if (lsms->fw_cfg) { ++ fw_cfg_modify_i16(lsms->fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); ++ } ++ cpu_init_ipi(lsms, env->irq[12], id); ++ cpu_init_apic(lsms, env, id); ++ ++ return cpu; ++} ++ ++static void fw_cfg_boot_set(void *opaque, const char *boot_device, ++ Error **errp) ++{ ++ fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); ++} ++ ++static FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, ++ LoongarchMachineState *lsms) ++{ ++ FWCfgState *fw_cfg; ++ uint64_t *numa_fw_cfg; ++ int i; ++ const CPUArchIdList *cpus; ++ MachineClass *mc = MACHINE_GET_CLASS(lsms); ++ MachineState *ms = MACHINE(OBJECT(lsms)); ++ int max_cpus = ms->smp.max_cpus; ++ int smp_cpus = ms->smp.cpus; ++ int nb_numa_nodes = ms->numa_state->num_nodes; ++ NodeInfo *numa_info = ms->numa_state->nodes; ++ ++ fw_cfg = fw_cfg_init_mem_wide(FW_CFG_ADDR + 8, FW_CFG_ADDR, 8, 0, NULL); ++ fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); ++ fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); ++ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); ++ ++ /* allocate memory for the NUMA channel: one (64bit) word for the number ++ * of nodes, one word for each VCPU->node and one word for each node to ++ * hold the amount of memory. ++ */ ++ numa_fw_cfg = g_new0(uint64_t, 1 + max_cpus + nb_numa_nodes); ++ numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes); ++ cpus = mc->possible_cpu_arch_ids(MACHINE(lsms)); ++ for (i = 0; i < cpus->len; i++) { ++ unsigned int apic_id = cpus->cpus[i].arch_id; ++ assert(apic_id < max_cpus); ++ numa_fw_cfg[apic_id + 1] = cpu_to_le64(cpus->cpus[i].props.node_id); ++ } ++ for (i = 0; i < nb_numa_nodes; i++) { ++ numa_fw_cfg[max_cpus + 1 + i] = ++ cpu_to_le64(numa_info[i].node_mem); ++ } ++ fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg, ++ (1 + max_cpus + nb_numa_nodes) * ++ sizeof(*numa_fw_cfg)); ++ ++ qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); ++ return fw_cfg; ++} ++ ++static void loongarch_build_smbios(LoongarchMachineState *lsms) ++{ ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ MachineState *ms = MACHINE(OBJECT(lsms)); ++ uint8_t *smbios_tables, *smbios_anchor; ++ size_t smbios_tables_len, smbios_anchor_len; ++ const char *product = "QEMU Virtual Machine"; ++ ms->smp.cores = 4; ++ ++ if (!lsms->fw_cfg) { ++ return; ++ } ++ ++ if (kvm_enabled()) { ++ if (strstr(lsmc->cpu_name, "5000")) { ++ product = "KVM"; ++ } ++ } else { ++ product = "Loongarch-3A5K-7A1000-TCG"; ++ } ++ ++ host_cpufreq = get_host_cpu_freq(); ++ ++ smbios_set_defaults("Loongson", product, lsmc->cpu_name, false, ++ true, NULL, NULL, SMBIOS_ENTRY_POINT_30); ++ ++ smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len, ++ &smbios_anchor, &smbios_anchor_len, &error_fatal); ++ ++ if (smbios_anchor) { ++ fw_cfg_add_file(lsms->fw_cfg, "etc/smbios/smbios-tables", ++ smbios_tables, smbios_tables_len); ++ fw_cfg_add_file(lsms->fw_cfg, "etc/smbios/smbios-anchor", ++ smbios_anchor, smbios_anchor_len); ++ } ++} ++ ++static ++void loongarch_machine_done(Notifier *notifier, void *data) ++{ ++ LoongarchMachineState *lsms = container_of(notifier, ++ LoongarchMachineState, machine_done); ++ loongarch_acpi_setup(); ++ loongarch_build_smbios(lsms); ++} ++ ++#ifdef CONFIG_TCG ++#define FEATURE_REG 0x1fe00008 ++#define VENDOR_REG 0x1fe00010 ++#define CPUNAME_REG 0x1fe00020 ++#define OTHER_FUNC_REG 0x1fe00420 ++#define _str(x) #x ++#define str(x) _str(x) ++#define SIMPLE_OPS(ADDR, SIZE) \ ++({\ ++ MemoryRegion *iomem = g_new(MemoryRegion, 1);\ ++ memory_region_init_io(iomem, NULL, &loongarch_qemu_ops, \ ++ (void *)ADDR, str(ADDR) , SIZE);\ ++ memory_region_add_subregion_overlap(address_space_mem, ADDR, iomem, 1);\ ++}) ++ ++static int reg180; ++ ++static void loongarch_qemu_write(void *opaque, hwaddr addr, ++ uint64_t val, unsigned size) ++{ ++ addr = ((hwaddr)(long)opaque) + addr; ++ addr = addr & 0xffffffff; ++ switch (addr) { ++ case 0x1fe00180: ++ reg180 = val; ++ break; ++ } ++} ++ ++static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size) ++{ ++ uint64_t feature = 0UL; ++ addr = ((hwaddr)(long)opaque) + addr; ++ addr = addr & 0xffffffff; ++ switch (addr) { ++ case 0x1fe00180: ++ return reg180; ++ case 0x1001041c: ++ return 0xa800; ++ case FEATURE_REG: ++ feature |= 1UL << 2 | 1UL << 3 | 1UL << 4 | 1UL << 11; ++ return feature ; ++ case VENDOR_REG: ++ return *(uint64_t *)"Loongson-3A5000"; ++ case CPUNAME_REG: ++ return *(uint64_t *)"3A5000"; ++ case 0x10013ffc: ++ return 0x80; ++ } ++ return 0; ++} ++ ++static const MemoryRegionOps loongarch_qemu_ops = { ++ .read = loongarch_qemu_read, ++ .write = loongarch_qemu_write, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++ .valid = { ++ .min_access_size = 4, ++ .max_access_size = 8, ++ }, ++ .impl = { ++ .min_access_size = 4, ++ .max_access_size = 8, ++ }, ++}; ++#endif ++ ++ ++static void loongarch_system_flash_cleanup_unused(LoongarchMachineState *lsms) ++{ ++ char *prop_name; ++ int i; ++ Object *dev_obj; ++ ++ for (i = 0; i < ARRAY_SIZE(lsms->flash); i++) { ++ dev_obj = OBJECT(lsms->flash[i]); ++ if (!object_property_get_bool(dev_obj, "realized", &error_abort)) { ++ prop_name = g_strdup_printf("pflash%d", i); ++ object_property_del(OBJECT(lsms), prop_name); ++ g_free(prop_name); ++ object_unparent(dev_obj); ++ lsms->flash[i] = NULL; ++ } ++ } ++} ++ ++ ++static bool loongarch_system_flash_init( LoongarchMachineState *lsms) ++{ ++ int i = 0; ++ int64_t size = 0; ++ PFlashCFI01 *pflash = NULL; ++ BlockBackend *pflash_blk; ++ ++ for(i = 0; i < ARRAY_SIZE(lsms->flash); i++) { ++ pflash_blk = NULL; ++ pflash = NULL; ++ ++ pflash = lsms->flash[i]; ++ pflash_cfi01_legacy_drive(pflash, ++ drive_get(IF_PFLASH, 0, i)); ++ ++ pflash_blk = pflash_cfi01_get_blk(pflash); ++ /*The pflash0 must be exist, or not support boot by pflash*/ ++ if(pflash_blk == NULL) { ++ if(i == 0) { ++ return false; ++ } else { ++ break; ++ } ++ } ++ ++ size = blk_getlength(pflash_blk); ++ if (size == 0 || size % FLASH_SECTOR_SIZE != 0) { ++ error_report("system firmware block device %s has invalid size " ++ "%" PRId64, ++ blk_name(pflash_blk), size); ++ error_report("its size must be a non-zero multiple of 0x%x", ++ FLASH_SECTOR_SIZE); ++ exit(1); ++ } ++ qdev_prop_set_uint32(DEVICE(pflash), "num-blocks", ++ size / FLASH_SECTOR_SIZE); ++ sysbus_realize_and_unref(SYS_BUS_DEVICE(pflash), &error_fatal); ++ if(i == 0) { ++ sysbus_mmio_map(SYS_BUS_DEVICE(pflash), 0, LS_BIOS_BASE); ++ } else { ++ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(pflash), 0, LS_BIOS_VAR_BASE, 1); ++ } ++ } ++ ++ return true; ++} ++static void ls3a5k_bios_init(LoongarchMachineState *lsms, ++ ram_addr_t ram_size, ++ uint64_t highram_size, ++ uint64_t phyAddr_initrd, ++ const char *kernel_filename, ++ const char *kernel_cmdline, ++ const char *initrd_filename) ++{ ++ MemoryRegion *bios; ++ bool fw_cfg_used = false; ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ char *filename; ++ int bios_size; ++ const char *bios_name; ++ ++ bios_name = MACHINE(lsms)->firmware; ++ if (kernel_filename) { ++ loaderparams.ram_size = ram_size; ++ loaderparams.kernel_filename = kernel_filename; ++ loaderparams.kernel_cmdline = kernel_cmdline; ++ loaderparams.initrd_filename = initrd_filename; ++ } ++ ++ if(loongarch_system_flash_init(lsms)) { ++ fw_cfg_used = true; ++ } else { ++ bios = g_new(MemoryRegion, 1); ++ memory_region_init_ram(bios, NULL, "loongarch.bios", LS_BIOS_SIZE, &error_fatal); ++ memory_region_set_readonly(bios, true); ++ memory_region_add_subregion(get_system_memory(), LS_BIOS_BASE, bios); ++ ++ /* BIOS load */ ++ if (bios_name) { ++ if (access(bios_name, R_OK) == 0) { ++ load_image_targphys(bios_name, LS_BIOS_BASE, LS_BIOS_SIZE); ++ } else { ++ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); ++ load_image_targphys(filename, LS_BIOS_BASE, LS_BIOS_SIZE); ++ g_free(filename); ++ } ++ fw_cfg_used = true; ++ } else { ++ if (strstr(lsmc->cpu_name, "5000")) { ++ bios_size = sizeof(ls3a5k_aui_boot_code); ++ rom_add_blob_fixed("bios", ls3a5k_aui_boot_code, bios_size, LS_BIOS_BASE); ++ } ++ ++ if (kernel_filename) { ++ lsms->reset_info[0]->vector = load_kernel(); ++ } else { ++ error_report("Please specify at lease one of -bios and -kernel"); ++ exit(1); ++ } ++ } ++ } ++ ++ loongarch_system_flash_cleanup_unused(lsms); ++ ++ if (fw_cfg_used) { ++ lsms->fw_cfg = loongarch_fw_cfg_init(ram_size, lsms); ++ rom_set_fw(lsms->fw_cfg); ++ fw_conf_init(ram_size); ++ rom_add_blob_fixed("fw_conf", (void *)&fw_config, ++ sizeof(fw_config), FW_CONF_ADDR); ++ ++ if (kernel_filename) { ++ fw_cfg_add_kernel_info(lsms->fw_cfg, highram_size, phyAddr_initrd); ++ } ++ } ++ ++ if (lsms->fw_cfg != NULL) { ++ fw_cfg_add_file(lsms->fw_cfg, "etc/memmap", ++ la_memmap_table, ++ sizeof(struct la_memmap_entry) * (la_memmap_entries)); ++ } ++ ++ return ; ++} ++static void create_fdt(LoongarchMachineState *lsms) ++{ ++ lsms->fdt = create_device_tree(&lsms->fdt_size); ++ if (!lsms->fdt) { ++ error_report("create_device_tree() failed"); ++ exit(1); ++ } ++ ++ /* Header */ ++ qemu_fdt_setprop_string(lsms->fdt, "/", "compatible", ++ "linux,dummy-loongson3"); ++ qemu_fdt_setprop_cell(lsms->fdt, "/", "#address-cells", 0x2); ++ qemu_fdt_setprop_cell(lsms->fdt, "/", "#size-cells", 0x2); ++} ++ ++static void fdt_add_cpu_nodes(const LoongarchMachineState *lsms) ++{ ++ int num; ++ const MachineState *ms = MACHINE(lsms); ++ int smp_cpus = ms->smp.cpus; ++ ++ qemu_fdt_add_subnode(lsms->fdt, "/cpus"); ++ qemu_fdt_setprop_cell(lsms->fdt, "/cpus", "#address-cells", 0x1); ++ qemu_fdt_setprop_cell(lsms->fdt, "/cpus", "#size-cells", 0x0); ++ ++ /* cpu nodes */ ++ for (num = smp_cpus - 1; num >= 0; num--) { ++ char *nodename = g_strdup_printf("/cpus/cpu@%d", num); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(qemu_get_cpu(num)); ++ ++ qemu_fdt_add_subnode(lsms->fdt, nodename); ++ qemu_fdt_setprop_string(lsms->fdt, nodename, "device_type", "cpu"); ++ qemu_fdt_setprop_string(lsms->fdt, nodename, "compatible", ++ cpu->dtb_compatible); ++ qemu_fdt_setprop_cell(lsms->fdt, nodename, "reg", num); ++ qemu_fdt_setprop_cell(lsms->fdt, nodename, "phandle", ++ qemu_fdt_alloc_phandle(lsms->fdt)); ++ g_free(nodename); ++ } ++ ++ /*cpu map */ ++ qemu_fdt_add_subnode(lsms->fdt, "/cpus/cpu-map"); ++ ++ for (num = smp_cpus - 1; num >= 0; num--) { ++ char *cpu_path = g_strdup_printf("/cpus/cpu@%d", num); ++ char *map_path; ++ ++ if (ms->smp.threads > 1) { ++ map_path = g_strdup_printf( ++ "/cpus/cpu-map/socket%d/core%d/thread%d", ++ num / (ms->smp.cores * ms->smp.threads), ++ (num / ms->smp.threads) % ms->smp.cores, ++ num % ms->smp.threads); ++ } else { ++ map_path = g_strdup_printf( ++ "/cpus/cpu-map/socket%d/core%d", ++ num / ms->smp.cores, ++ num % ms->smp.cores); ++ } ++ qemu_fdt_add_path(lsms->fdt, map_path); ++ qemu_fdt_setprop_phandle(lsms->fdt, map_path, "cpu", cpu_path); ++ ++ g_free(map_path); ++ g_free(cpu_path); ++ } ++} ++ ++static void fdt_add_fw_cfg_node(const LoongarchMachineState *lsms) ++{ ++ char *nodename; ++ hwaddr base = FW_CFG_ADDR; ++ ++ nodename = g_strdup_printf("/fw_cfg@%" PRIx64, base); ++ qemu_fdt_add_subnode(lsms->fdt, nodename); ++ qemu_fdt_setprop_string(lsms->fdt, nodename, ++ "compatible", "qemu,fw-cfg-mmio"); ++ qemu_fdt_setprop_sized_cells(lsms->fdt, nodename, "reg", ++ 2, base, 2, 0x8); ++ qemu_fdt_setprop(lsms->fdt, nodename, "dma-coherent", NULL, 0); ++ g_free(nodename); ++} ++ ++static void fdt_add_pcie_node(const LoongarchMachineState *lsms) ++{ ++ char *nodename; ++ hwaddr base_mmio = LS_ISA_MEM_BASE; ++ hwaddr size_mmio = LS_ISA_MEM_SIZE; ++ hwaddr base_pio = LS3A5K_ISA_IO_BASE; ++ hwaddr size_pio = LS_ISA_IO_SIZE; ++ hwaddr base_pcie = LS_PCIECFG_BASE; ++ hwaddr size_pcie = LS_PCIECFG_SIZE; ++ hwaddr base = base_pcie; ++ ++ nodename = g_strdup_printf("/pcie@%" PRIx64, base); ++ qemu_fdt_add_subnode(lsms->fdt, nodename); ++ qemu_fdt_setprop_string(lsms->fdt, nodename, ++ "compatible", "pci-host-ecam-generic"); ++ qemu_fdt_setprop_string(lsms->fdt, nodename, "device_type", "pci"); ++ qemu_fdt_setprop_cell(lsms->fdt, nodename, "#address-cells", 3); ++ qemu_fdt_setprop_cell(lsms->fdt, nodename, "#size-cells", 2); ++ qemu_fdt_setprop_cell(lsms->fdt, nodename, "linux,pci-domain", 0); ++ qemu_fdt_setprop_cells(lsms->fdt, nodename, "bus-range", 0, ++ PCIE_MMCFG_BUS(LS_PCIECFG_SIZE - 1)); ++ qemu_fdt_setprop(lsms->fdt, nodename, "dma-coherent", NULL, 0); ++ qemu_fdt_setprop_sized_cells(lsms->fdt, nodename, "reg", ++ 2, base_pcie, 2, size_pcie); ++ qemu_fdt_setprop_sized_cells(lsms->fdt, nodename, "ranges", ++ 1, FDT_PCI_RANGE_IOPORT, 2, 0, ++ 2, base_pio, 2, size_pio, ++ 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, ++ 2, base_mmio, 2, size_mmio); ++ g_free(nodename); ++ qemu_fdt_dumpdtb(lsms->fdt, lsms->fdt_size); ++} ++ ++static void ls3a5k_init(MachineState *args) ++{ ++ int i; ++ const char *cpu_model = args->cpu_type; ++ const char *kernel_filename = args->kernel_filename; ++ const char *kernel_cmdline = args->kernel_cmdline; ++ const char *initrd_filename = args->initrd_filename; ++ ++ ram_addr_t ram_size = args->ram_size; ++ MemoryRegion *address_space_mem = get_system_memory(); ++ ram_addr_t offset = 0; ++ MemoryRegion *isa_io = g_new(MemoryRegion, 1); ++ MemoryRegion *isa_mem = g_new(MemoryRegion, 1); ++ MachineState *machine = args; ++ MachineClass *mc = MACHINE_GET_CLASS(machine); ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ int smp_cpus = machine->smp.cpus; ++ int nb_numa_nodes = machine->numa_state->num_nodes; ++ NodeInfo *numa_info = machine->numa_state->nodes; ++ LOONGARCHCPU *cpu; ++ CPULOONGARCHState *env; ++ qemu_irq *ls7a_apic = NULL; ++ qemu_irq *pirq = NULL; ++ PCIBus *pci_bus = NULL; ++ char *ramName = NULL; ++ uint64_t lowram_size = 0, highram_size = 0, phyAddr = 0, ++ memmap_size = 0, highram_end_addr = 0; ++ ++ CPUArchIdList *possible_cpus; ++ if (strstr(lsmc->cpu_name, "5000")) { ++ if (strcmp(cpu_model, LOONGARCH_CPU_TYPE_NAME("Loongson-3A5000")) && ++ strcmp(cpu_model, LOONGARCH_CPU_TYPE_NAME("host"))) { ++ error_report("machine type %s does not match cpu type %s", ++ lsmc->cpu_name, cpu_model); ++ exit(1); ++ } ++ if (kvm_enabled()) { ++ kvm_vm_ioctl(kvm_state, KVM_LARCH_SET_CPUCFG, ls3a5k_cpucfgs); ++ } ++ } ++ ++ create_fdt(lsms); ++ ++ DPRINTF("isa 0x%lx\n", lsmc->isa_io_base); ++ DPRINTF("ht1lo 0x%lx\n", lsmc->ht1lo_pcicfg_base); ++ DPRINTF("cpu_name %s bridge_name %s\n", ++ lsmc->cpu_name, lsmc->bridge_name); ++ ++ /* init CPUs */ ++ mc->possible_cpu_arch_ids(machine); ++ possible_cpus = machine->possible_cpus; ++ ++ for (i = 0; i < smp_cpus; i++) { ++ Object *obj = NULL; ++ Error *local_err = NULL; ++ ++ obj = object_new(possible_cpus->cpus[i].type); ++ ++ object_property_set_uint(obj, "id", possible_cpus->cpus[i].arch_id, ++ &local_err); ++ object_property_set_bool(obj, "realized", true, &local_err); ++ ++ object_unref(obj); ++ error_propagate(&error_fatal, local_err); ++ ++ cpu = LOONGARCH_CPU(CPU(obj)); ++ if (cpu == NULL) { ++ fprintf(stderr, "Unable to find CPU definition\n"); ++ exit(1); ++ } ++ ++ env = &cpu->env; ++ cpu_states[i] = env; ++ env->CSR_TMID |= i; ++ ++ lsms->reset_info[i] = g_malloc0(sizeof(ResetData)); ++ lsms->reset_info[i]->cpu = cpu; ++ lsms->reset_info[i]->vector = env->active_tc.PC; ++ if (i == 0) { ++ qemu_register_reset(main_cpu_reset, lsms->reset_info[i]); ++ } else { ++ qemu_register_reset(slave_cpu_reset, lsms->reset_info[i]); ++ } ++ ++ /* Init CPU internal devices */ ++ cpu_init_irq(cpu); ++ cpu_loongarch_clock_init(cpu); ++ cpu_init_ipi(lsms, env->irq[12], i); ++ cpu_init_apic(lsms, env, i); ++ } ++ ++ lsms->hotpluged_cpu_num = 0; ++ fdt_add_cpu_nodes(lsms); ++ env = cpu_states[0]; ++ ++ /* node0 mem*/ ++ phyAddr = (uint64_t)0; ++ MemoryRegion *lowmem = g_new(MemoryRegion, 1); ++ ramName = g_strdup_printf("loongarch_ls3a.node%d.lowram", 0); ++ ++ lowram_size = MIN(ram_size, 256 * 0x100000); ++ memory_region_init_alias(lowmem, NULL, ramName, machine->ram, 0, lowram_size); ++ memory_region_add_subregion(address_space_mem, phyAddr, lowmem); ++ ++ offset += lowram_size; ++ if (nb_numa_nodes > 0) { ++ highram_size = numa_info[0].node_mem - S_256MiB; ++ if (numa_info[0].node_mem > S_1GiB) { ++ memmap_size = numa_info[0].node_mem - S_1GiB; ++ la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); ++ } ++ } else { ++ highram_size = ram_size - S_256MiB; ++ if (ram_size > S_1GiB) { ++ memmap_size = ram_size - S_1GiB; ++ la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); ++ } ++ } ++ ++ phyAddr = (uint64_t)0x90000000; ++ MemoryRegion *highmem = g_new(MemoryRegion, 1); ++ ramName = g_strdup_printf("loongarch_ls3a.node%d.highram", 0); ++ memory_region_init_alias(highmem, NULL, ramName, ++ machine->ram, offset, highram_size); ++ memory_region_add_subregion(address_space_mem, ++ phyAddr, highmem); ++ offset += highram_size; ++ phyAddr += highram_size; ++ ++ /* initrd address use high mem from high to low */ ++ highram_end_addr = phyAddr; ++ /* node1~ nodemax */ ++ for (i = 1; i < nb_numa_nodes; i++) { ++ MemoryRegion *nodemem = g_new(MemoryRegion, 1); ++ ramName = g_strdup_printf("loongarch_ls3a.node%d.ram", i); ++ memory_region_init_alias(nodemem, NULL, ramName, ++ machine->ram, offset, numa_info[i].node_mem); ++ memory_region_add_subregion(address_space_mem, ++ phyAddr, nodemem); ++ la_memmap_add_entry(phyAddr, numa_info[i].node_mem, SYSTEM_RAM); ++ offset += numa_info[i].node_mem; ++ phyAddr += numa_info[i].node_mem; ++ } ++ ++ fdt_add_fw_cfg_node(lsms); ++ ls3a5k_bios_init(lsms, ram_size, highram_size, highram_end_addr, ++ kernel_filename, kernel_cmdline, initrd_filename); ++ ++ lsms->machine_done.notify = loongarch_machine_done; ++ qemu_add_machine_init_done_notifier(&lsms->machine_done); ++ /*vmstate_register_ram_global(bios);*/ ++ ++ /* initialize hotplug memory address space */ ++ lsms->hotplug_memory_size = 0; ++ ++ /* always allocate the device memory information */ ++ machine->device_memory = g_malloc0(sizeof(*machine->device_memory)); ++ if (machine->ram_size < machine->maxram_size) { ++ int max_memslots; ++ ++ lsms->hotplug_memory_size = machine->maxram_size - machine->ram_size; ++ /* ++ * Limit the number of hotpluggable memory slots to half the number ++ * slots that KVM supports, leaving the other half for PCI and other ++ * devices. However ensure that number of slots doesn't drop below 32. ++ */ ++ max_memslots = LOONGARCH_MAX_RAM_SLOTS; ++ if (kvm_enabled()) { ++ max_memslots = kvm_get_max_memslots() / 2 ; ++ } ++ ++ if (machine->ram_slots == 0) ++ machine->ram_slots = lsms->hotplug_memory_size / ++ LOONGARCH_HOTPLUG_MEM_ALIGN; ++ ++ if (machine->ram_slots > max_memslots) { ++ error_report("Specified number of memory slots %" ++ PRIu64" exceeds max supported %d", ++ machine->ram_slots, max_memslots); ++ exit(1); ++ } ++ ++ lsms->ram_slots = machine->ram_slots; ++ ++ machine->device_memory->base = get_hotplug_membase(machine->ram_size); ++ memory_region_init(&machine->device_memory->mr, OBJECT(lsms), ++ "device-memory", lsms->hotplug_memory_size); ++ memory_region_add_subregion(get_system_memory(), ++ machine->device_memory->base, ++ &machine->device_memory->mr); ++ } ++ ++ memory_region_init_alias(isa_io, NULL, "isa-io", ++ get_system_io(), 0, LS_ISA_IO_SIZE); ++ memory_region_init(isa_mem, NULL, "isa-mem", LS_ISA_MEM_SIZE); ++ memory_region_add_subregion(get_system_memory(), lsmc->isa_io_base, isa_io); ++ memory_region_add_subregion(get_system_memory(), LS_ISA_MEM_BASE, isa_mem); ++ ++ if (!strcmp(lsmc->bridge_name, "ls7a")) { ++ /*Initialize the 7A IO interrupt subsystem*/ ++ DeviceState *ls7a_dev; ++ lsms->apic_xrupt_override = kvm_irqchip_in_kernel(); ++ ls7a_apic = ls3a_intctl_init(machine, cpu_states); ++ if (!ls7a_apic) { ++ perror("Init 7A APIC failed\n"); ++ exit(1); ++ } ++ pci_bus = ls7a_init(machine, ls7a_apic, &ls7a_dev); ++ ++ object_property_add_link(OBJECT(machine), ++ LOONGARCH_MACHINE_ACPI_DEVICE_PROP, ++ TYPE_HOTPLUG_HANDLER, ++ (Object **)&lsms->acpi_dev, ++ object_property_allow_set_link, ++ OBJ_PROP_LINK_STRONG); ++ object_property_set_link(OBJECT(machine), LOONGARCH_MACHINE_ACPI_DEVICE_PROP, ++ OBJECT(ls7a_dev), &error_abort); ++ ++#ifdef CONFIG_KVM ++ if (kvm_enabled()) { ++ kvm_direct_msi_allowed = (kvm_check_extension(kvm_state, ++ KVM_CAP_SIGNAL_MSI) > 0); ++ } else { ++ kvm_direct_msi_allowed = 0; ++ } ++ msi_nonbroken = kvm_direct_msi_allowed; ++#else ++ msi_nonbroken = true; ++#endif ++ sysbus_create_simple("ls7a_rtc", LS7A_RTC_REG_BASE, ++ ls7a_apic[LS7A_RTC_IRQ - LOONGARCH_PCH_IRQ_BASE]); ++ } ++ ++ /*Initialize the CPU serial device*/ ++ ++ if (serial_hd(0)) { ++ pirq = qemu_allocate_irqs(legacy_set_irq, ls7a_apic + ++ (LS7A_UART_IRQ - LOONGARCH_PCH_IRQ_BASE), 1); ++ serial_mm_init(address_space_mem, LS7A_UART_BASE, 0, pirq[0], ++ 115200, serial_hd(0), DEVICE_NATIVE_ENDIAN); ++ } ++ ++ /*network card*/ ++ network_init(pci_bus); ++ /* VGA setup. Don't bother loading the bios. */ ++ pci_vga_init(pci_bus); ++ ++ sysbus_realize_and_unref(SYS_BUS_DEVICE(qdev_new("iocsr")), &error_fatal); ++ ++#ifdef CONFIG_TCG ++ int nb_nodes = (smp_cpus - 1) / 4; ++ for (i = 0; i <= nb_nodes; i++) { ++ uint64_t off = (uint64_t)i << 44; ++ SIMPLE_OPS(((hwaddr)0x1fe00180 | off), 0x8); ++ SIMPLE_OPS(((hwaddr)0x1fe0019c | off), 0x8); ++ SIMPLE_OPS(((hwaddr)0x1fe001d0 | off), 0x8); ++ SIMPLE_OPS(((hwaddr)FEATURE_REG | off), 0x8); ++ SIMPLE_OPS(((hwaddr)VENDOR_REG | off), 0x8); ++ SIMPLE_OPS(((hwaddr)CPUNAME_REG | off), 0x8); ++ SIMPLE_OPS(((hwaddr)OTHER_FUNC_REG | off), 0x8); ++ } ++ ++ SIMPLE_OPS(0x1001041c, 0x4); ++ SIMPLE_OPS(0x10002000, 0x14); ++ SIMPLE_OPS(0x10013ffc, 0x4); ++#endif ++ ++ fdt_add_pcie_node(lsms); ++ ++ /* load fdt */ ++ MemoryRegion *fdt_rom = g_new(MemoryRegion, 1); ++ memory_region_init_rom(fdt_rom, NULL, "fdt", LS_FDT_SIZE, &error_fatal); ++ memory_region_add_subregion(get_system_memory(), LS_FDT_BASE, fdt_rom); ++ rom_add_blob_fixed("fdt", lsms->fdt, lsms->fdt_size, LS_FDT_BASE); ++} ++ ++static const CPUArchIdList *loongarch_possible_cpu_arch_ids(MachineState *ms) ++{ ++ int i; ++ int max_cpus = ms->smp.max_cpus; ++ ++ if (ms->possible_cpus) { ++ /* ++ * make sure that max_cpus hasn't changed since the first use, i.e. ++ * -smp hasn't been parsed after it ++ */ ++ assert(ms->possible_cpus->len == max_cpus); ++ return ms->possible_cpus; ++ } ++ ++ ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) + ++ sizeof(CPUArchId) * max_cpus); ++ ms->possible_cpus->len = max_cpus; ++ for (i = 0; i < ms->possible_cpus->len; i++) { ++ ms->possible_cpus->cpus[i].type = ms->cpu_type; ++ ms->possible_cpus->cpus[i].vcpus_count = 1; ++ ms->possible_cpus->cpus[i].props.has_core_id = true; ++ ms->possible_cpus->cpus[i].props.core_id = i; ++ ms->possible_cpus->cpus[i].arch_id = i; ++ } ++ return ms->possible_cpus; ++ ++} ++ ++static PFlashCFI01 *loongarch_pflash_create(LoongarchMachineState *lsms, ++ const char *name, ++ const char *alias_prop_name) ++{ ++ DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01); ++ ++ qdev_prop_set_uint64(dev, "sector-length", FLASH_SECTOR_SIZE); ++ qdev_prop_set_uint8(dev, "width", 1); ++ qdev_prop_set_string(dev, "name", name); ++ object_property_add_child(OBJECT(lsms), name, OBJECT(dev)); ++ object_property_add_alias(OBJECT(lsms), alias_prop_name, ++ OBJECT(dev), "drive"); ++ return PFLASH_CFI01(dev); ++} ++ ++ ++static void loongarch_system_flash_create(LoongarchMachineState *lsms) ++{ ++ lsms->flash[0] = loongarch_pflash_create(lsms, "system.flash0", ++ "pflash0"); ++ lsms->flash[1] = loongarch_pflash_create(lsms, "system.flash1", ++ "pflash1"); ++} ++ ++static void loongarch_machine_initfn(Object *obj) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(obj); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ lsms->acpi_build_enabled = lsmc->has_acpi_build; ++ loongarch_system_flash_create(lsms); ++ lsms->oem_id = g_strndup(EFI_ACPI_OEM_ID, 6); ++ lsms->oem_table_id = g_strndup(EFI_ACPI_OEM_TABLE_ID, 6); ++} ++ ++static void ls3a5k_ls7a_machine_options(MachineClass *m) ++{ ++ char *cpu_name = get_host_cpu_model_name(); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_CLASS(m); ++ m->desc = "Loongarch3a5k LS7A1000 machine"; ++ m->max_cpus = LOONGARCH_MAX_VCPUS; ++ m->alias = "loongson7a"; ++ m->is_default = 1; ++ lsmc->isa_io_base = LS3A5K_ISA_IO_BASE; ++ lsmc->ht1lo_pcicfg_base = LS3A5K_HT1LO_PCICFG_BASE; ++ lsmc->pciecfg_base = LS_PCIECFG_BASE; ++ lsmc->ls7a_ioapic_reg_base = LS3A5K_LS7A_IOAPIC_REG_BASE; ++ lsmc->node_shift = 44; ++ strncpy(lsmc->cpu_name, cpu_name, sizeof(lsmc->cpu_name) - 1); ++ lsmc->cpu_name[sizeof(lsmc->cpu_name) - 1] = 0; ++ strncpy(lsmc->bridge_name, "ls7a", sizeof(lsmc->bridge_name) - 1); ++ lsmc->bridge_name[sizeof(lsmc->bridge_name) - 1] = 0; ++ compat_props_add(m->compat_props, loongarch_compat, loongarch_compat_len); ++} ++ ++static void ls3a_board_reset(MachineState *ms) ++{ ++ qemu_devices_reset(); ++#ifdef CONFIG_KVM ++ struct loongarch_kvm_irqchip *chip; ++ int length; ++ ++ if (!kvm_enabled()) { ++ return; ++ } ++ length = sizeof(struct loongarch_kvm_irqchip) + ++ sizeof(struct loongarch_gipiState); ++ chip = g_malloc0(length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS3A_GIPI; ++ chip->len = length; ++ kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); ++ ++ length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct ls7a_ioapic_state); ++ chip = g_realloc(chip, length); ++ memset(chip, 0, length); ++ chip->chip_id = KVM_IRQCHIP_LS7A_IOAPIC; ++ chip->len = length; ++ kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); ++ ++ g_free(chip); ++#endif ++} ++ ++static CpuInstanceProperties ls3a_cpu_index_to_props(MachineState *ms, unsigned cpu_index) ++{ ++ MachineClass *mc = MACHINE_GET_CLASS(ms); ++ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); ++ ++ assert(cpu_index < possible_cpus->len); ++ return possible_cpus->cpus[cpu_index].props; ++} ++ ++static int64_t ls3a_get_default_cpu_node_id(const MachineState *ms, int idx) ++{ ++ int nb_numa_nodes = ms->numa_state->num_nodes; ++ int smp_cores = ms->smp.cores; ++ return idx / smp_cores % nb_numa_nodes; ++} ++ ++static void loongarch_class_init(ObjectClass *oc, void *data) ++{ ++ MachineClass *mc = MACHINE_CLASS(oc); ++ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_CLASS(oc); ++ ++ lsmc->get_hotplug_handler = mc->get_hotplug_handler; ++ lsmc->has_acpi_build = true; ++ mc->get_hotplug_handler = loongarch_get_hotpug_handler; ++ mc->has_hotpluggable_cpus = true; ++ mc->cpu_index_to_instance_props = ls3a_cpu_index_to_props; ++ mc->possible_cpu_arch_ids = loongarch_possible_cpu_arch_ids; ++ mc->get_default_cpu_node_id = ls3a_get_default_cpu_node_id; ++ mc->default_ram_size = 1 * GiB; ++ mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("Loongson-3A5000"); ++ mc->default_ram_id = "loongarch_ls3a.ram"; ++ ++ mc->reset = ls3a_board_reset; ++ mc->max_cpus = LOONGARCH_MAX_VCPUS; ++ hc->pre_plug = loongarch_machine_device_pre_plug; ++ hc->plug = loongarch_machine_device_plug; ++ hc->unplug = longson_machine_device_unplug; ++ hc->unplug_request = loongarch_machine_device_unplug_request; ++ ++ object_class_property_add(oc, "acpi", "OnOffAuto", ++ loongarch_get_acpi, loongarch_set_acpi, ++ NULL, NULL); ++ object_class_property_set_description(oc, "acpi", ++ "Enable ACPI"); ++} ++ ++static const TypeInfo loongarch_info = { ++ .name = TYPE_LOONGARCH_MACHINE, ++ .parent = TYPE_MACHINE, ++ .abstract = true, ++ .instance_size = sizeof(LoongarchMachineState), ++ .instance_init = loongarch_machine_initfn, ++ .class_size = sizeof(LoongarchMachineClass), ++ .class_init = loongarch_class_init, ++ .interfaces = (InterfaceInfo[]) { ++ { TYPE_HOTPLUG_HANDLER }, ++ { } ++ }, ++ ++}; ++ ++static void loongarch_machine_register_types(void) ++{ ++ type_register_static(&loongarch_info); ++} ++ ++type_init(loongarch_machine_register_types) ++ ++DEFINE_LS3A5K_MACHINE(loongson7a_v1_0, "loongson7a_v1.0", ++ ls3a5k_ls7a_machine_options); +diff --git a/hw/loongarch/larch_hotplug.c b/hw/loongarch/larch_hotplug.c +new file mode 100644 +index 000000000..7bce95712 +--- /dev/null ++++ b/hw/loongarch/larch_hotplug.c +@@ -0,0 +1,355 @@ ++/* ++ * Hotplug emulation on Loongarch system. ++ * ++ * Copyright (c) 2018 Loongarch Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++ ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include "qemu-common.h" ++#include "qemu/queue.h" ++#include "qemu/units.h" ++#include "qemu/cutils.h" ++#include "qemu/bcd.h" ++#include "hw/hotplug.h" ++#include "hw/loongarch/cpudevs.h" ++#include "hw/mem/memory-device.h" ++#include "sysemu/numa.h" ++#include "sysemu/cpus.h" ++#include "hw/loongarch/larch.h" ++#include "hw/cpu/core.h" ++#include "hw/nvram/fw_cfg.h" ++ ++/* find cpu slot in machine->possible_cpus by core_id */ ++static CPUArchId *loongarch_find_cpu_slot(MachineState *ms, uint32_t id, ++ int *idx) ++{ ++ int index = id; ++ ++ if (index >= ms->possible_cpus->len) { ++ return NULL; ++ } ++ if (idx) { ++ *idx = index; ++ } ++ return &ms->possible_cpus->cpus[index]; ++} ++ ++static void loongarch_memory_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ Error *local_err = NULL; ++ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); ++ HotplugHandlerClass *hhc; ++ uint64_t size; ++ ++ size = memory_device_get_region_size(MEMORY_DEVICE(dev), &error_abort); ++ if (size % LOONGARCH_HOTPLUG_MEM_ALIGN) { ++ error_setg(&local_err, "Hotplugged memory size must be a multiple of " ++ "%lld MB", LOONGARCH_HOTPLUG_MEM_ALIGN / MiB); ++ goto out; ++ } ++ ++ pc_dimm_plug(PC_DIMM(dev), MACHINE(lsms)); ++ ++ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); ++ hhc->plug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &error_abort); ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void loongarch_memory_unplug_request(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ Error *local_err = NULL; ++ HotplugHandlerClass *hhc; ++ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); ++ ++ if (!lsms->acpi_dev || !loongarch_is_acpi_enabled(lsms)) { ++ error_setg(&local_err, ++ "memory hotplug is not enabled: missing acpi device or acpi disabled"); ++ goto out; ++ } ++ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); ++ hhc->unplug_request(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); ++ ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void loongarch_cpu_unplug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ CPUArchId *found_cpu; ++ HotplugHandlerClass *hhc; ++ Error *local_err = NULL; ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); ++ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ ++ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); ++ hhc->unplug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); ++ ++ if (local_err) { ++ goto out; ++ } ++ ++ loongarch_cpu_destroy(machine, cpu); ++ ++ found_cpu = loongarch_find_cpu_slot(MACHINE(lsms), cpu->id, NULL); ++ found_cpu->cpu = NULL; ++ object_unparent(OBJECT(dev)); ++ lsms->hotpluged_cpu_num -= 1; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void loongarch_memory_unplug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ Error *local_err = NULL; ++ HotplugHandlerClass *hhc; ++ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); ++ ++ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); ++ hhc->unplug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); ++ ++ if (local_err) { ++ goto out; ++ } ++ ++ pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev)); ++ object_unparent(OBJECT(dev)); ++ ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void loongarch_cpu_pre_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ MachineState *ms = MACHINE(OBJECT(hotplug_dev)); ++ MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev); ++ LoongarchMachineState *lsms = LoongarchMACHINE(ms); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); ++ CPUArchId *cpu_slot; ++ Error *local_err = NULL; ++ int index; ++ int free_index = lsms->hotpluged_cpu_num + ms->smp.cpus; ++ int max_cpus = ms->smp.max_cpus; ++ ++ if (dev->hotplugged && !mc->has_hotpluggable_cpus) { ++ error_setg(&local_err, "CPU hotplug not supported for this machine"); ++ goto out; ++ } ++ ++ if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { ++ error_setg(errp, "Invalid CPU type, expected cpu type: '%s'", ++ ms->cpu_type); ++ return; ++ } ++ ++ /* if ID is not set, set it based on core properties */ ++ if (cpu->id == UNASSIGNED_CPU_ID) { ++ if ((cpu->core_id) > (max_cpus - 1)) { ++ error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u", ++ cpu->core_id, max_cpus - 1); ++ return; ++ } ++ ++ if (free_index > (max_cpus - 1)) { ++ error_setg(errp, "The maximum number of CPUs cannot exceed %u.", ++ max_cpus); ++ return; ++ } ++ ++ if (cpu->core_id != free_index) { ++ error_setg(errp, "Invalid CPU core-id: %u must be :%u", ++ cpu->core_id, free_index); ++ return; ++ } ++ ++ cpu->id = cpu->core_id; ++ } ++ ++ cpu_slot = loongarch_find_cpu_slot(MACHINE(hotplug_dev), cpu->id, &index); ++ if (!cpu_slot) { ++ error_setg(&local_err, "core id %d out of range", cpu->id); ++ goto out; ++ } ++ ++ if (cpu_slot->cpu) { ++ error_setg(&local_err, "core %d already populated", cpu->id); ++ goto out; ++ } ++ ++ numa_cpu_pre_plug(cpu_slot, dev, &local_err); ++ ++ return ; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void loongarch_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, ++ Error **errp) ++{ ++ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ PCDIMMDevice *dimm = PC_DIMM(dev); ++ Error *local_err = NULL; ++ uint64_t size; ++ ++ if (!lsms->acpi_dev || !loongarch_is_acpi_enabled(lsms)) { ++ error_setg(errp, ++ "memory hotplug is not enabled: missing acpi device or acpi disabled"); ++ return; ++ } ++ ++ size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &local_err); ++ if (local_err) { ++ error_propagate(errp, local_err); ++ return; ++ } ++ ++ if (size % LOONGARCH_HOTPLUG_MEM_ALIGN) { ++ error_setg(errp, "Hotplugged memory size must be a multiple of " ++ "%lld MB", LOONGARCH_HOTPLUG_MEM_ALIGN / MiB); ++ return; ++ } ++ ++ pc_dimm_pre_plug(dimm, MACHINE(hotplug_dev), NULL, errp); ++} ++ ++static void loongarch_cpu_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ CPUArchId *found_cpu; ++ HotplugHandlerClass *hhc; ++ Error *local_err = NULL; ++ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); ++ ++ if (lsms->acpi_dev) { ++ loongarch_cpu_create(machine, cpu, errp); ++ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); ++ hhc->plug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); ++ if (local_err) { ++ goto out; ++ } ++ } ++ ++ found_cpu = loongarch_find_cpu_slot(MACHINE(lsms), cpu->id, NULL); ++ found_cpu->cpu = OBJECT(dev); ++ lsms->hotpluged_cpu_num += 1; ++out: ++ error_propagate(errp, local_err); ++} ++ ++static void loongarch_cpu_unplug_request(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); ++ Error *local_err = NULL; ++ HotplugHandlerClass *hhc; ++ int idx = -1; ++ ++ if (!lsms->acpi_dev) { ++ error_setg(&local_err, "CPU hot unplug not supported without ACPI"); ++ goto out; ++ } ++ ++ loongarch_find_cpu_slot(MACHINE(lsms), cpu->id, &idx); ++ assert(idx != -1); ++ if (idx == 0) { ++ error_setg(&local_err, "Boot CPU is unpluggable"); ++ goto out; ++ } ++ ++ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); ++ hhc->unplug_request(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); ++ ++ if (local_err) { ++ goto out; ++ } ++ ++ out: ++ error_propagate(errp, local_err); ++} ++ ++void longson_machine_device_unplug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); ++ ++ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ loongarch_memory_unplug(hotplug_dev, dev, errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { ++ if (!mc->has_hotpluggable_cpus) { ++ error_setg(errp, "CPU hot unplug not supported on this machine"); ++ return; ++ } ++ loongarch_cpu_unplug(hotplug_dev, dev, errp); ++ } else { ++ error_setg(errp, "acpi: device unplug for not supported device" ++ " type: %s", object_get_typename(OBJECT(dev))); ++ } ++ ++ return; ++} ++ ++void loongarch_machine_device_unplug_request(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ loongarch_memory_unplug_request(hotplug_dev, dev, errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { ++ loongarch_cpu_unplug_request(hotplug_dev, dev, errp); ++ } ++} ++ ++HotplugHandler *loongarch_get_hotpug_handler(MachineState *machine, ++ DeviceState *dev) ++{ ++ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || ++ object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { ++ return HOTPLUG_HANDLER(machine); ++ } ++ return NULL; ++} ++ ++void loongarch_machine_device_pre_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ loongarch_memory_pre_plug(hotplug_dev, dev, errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { ++ loongarch_cpu_pre_plug(hotplug_dev, dev, errp); ++ } ++} ++ ++void loongarch_machine_device_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp) ++{ ++ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { ++ loongarch_memory_plug(hotplug_dev, dev, errp); ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { ++ loongarch_cpu_plug(hotplug_dev, dev, errp); ++ } ++} ++ +diff --git a/hw/loongarch/larch_int.c b/hw/loongarch/larch_int.c +new file mode 100644 +index 000000000..ca073a19c +--- /dev/null ++++ b/hw/loongarch/larch_int.c +@@ -0,0 +1,91 @@ ++/* ++ * QEMU LOONGARCH interrupt support ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ ++#include "qemu/osdep.h" ++#include "qemu/main-loop.h" ++#include "hw/hw.h" ++#include "hw/irq.h" ++#include "hw/loongarch/cpudevs.h" ++#include "cpu.h" ++#include "sysemu/kvm.h" ++#include "kvm_larch.h" ++#ifdef CONFIG_KVM ++#include ++#endif ++ ++static void cpu_irq_request(void *opaque, int irq, int level) ++{ ++ LOONGARCHCPU *cpu = opaque; ++ CPULOONGARCHState *env = &cpu->env; ++ CPUState *cs = CPU(cpu); ++ bool locked = false; ++ ++ if (irq < 0 || irq > 13) { ++ return; ++ } ++ ++ /* Make sure locking works even if BQL is already held by the caller */ ++ if (!qemu_mutex_iothread_locked()) { ++ locked = true; ++ qemu_mutex_lock_iothread(); ++ } ++ ++ if (level) { ++ env->CSR_ESTAT |= 1 << irq; ++ } else { ++ env->CSR_ESTAT &= ~(1 << irq); ++ } ++ ++ if (kvm_enabled()) { ++ if (irq == 2) { ++ kvm_loongarch_set_interrupt(cpu, irq, level); ++ } else if (irq == 3) { ++ kvm_loongarch_set_interrupt(cpu, irq, level); ++ } else if (irq == 12) { ++ kvm_loongarch_set_ipi_interrupt(cpu, irq, level); ++ } ++ } ++ ++ if (env->CSR_ESTAT & CSR_ESTAT_IPMASK) { ++ cpu_interrupt(cs, CPU_INTERRUPT_HARD); ++ } else { ++ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); ++ } ++ ++ if (locked) { ++ qemu_mutex_unlock_iothread(); ++ } ++} ++ ++void cpu_init_irq(LOONGARCHCPU *cpu) ++{ ++ CPULOONGARCHState *env = &cpu->env; ++ qemu_irq *qi; ++ int i; ++ ++ qi = qemu_allocate_irqs(cpu_irq_request, loongarch_env_get_cpu(env), N_IRQS); ++ for (i = 0; i < N_IRQS; i++) { ++ env->irq[i] = qi[i]; ++ } ++} ++ ++ +diff --git a/hw/loongarch/ls7a_nb.c b/hw/loongarch/ls7a_nb.c +new file mode 100644 +index 000000000..5a500fbd5 +--- /dev/null ++++ b/hw/loongarch/ls7a_nb.c +@@ -0,0 +1,352 @@ ++/* ++ * Loongarch 7A1000 north bridge support ++ * ++ * Copyright (c) 2019 Loongarch Technology ++ * Authors: ++ * Zhu Chen ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ ++#include "qemu/osdep.h" ++ ++#include "hw/hw.h" ++#include "hw/irq.h" ++#include "hw/sysbus.h" ++#include "hw/pci/pci.h" ++#include "hw/i386/pc.h" ++#include "hw/pci/pci_host.h" ++#include "hw/pci/pcie_host.h" ++#include "sysemu/sysemu.h" ++#include "exec/address-spaces.h" ++#include "qapi/error.h" ++#include "hw/loongarch/cpudevs.h" ++#include "hw/acpi/ls7a.h" ++#include "hw/i386/pc.h" ++#include "hw/isa/isa.h" ++#include "hw/boards.h" ++#include "qemu/log.h" ++#include "hw/loongarch/bios.h" ++#include "hw/loader.h" ++#include "elf.h" ++#include "exec/address-spaces.h" ++#include "exec/memory.h" ++#include "hw/pci/pci_bridge.h" ++#include "hw/pci/pci_bus.h" ++#include "linux/kvm.h" ++#include "sysemu/kvm.h" ++#include "sysemu/runstate.h" ++#include "sysemu/reset.h" ++#include "migration/vmstate.h" ++#include "hw/loongarch/larch.h" ++#include "hw/loongarch/ls7a.h" ++ ++#undef DEBUG_LS7A ++ ++#ifdef DEBUG_LS7A ++#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) ++#else ++#define DPRINTF(fmt, ...) ++#endif ++ ++static void ls7a_reset(void *opaque) ++{ ++ uint64_t wmask; ++ wmask = ~(-1); ++ ++ PCIDevice *dev = opaque; ++ pci_set_word(dev->config + PCI_VENDOR_ID, 0x0014); ++ pci_set_word(dev->wmask + PCI_VENDOR_ID, wmask & 0xffff); ++ pci_set_word(dev->cmask + PCI_VENDOR_ID, 0xffff); ++ pci_set_word(dev->config + PCI_DEVICE_ID, 0x7a00); ++ pci_set_word(dev->wmask + PCI_DEVICE_ID, wmask & 0xffff); ++ pci_set_word(dev->cmask + PCI_DEVICE_ID, 0xffff); ++ pci_set_word(dev->config + 0x4, 0x0000); ++ pci_set_word(dev->config + PCI_STATUS, 0x0010); ++ pci_set_word(dev->wmask + PCI_STATUS, wmask & 0xffff); ++ pci_set_word(dev->cmask + PCI_STATUS, 0xffff); ++ pci_set_byte(dev->config + PCI_REVISION_ID, 0x0); ++ pci_set_byte(dev->wmask + PCI_REVISION_ID, wmask & 0xff); ++ pci_set_byte(dev->cmask + PCI_REVISION_ID, 0xff); ++ pci_set_byte(dev->config + 0x9, 0x00); ++ pci_set_byte(dev->wmask + 0x9, wmask & 0xff); ++ pci_set_byte(dev->cmask + 0x9, 0xff); ++ pci_set_byte(dev->config + 0xa, 0x00); ++ pci_set_byte(dev->wmask + 0xa, wmask & 0xff); ++ pci_set_byte(dev->cmask + 0xa, 0xff); ++ pci_set_byte(dev->config + 0xb, 0x06); ++ pci_set_byte(dev->wmask + 0xb, wmask & 0xff); ++ pci_set_byte(dev->cmask + 0xb, 0xff); ++ pci_set_byte(dev->config + 0xc, 0x00); ++ pci_set_byte(dev->wmask + 0xc, wmask & 0xff); ++ pci_set_byte(dev->cmask + 0xc, 0xff); ++ pci_set_byte(dev->config + 0xe, 0x80); ++ pci_set_byte(dev->wmask + 0xe, wmask & 0xff); ++ pci_set_byte(dev->cmask + 0xe, 0xff); ++} ++ ++static const VMStateDescription vmstate_ls7a_pcie = { ++ .name = "LS7A_PCIE", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_PCI_DEVICE(dev, LS7APCIState), ++ VMSTATE_STRUCT(pm, LS7APCIState, 0, vmstate_ls7a_pm, LS7APCIPMRegs), ++ VMSTATE_UINT32_ARRAY(regs, LS7APCIState, LS7A_REGS), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static PCIINTxRoute ls7a_route_intx_pin_to_irq(void *opaque, int pin) ++{ ++ PCIINTxRoute route; ++ ++ route.irq = pin; ++ route.mode = PCI_INTX_ENABLED; ++ return route; ++} ++ ++static int pci_ls7a_map_irq(PCIDevice *d, int irq_num) ++{ ++ int irq; ++ ++ irq = 16 + ((PCI_SLOT(d->devfn) * 4 + irq_num) & 0xf); ++ return irq; ++} ++ ++static void pci_ls7a_set_irq(void *opaque, int irq_num, int level) ++{ ++ qemu_irq *pic = opaque; ++ DPRINTF("------ %s irq %d %d\n", __func__, irq_num, level); ++ qemu_set_irq(pic[irq_num], level); ++} ++ ++/* ++static int ls7a_pciehost_initfn(SysBusDevice *dev) ++{ ++ return 0; ++}*/ ++ ++static void ls7a_pcie_realize(PCIDevice *dev, Error **errp) ++{ ++ LS7APCIState *s = PCIE_LS7A(dev); ++ /* Ls7a North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" */ ++ pci_config_set_prog_interface(dev->config, 0x00); ++ ++ /* set the default value of north bridge pci config */ ++ qemu_register_reset(ls7a_reset, s); ++} ++ ++static void pci_ls7a_config_write(void *opaque, hwaddr addr, ++ uint64_t val, unsigned size) ++{ ++ hwaddr tmp_addr; ++ tmp_addr = addr & 0xffffff; ++ ++ pci_data_write(opaque, tmp_addr, val, size); ++} ++ ++static uint64_t pci_ls7a_config_read(void *opaque, ++ hwaddr addr, unsigned size) ++{ ++ uint64_t val; ++ hwaddr tmp_addr; ++ ++ tmp_addr = addr & 0xffffff; ++ val = pci_data_read(opaque, tmp_addr, size); ++ ++ if (addr & 0x3c) { ++ DPRINTF(TARGET_FMT_plx" val %lx\n", addr, val); ++ } ++ return val; ++} ++ ++static const MemoryRegionOps pci_ls7a_config_ops = { ++ .read = pci_ls7a_config_read, ++ .write = pci_ls7a_config_write, ++ /* Set to access 64bits data, because default to 32bits*/ ++ .valid = { ++ .min_access_size = 1, ++ .max_access_size = 4, ++ }, ++ /* Set to access 64bits data, because default to 32bits*/ ++ .impl = { ++ .min_access_size = 1, ++ .max_access_size = 4, ++ }, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++ ++}; ++ ++static AddressSpace *ls7a_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) ++{ ++ return &address_space_memory; ++} ++ ++static PCIBus *pci_ls7a_init(MachineState *machine, DeviceState *dev, ++ qemu_irq *pic) ++{ ++ LoongarchMachineState *lsms = LoongarchMACHINE(machine); ++ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ PCIExpressHost *e; ++ SysBusDevice *sysbus; ++ MemoryRegion *iomem = g_new(MemoryRegion, 1); ++ PCIHostState *phb; ++ ++ e = PCIE_HOST_BRIDGE(dev); ++ sysbus = SYS_BUS_DEVICE(e); ++ phb = PCI_HOST_BRIDGE(e); ++ phb->bus = pci_register_root_bus(dev, "pcie.0", pci_ls7a_set_irq, ++ pci_ls7a_map_irq, pic, ++ get_system_memory(), get_system_io(), ++ (1 << 3), 128, TYPE_PCIE_BUS); ++ pcie_host_mmcfg_update(e, true, lsmc->pciecfg_base, LS_PCIECFG_SIZE); ++ DPRINTF("------ %d\n", __LINE__); ++ ++ pci_bus_set_route_irq_fn(phb->bus, ls7a_route_intx_pin_to_irq); ++ memory_region_init_io(iomem, NULL, &pci_ls7a_config_ops, phb->bus, ++ "ls7a_pci_conf", HT1LO_PCICFG_SIZE); ++ sysbus_init_mmio(sysbus, iomem); ++ sysbus_mmio_map(sysbus, 0, lsmc->ht1lo_pcicfg_base); ++ ++ return phb->bus; ++} ++ ++PCIBus *ls7a_init(MachineState *machine, qemu_irq *pic, DeviceState **ls7a_dev) ++{ ++ DeviceState *dev; ++ PCIHostState *phb; ++ LS7APCIState *pbs; ++ PCIDevice *pcid; ++ PCIBus *pci_bus; ++ PCIExpressHost *e; ++ ++ /*1. init the HT PCI CFG*/ ++ DPRINTF("------ %d\n", __LINE__); ++ dev = qdev_new(TYPE_LS7A_PCIE_HOST_BRIDGE); ++ e = PCIE_HOST_BRIDGE(dev); ++ phb = PCI_HOST_BRIDGE(e); ++ ++ DPRINTF("------ %d\n", __LINE__); ++ pci_bus = pci_ls7a_init(machine, dev, pic); ++ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); ++ phb->bus = pci_bus; ++ /* set the pcihost pointer after rs780_pcihost_initfn is called */ ++ DPRINTF("------ %d\n", __LINE__); ++ pcid = pci_new(PCI_DEVFN(0, 0), TYPE_PCIE_LS7A); ++ pbs = PCIE_LS7A(pcid); ++ pbs->pciehost = LS7A_PCIE_HOST_BRIDGE(dev); ++ pbs->pciehost->pci_dev = pbs; ++ ++ if (ls7a_dev) { ++ *ls7a_dev = DEVICE(pcid); ++ } ++ ++ pci_realize_and_unref(pcid, phb->bus, &error_fatal); ++ ++ /* IOMMU */ ++ pci_setup_iommu(phb->bus, ls7a_pci_dma_iommu, NULL); ++ ++ ls7a_pm_init(&pbs->pm, pic); ++ DPRINTF("------ %d\n", __LINE__); ++ /*3. init the north bridge VGA,not do now*/ ++ return pci_bus; ++} ++ ++LS7APCIState *get_ls7a_type(Object *obj) ++{ ++ LS7APCIState *pbs; ++ ++ pbs = PCIE_LS7A(obj); ++ return pbs; ++} ++ ++static void ls7a_pcie_class_init(ObjectClass *klass, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(klass); ++ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); ++ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); ++ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(klass); ++ ++ k->realize = ls7a_pcie_realize; ++ k->vendor_id = 0x0014; ++ k->device_id = 0x7a00; ++ k->revision = 0x00; ++ k->class_id = PCI_CLASS_BRIDGE_HOST; ++ dc->desc = "LS7A1000 PCIE Host bridge"; ++ dc->vmsd = &vmstate_ls7a_pcie; ++ /* ++ * PCI-facing part of the host bridge, not usable without the ++ * host-facing part, which can't be device_add'ed, yet. ++ */ ++ dc->user_creatable = false; ++ hc->plug = ls7a_pm_device_plug_cb; ++ hc->unplug_request = ls7a_pm_device_unplug_request_cb; ++ hc->unplug = ls7a_pm_device_unplug_cb; ++ adevc->ospm_status = ls7a_pm_ospm_status; ++ adevc->send_event = ls7a_send_gpe; ++ adevc->madt_cpu = ls7a_madt_cpu_entry; ++} ++ ++static void ls7a_pci_add_properties(LS7APCIState *ls7a) ++{ ++ ls7a_pm_add_properties(OBJECT(ls7a), &ls7a->pm, NULL); ++} ++ ++static void ls7a_pci_initfn(Object *obj) ++{ ++ LS7APCIState *ls7a = get_ls7a_type(obj); ++ ++ ls7a_pci_add_properties(ls7a); ++} ++ ++static const TypeInfo ls7a_pcie_device_info = { ++ .name = TYPE_PCIE_LS7A, ++ .parent = TYPE_PCI_DEVICE, ++ .instance_size = sizeof(LS7APCIState), ++ .class_init = ls7a_pcie_class_init, ++ .instance_init = ls7a_pci_initfn, ++ .interfaces = (InterfaceInfo[]) { ++ { TYPE_HOTPLUG_HANDLER }, ++ { TYPE_ACPI_DEVICE_IF }, ++ { INTERFACE_CONVENTIONAL_PCI_DEVICE }, ++ { }, ++ }, ++}; ++ ++static void ls7a_pciehost_class_init(ObjectClass *klass, void *data) ++{ ++ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); ++ k->parent_class.fw_name = "pci"; ++} ++ ++static const TypeInfo ls7a_pciehost_info = { ++ .name = TYPE_LS7A_PCIE_HOST_BRIDGE, ++ .parent = TYPE_PCIE_HOST_BRIDGE, ++ .instance_size = sizeof(LS7APCIEHost), ++ .class_init = ls7a_pciehost_class_init, ++}; ++ ++static void ls7a_register_types(void) ++{ ++ type_register_static(&ls7a_pciehost_info); ++ type_register_static(&ls7a_pcie_device_info); ++} ++ ++type_init(ls7a_register_types) +diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build +new file mode 100644 +index 000000000..81ee99a02 +--- /dev/null ++++ b/hw/loongarch/meson.build +@@ -0,0 +1,15 @@ ++loongarch_ss = ss.source_set() ++loongarch_ss.add(files('larch_3a.c'), fdt) ++loongarch_ss.add(files( ++ 'larch_int.c', ++ 'larch_hotplug.c', ++ 'ls7a_nb.c', ++ 'ioapic.c', ++ 'acpi-build.c', ++ 'ipi.c', ++ 'apic.c', ++ 'iocsr.c', ++)) ++ ++hw_arch += {'loongarch64': loongarch_ss} ++ +diff --git a/include/hw/loongarch/bios.h b/include/hw/loongarch/bios.h +new file mode 100644 +index 000000000..3677303bf +--- /dev/null ++++ b/include/hw/loongarch/bios.h +@@ -0,0 +1,5 @@ ++#include "qemu/units.h" ++#include "cpu.h" ++ ++#define BIOS_SIZE (4 * MiB) ++#define BIOS_FILENAME "loongarch_bios.bin" +diff --git a/include/hw/loongarch/cpudevs.h b/include/hw/loongarch/cpudevs.h +new file mode 100644 +index 000000000..c05ae7a7f +--- /dev/null ++++ b/include/hw/loongarch/cpudevs.h +@@ -0,0 +1,53 @@ ++#ifndef HW_LOONGARCH_CPUDEVS_H ++#define HW_LOONGARCH_CPUDEVS_H ++ ++#include "target/loongarch64/cpu-qom.h" ++ ++/* Definitions for LOONGARCH CPU internal devices. */ ++#define MAX_GIPI_CORE_NUM 256 ++#define MAX_GIPI_MBX_NUM 4 ++ ++#define LS3A_INTC_IP 8 ++#define MAX_CORES 256 ++#define EXTIOI_IRQS (256) ++#define EXTIOI_IRQS_BITMAP_SIZE (256 / 8) ++/* map to ipnum per 32 irqs */ ++#define EXTIOI_IRQS_IPMAP_SIZE (256 / 32) ++ ++typedef struct gipi_core { ++ uint32_t status; ++ uint32_t en; ++ uint32_t set; ++ uint32_t clear; ++ uint64_t buf[MAX_GIPI_MBX_NUM]; ++ qemu_irq irq; ++} gipi_core; ++ ++typedef struct gipiState { ++ gipi_core core[MAX_GIPI_CORE_NUM]; ++} gipiState; ++ ++typedef struct apicState { ++ /* hardware state */ ++ uint8_t ext_en[EXTIOI_IRQS_BITMAP_SIZE]; ++ uint8_t ext_bounce[EXTIOI_IRQS_BITMAP_SIZE]; ++ uint8_t ext_isr[EXTIOI_IRQS_BITMAP_SIZE]; ++ uint8_t ext_coreisr[MAX_CORES][EXTIOI_IRQS_BITMAP_SIZE]; ++ uint8_t ext_ipmap[EXTIOI_IRQS_IPMAP_SIZE]; ++ uint8_t ext_coremap[EXTIOI_IRQS]; ++ uint16_t ext_nodetype[16]; ++ uint64_t ext_control; ++ ++ /* software state */ ++ uint8_t ext_sw_ipmap[EXTIOI_IRQS]; ++ uint8_t ext_sw_coremap[EXTIOI_IRQS]; ++ uint8_t ext_ipisr[MAX_CORES * LS3A_INTC_IP][EXTIOI_IRQS_BITMAP_SIZE]; ++ ++ qemu_irq parent_irq[MAX_CORES][LS3A_INTC_IP]; ++ qemu_irq *irq; ++} apicState; ++ ++void cpu_init_irq(LOONGARCHCPU *cpu); ++void cpu_loongarch_clock_init(LOONGARCHCPU *cpu); ++ ++#endif +diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h +new file mode 100644 +index 000000000..0886ed52a +--- /dev/null ++++ b/include/hw/loongarch/larch.h +@@ -0,0 +1,163 @@ ++/* ++ * Hotplug emulation on Loongarch system. ++ * ++ * Copyright (c) 2018 Loongarch Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++ ++#ifndef HW_LOONGARCH_H ++#define HW_LOONGARCH_H ++ ++#include "target/loongarch64/cpu.h" ++#include "qemu-common.h" ++#include "exec/memory.h" ++#include "hw/mem/pc-dimm.h" ++#include "hw/hotplug.h" ++#include "hw/boards.h" ++#include "hw/acpi/acpi.h" ++#include "qemu/notify.h" ++#include "qemu/error-report.h" ++#include "qemu/queue.h" ++#include "hw/acpi/memory_hotplug.h" ++#include "hw/loongarch/cpudevs.h" ++#include "hw/block/flash.h" ++ ++#define LOONGARCH_MAX_VCPUS 256 ++#define LOONGARCH_MAX_PFLASH 2 ++/* 256MB alignment for hotplug memory region */ ++#define LOONGARCH_HOTPLUG_MEM_ALIGN (1ULL << 28) ++#define LOONGARCH_MAX_RAM_SLOTS 10 ++ ++/* Memory types: */ ++#define SYSTEM_RAM 1 ++#define SYSTEM_RAM_RESERVED 2 ++#define ACPI_TABLE 3 ++#define ACPI_NVS 4 ++#define SYSTEM_PMEM 5 ++ ++#define MAX_MEM_MAP 128 ++ ++typedef struct LoongarchMachineClass { ++ /*< private >*/ ++ MachineClass parent_class; ++ ++ /* Methods: */ ++ HotplugHandler *(*get_hotplug_handler)(MachineState *machine, ++ DeviceState *dev); ++ ++ bool has_acpi_build; ++ ++ /* save different cpu address*/ ++ uint64_t isa_io_base; ++ uint64_t ht_control_regs_base; ++ uint64_t hpet_mmio_addr; ++ uint64_t smbus_cfg_base; ++ uint64_t ht1lo_pcicfg_base; ++ uint64_t pciecfg_base; ++ uint64_t ls7a_ioapic_reg_base; ++ uint32_t node_shift; ++ char cpu_name[40]; ++ char bridge_name[16]; ++ ++} LoongarchMachineClass; ++ ++typedef struct ResetData { ++ LOONGARCHCPU *cpu; ++ uint64_t vector; ++} ResetData; ++ ++typedef struct LoongarchMachineState { ++ /*< private >*/ ++ MachineState parent_obj; ++ ++ /* */ ++ ram_addr_t hotplug_memory_size; ++ ++ /* State for other subsystems/APIs: */ ++ Notifier machine_done; ++ /* Pointers to devices and objects: */ ++ HotplugHandler *acpi_dev; ++ int ram_slots; ++ ResetData *reset_info[LOONGARCH_MAX_VCPUS]; ++ DeviceState *rtc; ++ gipiState *gipi; ++ apicState *apic; ++ ++ FWCfgState *fw_cfg; ++ bool acpi_build_enabled; ++ bool apic_xrupt_override; ++ CPUArchIdList *possible_cpus; ++ PFlashCFI01 *flash[LOONGARCH_MAX_PFLASH]; ++ void *fdt; ++ int fdt_size; ++ unsigned int hotpluged_cpu_num; ++ OnOffAuto acpi; ++ char *oem_id; ++ char *oem_table_id; ++} LoongarchMachineState; ++ ++#define LOONGARCH_MACHINE_ACPI_DEVICE_PROP "loongarch-acpi-device" ++#define TYPE_LOONGARCH_MACHINE "loongarch-machine" ++ ++#define LoongarchMACHINE(obj) \ ++ OBJECT_CHECK(LoongarchMachineState, (obj), TYPE_LOONGARCH_MACHINE) ++#define LoongarchMACHINE_GET_CLASS(obj) \ ++ OBJECT_GET_CLASS(LoongarchMachineClass, (obj), TYPE_LOONGARCH_MACHINE) ++#define LoongarchMACHINE_CLASS(klass) \ ++ OBJECT_CLASS_CHECK(LoongarchMachineClass, (klass), TYPE_LOONGARCH_MACHINE) ++ ++#define DEFINE_LOONGARCH_MACHINE(suffix, namestr, initfn, optsfn) \ ++ static void loongarch_machine_##suffix##_class_init(ObjectClass *oc, void *data) \ ++ { \ ++ MachineClass *mc = MACHINE_CLASS(oc); \ ++ optsfn(mc); \ ++ mc->init = initfn; \ ++ } \ ++ static const TypeInfo loongarch_machine_type_##suffix = { \ ++ .name = namestr TYPE_MACHINE_SUFFIX, \ ++ .parent = TYPE_LOONGARCH_MACHINE, \ ++ .class_init = loongarch_machine_##suffix##_class_init, \ ++ }; \ ++ static void loongarch_machine_init_##suffix(void) \ ++ { \ ++ type_register(&loongarch_machine_type_##suffix); \ ++ } \ ++ type_init(loongarch_machine_init_##suffix) ++ ++void loongarch_machine_device_unplug_request(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp); ++void longson_machine_device_unplug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp); ++HotplugHandler *loongarch_get_hotpug_handler(MachineState *machine, ++ DeviceState *dev); ++void loongarch_machine_device_pre_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp); ++void loongarch_machine_device_plug(HotplugHandler *hotplug_dev, ++ DeviceState *dev, Error **errp); ++ ++LOONGARCHCPU *loongarch_cpu_create(MachineState *machine, LOONGARCHCPU *cpu, ++ Error **errp); ++void loongarch_cpu_destroy(MachineState *machine, LOONGARCHCPU *cpu); ++int cpu_init_ipi(LoongarchMachineState *ms, qemu_irq parent, int cpu); ++int cpu_init_apic(LoongarchMachineState *ms, CPULOONGARCHState *env, int cpu); ++int la_memmap_add_entry(uint64_t address, uint64_t length, uint32_t type); ++bool loongarch_is_acpi_enabled(LoongarchMachineState *vms); ++ ++/* acpi-build.c */ ++void ls7a_madt_cpu_entry(AcpiDeviceIf *adev, int uid, ++ const CPUArchIdList *apic_ids, GArray *entry, bool force_enabled); ++void slave_cpu_reset(void *opaque); ++extern uint64_t host_cpufreq; ++#endif +diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h +new file mode 100644 +index 000000000..686af763a +--- /dev/null ++++ b/include/hw/loongarch/ls7a.h +@@ -0,0 +1,152 @@ ++#ifndef HW_LS7A_H ++#define HW_LS7A_H ++ ++#include "hw/hw.h" ++#include "hw/isa/isa.h" ++#include "hw/sysbus.h" ++#include "hw/isa/apm.h" ++#include "hw/pci/pci.h" ++#include "hw/pci/pcie_host.h" ++#include "hw/pci/pci_bridge.h" ++#include "hw/acpi/acpi.h" ++#include "hw/acpi/ls7a.h" ++#include "hw/pci/pci_bus.h" ++ ++/* LS7A PCH Registers (Misc, Confreg) */ ++#define LS7A_PCH_REG_BASE 0x10000000UL ++#define LS3A5K_LS7A_IOAPIC_REG_BASE (LS7A_PCH_REG_BASE) ++#define LS7A_MISC_REG_BASE (LS7A_PCH_REG_BASE + 0x00080000) ++#define LS7A_ACPI_REG_BASE (LS7A_MISC_REG_BASE + 0x00050000) ++ ++#define LOONGARCH_PCH_IRQ_BASE 64 ++#define LS7A_UART_IRQ (LOONGARCH_PCH_IRQ_BASE + 2) ++#define LS7A_RTC_IRQ (LOONGARCH_PCH_IRQ_BASE + 3) ++#define LS7A_SCI_IRQ (LOONGARCH_PCH_IRQ_BASE + 4) ++#define LS7A_ACPI_IO_BASE 0x800 ++#define LS7A_ACPI_IO_SIZE 0x100 ++#define LS7A_PM_EVT_BLK (0x0C) /* 4 bytes */ ++#define LS7A_PM_CNT_BLK (0x14) /* 2 bytes */ ++#define LS7A_GPE0_STS_REG (0x28) /* 4 bytes */ ++#define LS7A_GPE0_ENA_REG (0x2C) /* 4 bytes */ ++#define LS7A_GPE0_RESET_REG (0x30) /* 4 bytes */ ++#define LS7A_PM_TMR_BLK (0x18) /* 4 bytes */ ++#define LS7A_GPE0_LEN (8) ++#define LS7A_RTC_REG_BASE (LS7A_MISC_REG_BASE + 0x00050100) ++#define LS7A_RTC_LEN (0x100) ++ ++#define ACPI_IO_BASE (LS7A_ACPI_REG_BASE) ++#define ACPI_GPE0_LEN (LS7A_GPE0_LEN) ++#define ACPI_IO_SIZE (LS7A_ACPI_IO_SIZE) ++#define ACPI_SCI_IRQ (LS7A_SCI_IRQ) ++ ++#define LS3A5K_ISA_IO_BASE 0x18000000UL ++#define LS_ISA_MEM_BASE 0x40000000 ++#define LS3A5K_HT1LO_PCICFG_BASE 0x1a000000 ++#define HT1LO_PCICFG_SIZE 0x02000000 ++#define LS_BIOS_BASE 0x1c000000 ++#define LS_BIOS_VAR_BASE 0x1c3a0000 ++#define LS_BIOS_SIZE (4 * 1024 * 1024) ++ ++#define FW_CFG_ADDR 0x1e020000 ++#define LS7A_REG_BASE 0x1FE00000 ++#define LS7A_PCICONFIG_BASE (LS7A_REG_BASE + 0x30) ++#define LS7A_PCICONFIG_SIZE (0x100) ++#define LS7A_INTERNAL_REG_BASE (LS7A_REG_BASE + 0x100) ++#define LS7A_INTERNAL_REG_SIZE (0xE0) ++#define LS7A_REGS (0xE0 >> 2) ++#define LS7A_UART_BASE 0x1fe001e0 ++#define LS7A_UART_LEN 0x8 ++ ++#define LS_FDT_BASE 0x1c400000 ++#define LS_FDT_SIZE 0x100000 ++ ++#define LS_PCIECFG_BASE 0x20000000 ++#define LS_PCIECFG_SIZE 0x08000000 ++#define MSI_ADDR_LOW 0x2FF00000 ++#define MSI_ADDR_HI 0x0 ++ ++#define SMP_GIPI_MAILBOX 0x1f000000ULL ++#define CORE0_STATUS_OFF 0x000 ++#define CORE0_EN_OFF 0x004 ++#define CORE0_SET_OFF 0x008 ++#define CORE0_CLEAR_OFF 0x00c ++#define CORE0_BUF_20 0x020 ++#define CORE0_BUF_28 0x028 ++#define CORE0_BUF_30 0x030 ++#define CORE0_BUF_38 0x038 ++#define CORE0_IPI_SEND 0x040 ++#define CORE0_MAIL_SEND 0x048 ++ ++#define INT_ROUTER_REGS_BASE 0x1fe01400UL ++#define INT_ROUTER_REGS_SIZE 0x100 ++#define INT_ROUTER_REGS_SYS_INT0 0x00 ++#define INT_ROUTER_REGS_SYS_INT1 0x01 ++#define INT_ROUTER_REGS_SYS_INT2 0x02 ++#define INT_ROUTER_REGS_SYS_INT3 0x03 ++#define INT_ROUTER_REGS_PCI_INT0 0x04 ++#define INT_ROUTER_REGS_PCI_INT1 0x05 ++#define INT_ROUTER_REGS_PCI_INT2 0x06 ++#define INT_ROUTER_REGS_PCI_INT3 0x07 ++#define INT_ROUTER_REGS_MATRIX_INT0 0x08 ++#define INT_ROUTER_REGS_MATRIX_INT1 0x09 ++#define INT_ROUTER_REGS_LPC_INT 0x0a ++#define INT_ROUTER_REGS_MC0 0x0b ++#define INT_ROUTER_REGS_MC1 0x0c ++#define INT_ROUTER_REGS_BARRIER 0x0d ++#define INT_ROUTER_REGS_THSENS_INT 0x0e ++#define INT_ROUTER_REGS_PCI_PERR 0x0f ++#define INT_ROUTER_REGS_HT0_INT0 0x10 ++#define INT_ROUTER_REGS_HT0_INT1 0x11 ++#define INT_ROUTER_REGS_HT0_INT2 0x12 ++#define INT_ROUTER_REGS_HT0_INT3 0x13 ++#define INT_ROUTER_REGS_HT0_INT4 0x14 ++#define INT_ROUTER_REGS_HT0_INT5 0x15 ++#define INT_ROUTER_REGS_HT0_INT6 0x16 ++#define INT_ROUTER_REGS_HT0_INT7 0x17 ++#define INT_ROUTER_REGS_HT1_INT0 0x18 ++#define INT_ROUTER_REGS_HT1_INT1 0x19 ++#define INT_ROUTER_REGS_HT1_INT2 0x1a ++#define INT_ROUTER_REGS_HT1_INT3 0x1b ++#define INT_ROUTER_REGS_HT1_INT4 0x1c ++#define INT_ROUTER_REGS_HT1_INT5 0x1d ++#define INT_ROUTER_REGS_HT1_INT6 0x1e ++#define INT_ROUTER_REGS_HT1_INT7 0x1f ++#define INT_ROUTER_REGS_ISR 0x20 ++#define INT_ROUTER_REGS_EN 0x24 ++#define INT_ROUTER_REGS_EN_SET 0x28 ++#define INT_ROUTER_REGS_EN_CLR 0x2c ++#define INT_ROUTER_REGS_EDGE 0x38 ++#define INT_ROUTER_REGS_CORE0_INTISR 0x40 ++#define INT_ROUTER_REGS_CORE1_INTISR 0x48 ++#define INT_ROUTER_REGS_CORE2_INTISR 0x50 ++#define INT_ROUTER_REGS_CORE3_INTISR 0x58 ++ ++typedef struct LS7APCIState LS7APCIState; ++typedef struct LS7APCIEHost { ++ PCIExpressHost parent_obj; ++ LS7APCIState *pci_dev; ++} LS7APCIEHost; ++ ++struct LS7APCIState { ++ PCIDevice dev; ++ ++ LS7APCIEHost *pciehost; ++ uint32_t regs[LS7A_REGS]; ++ ++ /* LS7A registers */ ++ MemoryRegion iomem; ++ LS7APCIPMRegs pm; ++}; ++ ++#define TYPE_LS7A_PCIE_HOST_BRIDGE "ls7a1000-pciehost" ++#define LS7A_PCIE_HOST_BRIDGE(obj) \ ++ OBJECT_CHECK(LS7APCIEHost, (obj), TYPE_LS7A_PCIE_HOST_BRIDGE) ++ ++#define TYPE_PCIE_LS7A "ls7a1000_pcie" ++#define PCIE_LS7A(obj) \ ++ OBJECT_CHECK(LS7APCIState, (obj), TYPE_PCIE_LS7A) ++ ++PCIBus *ls7a_init(MachineState *machine, qemu_irq *irq, DeviceState **ls7a_dev); ++LS7APCIState *get_ls7a_type(Object *obj); ++ ++#endif /* HW_LS7A_H */ +-- +2.27.0 + diff --git a/Add-loongarch64-rh-devices.mak.patch b/Add-loongarch64-rh-devices.mak.patch new file mode 100644 index 00000000..b2c80fdc --- /dev/null +++ b/Add-loongarch64-rh-devices.mak.patch @@ -0,0 +1,3212 @@ +From 6434428d8170ddb43505d62ef6a052f15c3c1978 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Wed, 7 Dec 2022 05:24:26 -0500 +Subject: [PATCH 09/11] Add loongarch64-rh-devices.mak. + +Signed-off-by: lixianglai +--- + .../loongarch64-rh-devices.mak | 155 ++ + configure | 5 + + pc-bios/meson.build | 1 + + tcg/loongarch64/tcg-insn-defs.c.inc | 979 +++++++++ + tcg/loongarch64/tcg-target-con-set.h | 31 + + tcg/loongarch64/tcg-target-con-str.h | 28 + + tcg/loongarch64/tcg-target.c.inc | 1744 +++++++++++++++++ + tcg/loongarch64/tcg-target.h | 178 ++ + 8 files changed, 3121 insertions(+) + create mode 100644 configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak + create mode 100644 tcg/loongarch64/tcg-insn-defs.c.inc + create mode 100644 tcg/loongarch64/tcg-target-con-set.h + create mode 100644 tcg/loongarch64/tcg-target-con-str.h + create mode 100644 tcg/loongarch64/tcg-target.c.inc + create mode 100644 tcg/loongarch64/tcg-target.h + +diff --git a/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak +new file mode 100644 +index 000000000..e7b5bdc8e +--- /dev/null ++++ b/configs/devices/loongarch64-softmmu/loongarch64-rh-devices.mak +@@ -0,0 +1,155 @@ ++ ++include ../rh-virtio.mak ++# Default configuration for loongarch-softmmu ++ ++CONFIG_PCI=y ++CONFIG_ACPI_PCI=y ++# For now, CONFIG_IDE_CORE requires ISA, so we enable it here ++CONFIG_ISA_BUS=y ++CONFIG_VIRTIO_PCI=y ++ ++CONFIG_VGA_PCI=y ++CONFIG_ACPI_SMBUS=y ++#CONFIG_VHOST_USER_SCSI=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) ++CONFIG_VHOST_USER_SCSI=y ++#CONFIG_VHOST_USER_BLK=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) ++CONFIG_VHOST_USER_BLK=y ++CONFIG_VIRTIO=y ++CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_BLK=y ++CONFIG_VIRTIO_CRYPTO=y ++CONFIG_VIRTIO_GPU=y ++CONFIG_VIRTIO_INPUT=y ++CONFIG_VIRTIO_NET=y ++CONFIG_VIRTIO_RNG=y ++CONFIG_SCSI=y ++CONFIG_VIRTIO_SCSI=y ++CONFIG_VIRTIO_SERIAL=y ++ ++CONFIG_USB_UHCI=y ++CONFIG_USB_OHCI=y ++CONFIG_USB_OHCI_PCI=y ++CONFIG_USB_XHCI=y ++CONFIG_USB_XHCI_NEC=y ++CONFIG_NE2000_PCI=y ++CONFIG_EEPRO100_PCI=y ++CONFIG_PCNET_PCI=y ++CONFIG_PCNET_COMMON=y ++CONFIG_AC97=y ++CONFIG_HDA=y ++CONFIG_ES1370=y ++CONFIG_SCSI=y ++CONFIG_LSI_SCSI_PCI=y ++CONFIG_VMW_PVSCSI_SCSI_PCI=y ++CONFIG_MEGASAS_SCSI_PCI=y ++CONFIG_MPTSAS_SCSI_PCI=y ++CONFIG_RTL8139_PCI=y ++CONFIG_E1000_PCI=y ++CONFIG_IDE_CORE=y ++CONFIG_IDE_QDEV=y ++CONFIG_IDE_PCI=y ++CONFIG_AHCI=y ++CONFIG_AHCI_ICH9=y ++CONFIG_ESP=y ++CONFIG_ESP_PCI=y ++CONFIG_SERIAL=y ++CONFIG_SERIAL_ISA=y ++CONFIG_SERIAL_PCI=y ++CONFIG_CAN_BUS=y ++CONFIG_CAN_SJA1000=y ++CONFIG_CAN_PCI=y ++CONFIG_USB_UHCI=y ++CONFIG_USB_OHCI=y ++CONFIG_USB_XHCI=y ++CONFIG_USB_XHCI_NEC=y ++CONFIG_NE2000_PCI=y ++CONFIG_EEPRO100_PCI=y ++CONFIG_PCNET_PCI=y ++CONFIG_PCNET_COMMON=y ++CONFIG_AC97=y ++CONFIG_HDA=y ++CONFIG_ES1370=y ++CONFIG_SCSI=y ++CONFIG_LSI_SCSI_PCI=y ++CONFIG_VMW_PVSCSI_SCSI_PCI=y ++CONFIG_MEGASAS_SCSI_PCI=y ++CONFIG_MPTSAS_SCSI_PCI=y ++CONFIG_RTL8139_PCI=y ++CONFIG_E1000_PCI=y ++CONFIG_IDE_CORE=y ++CONFIG_IDE_QDEV=y ++CONFIG_IDE_PCI=y ++CONFIG_AHCI=y ++CONFIG_ESP=y ++CONFIG_ESP_PCI=y ++CONFIG_SERIAL=y ++CONFIG_SERIAL_ISA=y ++CONFIG_SERIAL_PCI=y ++CONFIG_CAN_BUS=y ++CONFIG_CAN_SJA1000=y ++CONFIG_CAN_PCI=y ++ ++CONFIG_SPICE=y ++CONFIG_QXL=y ++CONFIG_ESP=y ++CONFIG_SCSI=y ++CONFIG_VGA_ISA=y ++CONFIG_VGA_ISA_MM=y ++CONFIG_VGA_CIRRUS=y ++CONFIG_VMWARE_VGA=y ++CONFIG_VIRTIO_VGA=y ++CONFIG_SERIAL_ISA=y ++CONFIG_PARALLEL=y ++CONFIG_I8254=y ++CONFIG_PCSPK=y ++CONFIG_PCKBD=y ++CONFIG_FDC=y ++CONFIG_ACPI=y ++CONFIG_ACPI_MEMORY_HOTPLUG=y ++CONFIG_ACPI_NVDIMM=y ++CONFIG_ACPI_CPU_HOTPLUG=y ++CONFIG_APM=y ++CONFIG_I8257=y ++CONFIG_PIIX4=y ++CONFIG_IDE_ISA=y ++CONFIG_IDE_PIIX=y ++#CONFIG_NE2000_ISA=y ++CONFIG_MIPSNET=y ++CONFIG_PFLASH_CFI01=y ++CONFIG_I8259=y ++CONFIG_MC146818RTC=y ++CONFIG_ISA_TESTDEV=y ++CONFIG_EMPTY_SLOT=y ++CONFIG_I2C=y ++CONFIG_DIMM=y ++CONFIG_MEM_DEVICE=y ++ ++# Arch Specified CONFIG defines ++CONFIG_IDE_VIA=y ++CONFIG_VT82C686=y ++CONFIG_RC4030=y ++CONFIG_DP8393X=y ++CONFIG_DS1225Y=y ++CONFIG_FITLOADER=y ++CONFIG_SMBIOS=y ++ ++CONFIG_PCIE_PORT=y ++CONFIG_I82801B11=y ++CONFIG_XIO3130=y ++CONFIG_PCI_EXPRESS=y ++CONFIG_MSI_NONBROKEN=y ++CONFIG_IOH3420=y ++CONFIG_SD=y ++CONFIG_SDHCI=y ++CONFIG_VIRTFS=y ++CONFIG_VIRTIO_9P=y ++CONFIG_USB_EHCI=y ++CONFIG_USB_EHCI_PCI=y ++CONFIG_USB_EHCI_SYSBUS=y ++CONFIG_USB_STORAGE_BOT=y ++CONFIG_TPM_EMULATOR=y ++CONFIG_TPM_TIS=y ++CONFIG_PLATFORM_BUS=y ++CONFIG_TPM_TIS_SYSBUS=y ++CONFIG_ACPI_LOONGARCH=y ++CONFIG_LS7A_RTC=y +diff --git a/configure b/configure +index 2576d1c69..a84dc891c 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/pc-bios/meson.build b/pc-bios/meson.build +index 4f3f351f7..f2a1d111a 100644 +--- a/pc-bios/meson.build ++++ b/pc-bios/meson.build +@@ -87,6 +87,7 @@ blobs = files( + 'opensbi-riscv64-generic-fw_dynamic.elf', + 'npcm7xx_bootrom.bin', + 'loongarch_bios.bin', ++ 'loongarch_vars.bin', + ) + + if get_option('install_blobs') +diff --git a/tcg/loongarch64/tcg-insn-defs.c.inc b/tcg/loongarch64/tcg-insn-defs.c.inc +new file mode 100644 +index 000000000..d16257185 +--- /dev/null ++++ b/tcg/loongarch64/tcg-insn-defs.c.inc +@@ -0,0 +1,979 @@ ++/* SPDX-License-Identifier: MIT */ ++/* ++ * LoongArch instruction formats, opcodes, and encoders for TCG use. ++ * ++ * This file is auto-generated by genqemutcgdefs from ++ * https://github.com/loongson-community/loongarch-opcodes, ++ * from commit 961f0c60f5b63e574d785995600c71ad5413fdc4. ++ * DO NOT EDIT. ++ */ ++ ++typedef enum { ++ OPC_CLZ_W = 0x00001400, ++ OPC_CTZ_W = 0x00001c00, ++ OPC_CLZ_D = 0x00002400, ++ OPC_CTZ_D = 0x00002c00, ++ OPC_REVB_2H = 0x00003000, ++ OPC_REVB_2W = 0x00003800, ++ OPC_REVB_D = 0x00003c00, ++ OPC_SEXT_H = 0x00005800, ++ OPC_SEXT_B = 0x00005c00, ++ OPC_ADD_W = 0x00100000, ++ OPC_ADD_D = 0x00108000, ++ OPC_SUB_W = 0x00110000, ++ OPC_SUB_D = 0x00118000, ++ OPC_SLT = 0x00120000, ++ OPC_SLTU = 0x00128000, ++ OPC_MASKEQZ = 0x00130000, ++ OPC_MASKNEZ = 0x00138000, ++ OPC_NOR = 0x00140000, ++ OPC_AND = 0x00148000, ++ OPC_OR = 0x00150000, ++ OPC_XOR = 0x00158000, ++ OPC_ORN = 0x00160000, ++ OPC_ANDN = 0x00168000, ++ OPC_SLL_W = 0x00170000, ++ OPC_SRL_W = 0x00178000, ++ OPC_SRA_W = 0x00180000, ++ OPC_SLL_D = 0x00188000, ++ OPC_SRL_D = 0x00190000, ++ OPC_SRA_D = 0x00198000, ++ OPC_ROTR_W = 0x001b0000, ++ OPC_ROTR_D = 0x001b8000, ++ OPC_MUL_W = 0x001c0000, ++ OPC_MULH_W = 0x001c8000, ++ OPC_MULH_WU = 0x001d0000, ++ OPC_MUL_D = 0x001d8000, ++ OPC_MULH_D = 0x001e0000, ++ OPC_MULH_DU = 0x001e8000, ++ OPC_DIV_W = 0x00200000, ++ OPC_MOD_W = 0x00208000, ++ OPC_DIV_WU = 0x00210000, ++ OPC_MOD_WU = 0x00218000, ++ OPC_DIV_D = 0x00220000, ++ OPC_MOD_D = 0x00228000, ++ OPC_DIV_DU = 0x00230000, ++ OPC_MOD_DU = 0x00238000, ++ OPC_SLLI_W = 0x00408000, ++ OPC_SLLI_D = 0x00410000, ++ OPC_SRLI_W = 0x00448000, ++ OPC_SRLI_D = 0x00450000, ++ OPC_SRAI_W = 0x00488000, ++ OPC_SRAI_D = 0x00490000, ++ OPC_ROTRI_W = 0x004c8000, ++ OPC_ROTRI_D = 0x004d0000, ++ OPC_BSTRINS_W = 0x00600000, ++ OPC_BSTRPICK_W = 0x00608000, ++ OPC_BSTRINS_D = 0x00800000, ++ OPC_BSTRPICK_D = 0x00c00000, ++ OPC_SLTI = 0x02000000, ++ OPC_SLTUI = 0x02400000, ++ OPC_ADDI_W = 0x02800000, ++ OPC_ADDI_D = 0x02c00000, ++ OPC_CU52I_D = 0x03000000, ++ OPC_ANDI = 0x03400000, ++ OPC_ORI = 0x03800000, ++ OPC_XORI = 0x03c00000, ++ OPC_LU12I_W = 0x14000000, ++ OPC_CU32I_D = 0x16000000, ++ OPC_PCADDU2I = 0x18000000, ++ OPC_PCALAU12I = 0x1a000000, ++ OPC_PCADDU12I = 0x1c000000, ++ OPC_PCADDU18I = 0x1e000000, ++ OPC_LD_B = 0x28000000, ++ OPC_LD_H = 0x28400000, ++ OPC_LD_W = 0x28800000, ++ OPC_LD_D = 0x28c00000, ++ OPC_ST_B = 0x29000000, ++ OPC_ST_H = 0x29400000, ++ OPC_ST_W = 0x29800000, ++ OPC_ST_D = 0x29c00000, ++ OPC_LD_BU = 0x2a000000, ++ OPC_LD_HU = 0x2a400000, ++ OPC_LD_WU = 0x2a800000, ++ OPC_LDX_B = 0x38000000, ++ OPC_LDX_H = 0x38040000, ++ OPC_LDX_W = 0x38080000, ++ OPC_LDX_D = 0x380c0000, ++ OPC_STX_B = 0x38100000, ++ OPC_STX_H = 0x38140000, ++ OPC_STX_W = 0x38180000, ++ OPC_STX_D = 0x381c0000, ++ OPC_LDX_BU = 0x38200000, ++ OPC_LDX_HU = 0x38240000, ++ OPC_LDX_WU = 0x38280000, ++ OPC_DBAR = 0x38720000, ++ OPC_JIRL = 0x4c000000, ++ OPC_B = 0x50000000, ++ OPC_BL = 0x54000000, ++ OPC_BEQ = 0x58000000, ++ OPC_BNE = 0x5c000000, ++ OPC_BGT = 0x60000000, ++ OPC_BLE = 0x64000000, ++ OPC_BGTU = 0x68000000, ++ OPC_BLEU = 0x6c000000, ++} LoongArchInsn; ++ ++static int32_t __attribute__((unused)) ++encode_d_slot(LoongArchInsn opc, uint32_t d) ++{ ++ return opc | d; ++} ++ ++static int32_t __attribute__((unused)) ++encode_dj_slots(LoongArchInsn opc, uint32_t d, uint32_t j) ++{ ++ return opc | d | j << 5; ++} ++ ++static int32_t __attribute__((unused)) ++encode_djk_slots(LoongArchInsn opc, uint32_t d, uint32_t j, uint32_t k) ++{ ++ return opc | d | j << 5 | k << 10; ++} ++ ++static int32_t __attribute__((unused)) ++encode_djkm_slots(LoongArchInsn opc, uint32_t d, uint32_t j, uint32_t k, ++ uint32_t m) ++{ ++ return opc | d | j << 5 | k << 10 | m << 16; ++} ++ ++static int32_t __attribute__((unused)) ++encode_dk_slots(LoongArchInsn opc, uint32_t d, uint32_t k) ++{ ++ return opc | d | k << 10; ++} ++ ++static int32_t __attribute__((unused)) ++encode_dj_insn(LoongArchInsn opc, TCGReg d, TCGReg j) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ return encode_dj_slots(opc, d, j); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djk_insn(LoongArchInsn opc, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(k >= 0 && k <= 0x1f); ++ return encode_djk_slots(opc, d, j, k); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djsk12_insn(LoongArchInsn opc, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(sk12 >= -0x800 && sk12 <= 0x7ff); ++ return encode_djk_slots(opc, d, j, sk12 & 0xfff); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djsk16_insn(LoongArchInsn opc, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(sk16 >= -0x8000 && sk16 <= 0x7fff); ++ return encode_djk_slots(opc, d, j, sk16 & 0xffff); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djuk12_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk12) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(uk12 <= 0xfff); ++ return encode_djk_slots(opc, d, j, uk12); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djuk5_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk5) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(uk5 <= 0x1f); ++ return encode_djk_slots(opc, d, j, uk5); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djuk5um5_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk5, ++ uint32_t um5) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(uk5 <= 0x1f); ++ tcg_debug_assert(um5 <= 0x1f); ++ return encode_djkm_slots(opc, d, j, uk5, um5); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djuk6_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk6) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(uk6 <= 0x3f); ++ return encode_djk_slots(opc, d, j, uk6); ++} ++ ++static int32_t __attribute__((unused)) ++encode_djuk6um6_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk6, ++ uint32_t um6) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(j >= 0 && j <= 0x1f); ++ tcg_debug_assert(uk6 <= 0x3f); ++ tcg_debug_assert(um6 <= 0x3f); ++ return encode_djkm_slots(opc, d, j, uk6, um6); ++} ++ ++static int32_t __attribute__((unused)) ++encode_dsj20_insn(LoongArchInsn opc, TCGReg d, int32_t sj20) ++{ ++ tcg_debug_assert(d >= 0 && d <= 0x1f); ++ tcg_debug_assert(sj20 >= -0x80000 && sj20 <= 0x7ffff); ++ return encode_dj_slots(opc, d, sj20 & 0xfffff); ++} ++ ++static int32_t __attribute__((unused)) ++encode_sd10k16_insn(LoongArchInsn opc, int32_t sd10k16) ++{ ++ tcg_debug_assert(sd10k16 >= -0x2000000 && sd10k16 <= 0x1ffffff); ++ return encode_dk_slots(opc, (sd10k16 >> 16) & 0x3ff, sd10k16 & 0xffff); ++} ++ ++static int32_t __attribute__((unused)) ++encode_ud15_insn(LoongArchInsn opc, uint32_t ud15) ++{ ++ tcg_debug_assert(ud15 <= 0x7fff); ++ return encode_d_slot(opc, ud15); ++} ++ ++/* Emits the `clz.w d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_clz_w(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_CLZ_W, d, j)); ++} ++ ++/* Emits the `ctz.w d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ctz_w(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_CTZ_W, d, j)); ++} ++ ++/* Emits the `clz.d d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_clz_d(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_CLZ_D, d, j)); ++} ++ ++/* Emits the `ctz.d d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ctz_d(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_CTZ_D, d, j)); ++} ++ ++/* Emits the `revb.2h d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_revb_2h(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_REVB_2H, d, j)); ++} ++ ++/* Emits the `revb.2w d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_revb_2w(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_REVB_2W, d, j)); ++} ++ ++/* Emits the `revb.d d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_revb_d(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_REVB_D, d, j)); ++} ++ ++/* Emits the `sext.h d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sext_h(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_SEXT_H, d, j)); ++} ++ ++/* Emits the `sext.b d, j` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sext_b(TCGContext *s, TCGReg d, TCGReg j) ++{ ++ tcg_out32(s, encode_dj_insn(OPC_SEXT_B, d, j)); ++} ++ ++/* Emits the `add.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_add_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_ADD_W, d, j, k)); ++} ++ ++/* Emits the `add.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_add_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_ADD_D, d, j, k)); ++} ++ ++/* Emits the `sub.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sub_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SUB_W, d, j, k)); ++} ++ ++/* Emits the `sub.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sub_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SUB_D, d, j, k)); ++} ++ ++/* Emits the `slt d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_slt(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SLT, d, j, k)); ++} ++ ++/* Emits the `sltu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sltu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SLTU, d, j, k)); ++} ++ ++/* Emits the `maskeqz d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_maskeqz(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MASKEQZ, d, j, k)); ++} ++ ++/* Emits the `masknez d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_masknez(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MASKNEZ, d, j, k)); ++} ++ ++/* Emits the `nor d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_nor(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_NOR, d, j, k)); ++} ++ ++/* Emits the `and d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_and(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_AND, d, j, k)); ++} ++ ++/* Emits the `or d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_or(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_OR, d, j, k)); ++} ++ ++/* Emits the `xor d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_xor(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_XOR, d, j, k)); ++} ++ ++/* Emits the `orn d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_orn(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_ORN, d, j, k)); ++} ++ ++/* Emits the `andn d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_andn(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_ANDN, d, j, k)); ++} ++ ++/* Emits the `sll.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sll_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SLL_W, d, j, k)); ++} ++ ++/* Emits the `srl.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_srl_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SRL_W, d, j, k)); ++} ++ ++/* Emits the `sra.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sra_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SRA_W, d, j, k)); ++} ++ ++/* Emits the `sll.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sll_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SLL_D, d, j, k)); ++} ++ ++/* Emits the `srl.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_srl_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SRL_D, d, j, k)); ++} ++ ++/* Emits the `sra.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sra_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_SRA_D, d, j, k)); ++} ++ ++/* Emits the `rotr.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_rotr_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_ROTR_W, d, j, k)); ++} ++ ++/* Emits the `rotr.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_rotr_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_ROTR_D, d, j, k)); ++} ++ ++/* Emits the `mul.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mul_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MUL_W, d, j, k)); ++} ++ ++/* Emits the `mulh.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mulh_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MULH_W, d, j, k)); ++} ++ ++/* Emits the `mulh.wu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mulh_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MULH_WU, d, j, k)); ++} ++ ++/* Emits the `mul.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mul_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MUL_D, d, j, k)); ++} ++ ++/* Emits the `mulh.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mulh_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MULH_D, d, j, k)); ++} ++ ++/* Emits the `mulh.du d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mulh_du(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MULH_DU, d, j, k)); ++} ++ ++/* Emits the `div.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_div_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_DIV_W, d, j, k)); ++} ++ ++/* Emits the `mod.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mod_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MOD_W, d, j, k)); ++} ++ ++/* Emits the `div.wu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_div_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_DIV_WU, d, j, k)); ++} ++ ++/* Emits the `mod.wu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mod_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MOD_WU, d, j, k)); ++} ++ ++/* Emits the `div.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_div_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_DIV_D, d, j, k)); ++} ++ ++/* Emits the `mod.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mod_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MOD_D, d, j, k)); ++} ++ ++/* Emits the `div.du d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_div_du(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_DIV_DU, d, j, k)); ++} ++ ++/* Emits the `mod.du d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_mod_du(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_MOD_DU, d, j, k)); ++} ++ ++/* Emits the `slli.w d, j, uk5` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_slli_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) ++{ ++ tcg_out32(s, encode_djuk5_insn(OPC_SLLI_W, d, j, uk5)); ++} ++ ++/* Emits the `slli.d d, j, uk6` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_slli_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) ++{ ++ tcg_out32(s, encode_djuk6_insn(OPC_SLLI_D, d, j, uk6)); ++} ++ ++/* Emits the `srli.w d, j, uk5` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_srli_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) ++{ ++ tcg_out32(s, encode_djuk5_insn(OPC_SRLI_W, d, j, uk5)); ++} ++ ++/* Emits the `srli.d d, j, uk6` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_srli_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) ++{ ++ tcg_out32(s, encode_djuk6_insn(OPC_SRLI_D, d, j, uk6)); ++} ++ ++/* Emits the `srai.w d, j, uk5` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_srai_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) ++{ ++ tcg_out32(s, encode_djuk5_insn(OPC_SRAI_W, d, j, uk5)); ++} ++ ++/* Emits the `srai.d d, j, uk6` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_srai_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) ++{ ++ tcg_out32(s, encode_djuk6_insn(OPC_SRAI_D, d, j, uk6)); ++} ++ ++/* Emits the `rotri.w d, j, uk5` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_rotri_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) ++{ ++ tcg_out32(s, encode_djuk5_insn(OPC_ROTRI_W, d, j, uk5)); ++} ++ ++/* Emits the `rotri.d d, j, uk6` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_rotri_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) ++{ ++ tcg_out32(s, encode_djuk6_insn(OPC_ROTRI_D, d, j, uk6)); ++} ++ ++/* Emits the `bstrins.w d, j, uk5, um5` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bstrins_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5, ++ uint32_t um5) ++{ ++ tcg_out32(s, encode_djuk5um5_insn(OPC_BSTRINS_W, d, j, uk5, um5)); ++} ++ ++/* Emits the `bstrpick.w d, j, uk5, um5` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bstrpick_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5, ++ uint32_t um5) ++{ ++ tcg_out32(s, encode_djuk5um5_insn(OPC_BSTRPICK_W, d, j, uk5, um5)); ++} ++ ++/* Emits the `bstrins.d d, j, uk6, um6` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bstrins_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6, ++ uint32_t um6) ++{ ++ tcg_out32(s, encode_djuk6um6_insn(OPC_BSTRINS_D, d, j, uk6, um6)); ++} ++ ++/* Emits the `bstrpick.d d, j, uk6, um6` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bstrpick_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6, ++ uint32_t um6) ++{ ++ tcg_out32(s, encode_djuk6um6_insn(OPC_BSTRPICK_D, d, j, uk6, um6)); ++} ++ ++/* Emits the `slti d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_slti(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_SLTI, d, j, sk12)); ++} ++ ++/* Emits the `sltui d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_sltui(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_SLTUI, d, j, sk12)); ++} ++ ++/* Emits the `addi.w d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_addi_w(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_ADDI_W, d, j, sk12)); ++} ++ ++/* Emits the `addi.d d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_addi_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_ADDI_D, d, j, sk12)); ++} ++ ++/* Emits the `cu52i.d d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_cu52i_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_CU52I_D, d, j, sk12)); ++} ++ ++/* Emits the `andi d, j, uk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_andi(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12) ++{ ++ tcg_out32(s, encode_djuk12_insn(OPC_ANDI, d, j, uk12)); ++} ++ ++/* Emits the `ori d, j, uk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ori(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12) ++{ ++ tcg_out32(s, encode_djuk12_insn(OPC_ORI, d, j, uk12)); ++} ++ ++/* Emits the `xori d, j, uk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_xori(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12) ++{ ++ tcg_out32(s, encode_djuk12_insn(OPC_XORI, d, j, uk12)); ++} ++ ++/* Emits the `lu12i.w d, sj20` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_lu12i_w(TCGContext *s, TCGReg d, int32_t sj20) ++{ ++ tcg_out32(s, encode_dsj20_insn(OPC_LU12I_W, d, sj20)); ++} ++ ++/* Emits the `cu32i.d d, sj20` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_cu32i_d(TCGContext *s, TCGReg d, int32_t sj20) ++{ ++ tcg_out32(s, encode_dsj20_insn(OPC_CU32I_D, d, sj20)); ++} ++ ++/* Emits the `pcaddu2i d, sj20` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_pcaddu2i(TCGContext *s, TCGReg d, int32_t sj20) ++{ ++ tcg_out32(s, encode_dsj20_insn(OPC_PCADDU2I, d, sj20)); ++} ++ ++/* Emits the `pcalau12i d, sj20` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_pcalau12i(TCGContext *s, TCGReg d, int32_t sj20) ++{ ++ tcg_out32(s, encode_dsj20_insn(OPC_PCALAU12I, d, sj20)); ++} ++ ++/* Emits the `pcaddu12i d, sj20` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_pcaddu12i(TCGContext *s, TCGReg d, int32_t sj20) ++{ ++ tcg_out32(s, encode_dsj20_insn(OPC_PCADDU12I, d, sj20)); ++} ++ ++/* Emits the `pcaddu18i d, sj20` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_pcaddu18i(TCGContext *s, TCGReg d, int32_t sj20) ++{ ++ tcg_out32(s, encode_dsj20_insn(OPC_PCADDU18I, d, sj20)); ++} ++ ++/* Emits the `ld.b d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_b(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_B, d, j, sk12)); ++} ++ ++/* Emits the `ld.h d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_h(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_H, d, j, sk12)); ++} ++ ++/* Emits the `ld.w d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_w(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_W, d, j, sk12)); ++} ++ ++/* Emits the `ld.d d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_D, d, j, sk12)); ++} ++ ++/* Emits the `st.b d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_st_b(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_ST_B, d, j, sk12)); ++} ++ ++/* Emits the `st.h d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_st_h(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_ST_H, d, j, sk12)); ++} ++ ++/* Emits the `st.w d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_st_w(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_ST_W, d, j, sk12)); ++} ++ ++/* Emits the `st.d d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_st_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_ST_D, d, j, sk12)); ++} ++ ++/* Emits the `ld.bu d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_bu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_BU, d, j, sk12)); ++} ++ ++/* Emits the `ld.hu d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_hu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_HU, d, j, sk12)); ++} ++ ++/* Emits the `ld.wu d, j, sk12` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ld_wu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) ++{ ++ tcg_out32(s, encode_djsk12_insn(OPC_LD_WU, d, j, sk12)); ++} ++ ++/* Emits the `ldx.b d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_b(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_B, d, j, k)); ++} ++ ++/* Emits the `ldx.h d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_h(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_H, d, j, k)); ++} ++ ++/* Emits the `ldx.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_W, d, j, k)); ++} ++ ++/* Emits the `ldx.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_D, d, j, k)); ++} ++ ++/* Emits the `stx.b d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_stx_b(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_STX_B, d, j, k)); ++} ++ ++/* Emits the `stx.h d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_stx_h(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_STX_H, d, j, k)); ++} ++ ++/* Emits the `stx.w d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_stx_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_STX_W, d, j, k)); ++} ++ ++/* Emits the `stx.d d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_stx_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_STX_D, d, j, k)); ++} ++ ++/* Emits the `ldx.bu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_bu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_BU, d, j, k)); ++} ++ ++/* Emits the `ldx.hu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_hu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_HU, d, j, k)); ++} ++ ++/* Emits the `ldx.wu d, j, k` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ldx_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) ++{ ++ tcg_out32(s, encode_djk_insn(OPC_LDX_WU, d, j, k)); ++} ++ ++/* Emits the `dbar ud15` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_dbar(TCGContext *s, uint32_t ud15) ++{ ++ tcg_out32(s, encode_ud15_insn(OPC_DBAR, ud15)); ++} ++ ++/* Emits the `jirl d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_jirl(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_JIRL, d, j, sk16)); ++} ++ ++/* Emits the `b sd10k16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_b(TCGContext *s, int32_t sd10k16) ++{ ++ tcg_out32(s, encode_sd10k16_insn(OPC_B, sd10k16)); ++} ++ ++/* Emits the `bl sd10k16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bl(TCGContext *s, int32_t sd10k16) ++{ ++ tcg_out32(s, encode_sd10k16_insn(OPC_BL, sd10k16)); ++} ++ ++/* Emits the `beq d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_beq(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_BEQ, d, j, sk16)); ++} ++ ++/* Emits the `bne d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bne(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_BNE, d, j, sk16)); ++} ++ ++/* Emits the `bgt d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bgt(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_BGT, d, j, sk16)); ++} ++ ++/* Emits the `ble d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_ble(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_BLE, d, j, sk16)); ++} ++ ++/* Emits the `bgtu d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bgtu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_BGTU, d, j, sk16)); ++} ++ ++/* Emits the `bleu d, j, sk16` instruction. */ ++static void __attribute__((unused)) ++tcg_out_opc_bleu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) ++{ ++ tcg_out32(s, encode_djsk16_insn(OPC_BLEU, d, j, sk16)); ++} ++ ++/* End of generated code. */ +diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h +new file mode 100644 +index 000000000..349c67268 +--- /dev/null ++++ b/tcg/loongarch64/tcg-target-con-set.h +@@ -0,0 +1,31 @@ ++/* SPDX-License-Identifier: MIT */ ++/* ++ * Define LoongArch target-specific constraint sets. ++ * ++ * Copyright (c) 2021 WANG Xuerui ++ * ++ * Based on tcg/riscv/tcg-target-con-set.h ++ * ++ * Copyright (c) 2021 Linaro ++ */ ++ ++/* ++ * C_On_Im(...) defines a constraint set with outputs and inputs. ++ * Each operand should be a sequence of constraint letters as defined by ++ * tcg-target-con-str.h; the constraint combination is inclusive or. ++ */ ++C_O0_I1(r) ++C_O0_I2(rZ, r) ++C_O0_I2(rZ, rZ) ++C_O0_I2(LZ, L) ++C_O1_I1(r, r) ++C_O1_I1(r, L) ++C_O1_I2(r, r, rC) ++C_O1_I2(r, r, ri) ++C_O1_I2(r, r, rI) ++C_O1_I2(r, r, rU) ++C_O1_I2(r, r, rW) ++C_O1_I2(r, r, rZ) ++C_O1_I2(r, 0, rZ) ++C_O1_I2(r, rZ, rN) ++C_O1_I2(r, rZ, rZ) +diff --git a/tcg/loongarch64/tcg-target-con-str.h b/tcg/loongarch64/tcg-target-con-str.h +new file mode 100644 +index 000000000..c3986a4fd +--- /dev/null ++++ b/tcg/loongarch64/tcg-target-con-str.h +@@ -0,0 +1,28 @@ ++/* SPDX-License-Identifier: MIT */ ++/* ++ * Define LoongArch target-specific operand constraints. ++ * ++ * Copyright (c) 2021 WANG Xuerui ++ * ++ * Based on tcg/riscv/tcg-target-con-str.h ++ * ++ * Copyright (c) 2021 Linaro ++ */ ++ ++/* ++ * Define constraint letters for register sets: ++ * REGS(letter, register_mask) ++ */ ++REGS('r', ALL_GENERAL_REGS) ++REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS) ++ ++/* ++ * Define constraint letters for constants: ++ * CONST(letter, TCG_CT_CONST_* bit set) ++ */ ++CONST('I', TCG_CT_CONST_S12) ++CONST('N', TCG_CT_CONST_N12) ++CONST('U', TCG_CT_CONST_U12) ++CONST('Z', TCG_CT_CONST_ZERO) ++CONST('C', TCG_CT_CONST_C12) ++CONST('W', TCG_CT_CONST_WSZ) +diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc +new file mode 100644 +index 000000000..9b53549ed +--- /dev/null ++++ b/tcg/loongarch64/tcg-target.c.inc +@@ -0,0 +1,1744 @@ ++/* ++ * Tiny Code Generator for QEMU ++ * ++ * Copyright (c) 2021 WANG Xuerui ++ * ++ * Based on tcg/riscv/tcg-target.c.inc ++ * ++ * Copyright (c) 2018 SiFive, Inc ++ * Copyright (c) 2008-2009 Arnaud Patard ++ * Copyright (c) 2009 Aurelien Jarno ++ * Copyright (c) 2008 Fabrice Bellard ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ ++#include "../tcg-ldst.c.inc" ++ ++#ifdef CONFIG_DEBUG_TCG ++static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { ++ "zero", ++ "ra", ++ "tp", ++ "sp", ++ "a0", ++ "a1", ++ "a2", ++ "a3", ++ "a4", ++ "a5", ++ "a6", ++ "a7", ++ "t0", ++ "t1", ++ "t2", ++ "t3", ++ "t4", ++ "t5", ++ "t6", ++ "t7", ++ "t8", ++ "r21", /* reserved in the LP64* ABI, hence no ABI name */ ++ "s9", ++ "s0", ++ "s1", ++ "s2", ++ "s3", ++ "s4", ++ "s5", ++ "s6", ++ "s7", ++ "s8" ++}; ++#endif ++ ++static const int tcg_target_reg_alloc_order[] = { ++ /* Registers preserved across calls */ ++ /* TCG_REG_S0 reserved for TCG_AREG0 */ ++ TCG_REG_S1, ++ TCG_REG_S2, ++ TCG_REG_S3, ++ TCG_REG_S4, ++ TCG_REG_S5, ++ TCG_REG_S6, ++ TCG_REG_S7, ++ TCG_REG_S8, ++ TCG_REG_S9, ++ ++ /* Registers (potentially) clobbered across calls */ ++ TCG_REG_T0, ++ TCG_REG_T1, ++ TCG_REG_T2, ++ TCG_REG_T3, ++ TCG_REG_T4, ++ TCG_REG_T5, ++ TCG_REG_T6, ++ TCG_REG_T7, ++ TCG_REG_T8, ++ ++ /* Argument registers, opposite order of allocation. */ ++ TCG_REG_A7, ++ TCG_REG_A6, ++ TCG_REG_A5, ++ TCG_REG_A4, ++ TCG_REG_A3, ++ TCG_REG_A2, ++ TCG_REG_A1, ++ TCG_REG_A0, ++}; ++ ++static const int tcg_target_call_iarg_regs[] = { ++ TCG_REG_A0, ++ TCG_REG_A1, ++ TCG_REG_A2, ++ TCG_REG_A3, ++ TCG_REG_A4, ++ TCG_REG_A5, ++ TCG_REG_A6, ++ TCG_REG_A7, ++}; ++ ++static const int tcg_target_call_oarg_regs[] = { ++ TCG_REG_A0, ++ TCG_REG_A1, ++}; ++ ++#ifndef CONFIG_SOFTMMU ++#define USE_GUEST_BASE (guest_base != 0) ++#define TCG_GUEST_BASE_REG TCG_REG_S1 ++#endif ++ ++#define TCG_CT_CONST_ZERO 0x100 ++#define TCG_CT_CONST_S12 0x200 ++#define TCG_CT_CONST_N12 0x400 ++#define TCG_CT_CONST_U12 0x800 ++#define TCG_CT_CONST_C12 0x1000 ++#define TCG_CT_CONST_WSZ 0x2000 ++ ++#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32) ++/* ++ * For softmmu, we need to avoid conflicts with the first 5 ++ * argument registers to call the helper. Some of these are ++ * also used for the tlb lookup. ++ */ ++#ifdef CONFIG_SOFTMMU ++#define SOFTMMU_RESERVE_REGS MAKE_64BIT_MASK(TCG_REG_A0, 5) ++#else ++#define SOFTMMU_RESERVE_REGS 0 ++#endif ++ ++ ++static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len) ++{ ++ return sextract64(val, pos, len); ++} ++ ++/* test if a constant matches the constraint */ ++static bool tcg_target_const_match(int64_t val, TCGType type, int ct) ++{ ++ if (ct & TCG_CT_CONST) { ++ return true; ++ } ++ if ((ct & TCG_CT_CONST_ZERO) && val == 0) { ++ return true; ++ } ++ if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) { ++ return true; ++ } ++ if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) { ++ return true; ++ } ++ if ((ct & TCG_CT_CONST_U12) && val >= 0 && val <= 0xfff) { ++ return true; ++ } ++ if ((ct & TCG_CT_CONST_C12) && ~val >= 0 && ~val <= 0xfff) { ++ return true; ++ } ++ if ((ct & TCG_CT_CONST_WSZ) && val == (type == TCG_TYPE_I32 ? 32 : 64)) { ++ return true; ++ } ++ return false; ++} ++ ++/* ++ * Relocations ++ */ ++ ++/* ++ * Relocation records defined in LoongArch ELF psABI v1.00 is way too ++ * complicated; a whopping stack machine is needed to stuff the fields, at ++ * the very least one SOP_PUSH and one SOP_POP (of the correct format) are ++ * needed. ++ * ++ * Hence, define our own simpler relocation types. Numbers are chosen as to ++ * not collide with potential future additions to the true ELF relocation ++ * type enum. ++ */ ++ ++/* Field Sk16, shifted right by 2; suitable for conditional jumps */ ++#define R_LOONGARCH_BR_SK16 256 ++/* Field Sd10k16, shifted right by 2; suitable for B and BL */ ++#define R_LOONGARCH_BR_SD10K16 257 ++ ++static bool reloc_br_sk16(tcg_insn_unit *src_rw, const tcg_insn_unit *target) ++{ ++ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); ++ intptr_t offset = (intptr_t)target - (intptr_t)src_rx; ++ ++ tcg_debug_assert((offset & 3) == 0); ++ offset >>= 2; ++ if (offset == sextreg(offset, 0, 16)) { ++ *src_rw = deposit64(*src_rw, 10, 16, offset); ++ return true; ++ } ++ ++ return false; ++} ++ ++static bool reloc_br_sd10k16(tcg_insn_unit *src_rw, ++ const tcg_insn_unit *target) ++{ ++ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); ++ intptr_t offset = (intptr_t)target - (intptr_t)src_rx; ++ ++ tcg_debug_assert((offset & 3) == 0); ++ offset >>= 2; ++ if (offset == sextreg(offset, 0, 26)) { ++ *src_rw = deposit64(*src_rw, 0, 10, offset >> 16); /* slot d10 */ ++ *src_rw = deposit64(*src_rw, 10, 16, offset); /* slot k16 */ ++ return true; ++ } ++ ++ return false; ++} ++ ++static bool patch_reloc(tcg_insn_unit *code_ptr, int type, ++ intptr_t value, intptr_t addend) ++{ ++ tcg_debug_assert(addend == 0); ++ switch (type) { ++ case R_LOONGARCH_BR_SK16: ++ return reloc_br_sk16(code_ptr, (tcg_insn_unit *)value); ++ case R_LOONGARCH_BR_SD10K16: ++ return reloc_br_sd10k16(code_ptr, (tcg_insn_unit *)value); ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++#include "tcg-insn-defs.c.inc" ++ ++/* ++ * TCG intrinsics ++ */ ++ ++static void tcg_out_mb(TCGContext *s, TCGArg a0) ++{ ++ /* Baseline LoongArch only has the full barrier, unfortunately. */ ++ tcg_out_opc_dbar(s, 0); ++} ++ ++static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) ++{ ++ if (ret == arg) { ++ return true; ++ } ++ switch (type) { ++ case TCG_TYPE_I32: ++ case TCG_TYPE_I64: ++ /* ++ * Conventional register-register move used in LoongArch is ++ * `or dst, src, zero`. ++ */ ++ tcg_out_opc_or(s, ret, arg, TCG_REG_ZERO); ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++ return true; ++} ++ ++static bool imm_part_needs_loading(bool high_bits_are_ones, ++ tcg_target_long part) ++{ ++ if (high_bits_are_ones) { ++ return part != -1; ++ } else { ++ return part != 0; ++ } ++} ++ ++/* Loads a 32-bit immediate into rd, sign-extended. */ ++static void tcg_out_movi_i32(TCGContext *s, TCGReg rd, int32_t val) ++{ ++ tcg_target_long lo = sextreg(val, 0, 12); ++ tcg_target_long hi12 = sextreg(val, 12, 20); ++ ++ /* Single-instruction cases. */ ++ if (lo == val) { ++ /* val fits in simm12: addi.w rd, zero, val */ ++ tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val); ++ return; ++ } ++ if (0x800 <= val && val <= 0xfff) { ++ /* val fits in uimm12: ori rd, zero, val */ ++ tcg_out_opc_ori(s, rd, TCG_REG_ZERO, val); ++ return; ++ } ++ ++ /* High bits must be set; load with lu12i.w + optional ori. */ ++ tcg_out_opc_lu12i_w(s, rd, hi12); ++ if (lo != 0) { ++ tcg_out_opc_ori(s, rd, rd, lo & 0xfff); ++ } ++} ++ ++static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, ++ tcg_target_long val) ++{ ++ /* ++ * LoongArch conventionally loads 64-bit immediates in at most 4 steps, ++ * with dedicated instructions for filling the respective bitfields ++ * below: ++ * ++ * 6 5 4 3 ++ * 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 ++ * +-----------------------+---------------------------------------+... ++ * | hi52 | hi32 | ++ * +-----------------------+---------------------------------------+... ++ * 3 2 1 ++ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ++ * ...+-------------------------------------+-------------------------+ ++ * | hi12 | lo | ++ * ...+-------------------------------------+-------------------------+ ++ * ++ * Check if val belong to one of the several fast cases, before falling ++ * back to the slow path. ++ */ ++ ++ intptr_t pc_offset; ++ tcg_target_long val_lo, val_hi, pc_hi, offset_hi; ++ tcg_target_long hi32, hi52; ++ bool rd_high_bits_are_ones; ++ ++ /* Value fits in signed i32. */ ++ if (type == TCG_TYPE_I32 || val == (int32_t)val) { ++ tcg_out_movi_i32(s, rd, val); ++ return; ++ } ++ ++ /* PC-relative cases. */ ++ pc_offset = tcg_pcrel_diff(s, (void *)val); ++ if (pc_offset == sextreg(pc_offset, 0, 22) && (pc_offset & 3) == 0) { ++ /* Single pcaddu2i. */ ++ tcg_out_opc_pcaddu2i(s, rd, pc_offset >> 2); ++ return; ++ } ++ ++ if (pc_offset == (int32_t)pc_offset) { ++ /* Offset within 32 bits; load with pcalau12i + ori. */ ++ val_lo = sextreg(val, 0, 12); ++ val_hi = val >> 12; ++ pc_hi = (val - pc_offset) >> 12; ++ offset_hi = val_hi - pc_hi; ++ ++ tcg_debug_assert(offset_hi == sextreg(offset_hi, 0, 20)); ++ tcg_out_opc_pcalau12i(s, rd, offset_hi); ++ if (val_lo != 0) { ++ tcg_out_opc_ori(s, rd, rd, val_lo & 0xfff); ++ } ++ return; ++ } ++ ++ hi32 = sextreg(val, 32, 20); ++ hi52 = sextreg(val, 52, 12); ++ ++ /* Single cu52i.d case. */ ++ if (ctz64(val) >= 52) { ++ tcg_out_opc_cu52i_d(s, rd, TCG_REG_ZERO, hi52); ++ return; ++ } ++ ++ /* Slow path. Initialize the low 32 bits, then concat high bits. */ ++ tcg_out_movi_i32(s, rd, val); ++ rd_high_bits_are_ones = (int32_t)val < 0; ++ ++ if (imm_part_needs_loading(rd_high_bits_are_ones, hi32)) { ++ tcg_out_opc_cu32i_d(s, rd, hi32); ++ rd_high_bits_are_ones = hi32 < 0; ++ } ++ ++ if (imm_part_needs_loading(rd_high_bits_are_ones, hi52)) { ++ tcg_out_opc_cu52i_d(s, rd, rd, hi52); ++ } ++} ++ ++static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg) ++{ ++ tcg_out_opc_andi(s, ret, arg, 0xff); ++} ++ ++static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg) ++{ ++ tcg_out_opc_bstrpick_w(s, ret, arg, 0, 15); ++} ++ ++static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg) ++{ ++ tcg_out_opc_bstrpick_d(s, ret, arg, 0, 31); ++} ++ ++static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg) ++{ ++ tcg_out_opc_sext_b(s, ret, arg); ++} ++ ++static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg) ++{ ++ tcg_out_opc_sext_h(s, ret, arg); ++} ++ ++static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg) ++{ ++ tcg_out_opc_addi_w(s, ret, arg, 0); ++} ++ ++static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc, ++ TCGReg a0, TCGReg a1, TCGReg a2, ++ bool c2, bool is_32bit) ++{ ++ if (c2) { ++ /* ++ * Fast path: semantics already satisfied due to constraint and ++ * insn behavior, single instruction is enough. ++ */ ++ tcg_debug_assert(a2 == (is_32bit ? 32 : 64)); ++ /* all clz/ctz insns belong to DJ-format */ ++ tcg_out32(s, encode_dj_insn(opc, a0, a1)); ++ return; ++ } ++ ++ tcg_out32(s, encode_dj_insn(opc, TCG_REG_TMP0, a1)); ++ /* a0 = a1 ? REG_TMP0 : a2 */ ++ tcg_out_opc_maskeqz(s, TCG_REG_TMP0, TCG_REG_TMP0, a1); ++ tcg_out_opc_masknez(s, a0, a2, a1); ++ tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0); ++} ++ ++static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, ++ TCGReg arg1, TCGReg arg2, bool c2) ++{ ++ TCGReg tmp; ++ ++ if (c2) { ++ tcg_debug_assert(arg2 == 0); ++ } ++ ++ switch (cond) { ++ case TCG_COND_EQ: ++ if (c2) { ++ tmp = arg1; ++ } else { ++ tcg_out_opc_sub_d(s, ret, arg1, arg2); ++ tmp = ret; ++ } ++ tcg_out_opc_sltui(s, ret, tmp, 1); ++ break; ++ case TCG_COND_NE: ++ if (c2) { ++ tmp = arg1; ++ } else { ++ tcg_out_opc_sub_d(s, ret, arg1, arg2); ++ tmp = ret; ++ } ++ tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp); ++ break; ++ case TCG_COND_LT: ++ tcg_out_opc_slt(s, ret, arg1, arg2); ++ break; ++ case TCG_COND_GE: ++ tcg_out_opc_slt(s, ret, arg1, arg2); ++ tcg_out_opc_xori(s, ret, ret, 1); ++ break; ++ case TCG_COND_LE: ++ tcg_out_setcond(s, TCG_COND_GE, ret, arg2, arg1, false); ++ break; ++ case TCG_COND_GT: ++ tcg_out_setcond(s, TCG_COND_LT, ret, arg2, arg1, false); ++ break; ++ case TCG_COND_LTU: ++ tcg_out_opc_sltu(s, ret, arg1, arg2); ++ break; ++ case TCG_COND_GEU: ++ tcg_out_opc_sltu(s, ret, arg1, arg2); ++ tcg_out_opc_xori(s, ret, ret, 1); ++ break; ++ case TCG_COND_LEU: ++ tcg_out_setcond(s, TCG_COND_GEU, ret, arg2, arg1, false); ++ break; ++ case TCG_COND_GTU: ++ tcg_out_setcond(s, TCG_COND_LTU, ret, arg2, arg1, false); ++ break; ++ default: ++ g_assert_not_reached(); ++ break; ++ } ++} ++ ++/* ++ * Branch helpers ++ */ ++ ++static const struct { ++ LoongArchInsn op; ++ bool swap; ++} tcg_brcond_to_loongarch[] = { ++ [TCG_COND_EQ] = { OPC_BEQ, false }, ++ [TCG_COND_NE] = { OPC_BNE, false }, ++ [TCG_COND_LT] = { OPC_BGT, true }, ++ [TCG_COND_GE] = { OPC_BLE, true }, ++ [TCG_COND_LE] = { OPC_BLE, false }, ++ [TCG_COND_GT] = { OPC_BGT, false }, ++ [TCG_COND_LTU] = { OPC_BGTU, true }, ++ [TCG_COND_GEU] = { OPC_BLEU, true }, ++ [TCG_COND_LEU] = { OPC_BLEU, false }, ++ [TCG_COND_GTU] = { OPC_BGTU, false } ++}; ++ ++static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1, ++ TCGReg arg2, TCGLabel *l) ++{ ++ LoongArchInsn op = tcg_brcond_to_loongarch[cond].op; ++ ++ tcg_debug_assert(op != 0); ++ ++ if (tcg_brcond_to_loongarch[cond].swap) { ++ TCGReg t = arg1; ++ arg1 = arg2; ++ arg2 = t; ++ } ++ ++ /* all conditional branch insns belong to DJSk16-format */ ++ tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SK16, l, 0); ++ tcg_out32(s, encode_djsk16_insn(op, arg1, arg2, 0)); ++} ++ ++static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail) ++{ ++ TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA; ++ ptrdiff_t offset = tcg_pcrel_diff(s, arg); ++ ++ tcg_debug_assert((offset & 3) == 0); ++ if (offset == sextreg(offset, 0, 28)) { ++ /* short jump: +/- 256MiB */ ++ if (tail) { ++ tcg_out_opc_b(s, offset >> 2); ++ } else { ++ tcg_out_opc_bl(s, offset >> 2); ++ } ++ } else if (offset == sextreg(offset, 0, 38)) { ++ /* long jump: +/- 256GiB */ ++ tcg_target_long lo = sextreg(offset, 0, 18); ++ tcg_target_long hi = offset - lo; ++ tcg_out_opc_pcaddu18i(s, TCG_REG_TMP0, hi >> 18); ++ tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2); ++ } else { ++ /* far jump: 64-bit */ ++ tcg_target_long lo = sextreg((tcg_target_long)arg, 0, 18); ++ tcg_target_long hi = (tcg_target_long)arg - lo; ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, hi); ++ tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2); ++ } ++} ++ ++static void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg) ++{ ++ tcg_out_call_int(s, arg, false); ++} ++ ++/* ++ * Load/store helpers ++ */ ++ ++static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, TCGReg data, ++ TCGReg addr, intptr_t offset) ++{ ++ intptr_t imm12 = sextreg(offset, 0, 12); ++ ++ if (offset != imm12) { ++ intptr_t diff = offset - (uintptr_t)s->code_ptr; ++ ++ if (addr == TCG_REG_ZERO && diff == (int32_t)diff) { ++ imm12 = sextreg(diff, 0, 12); ++ tcg_out_opc_pcaddu12i(s, TCG_REG_TMP2, (diff - imm12) >> 12); ++ } else { ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP2, offset - imm12); ++ if (addr != TCG_REG_ZERO) { ++ tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, addr); ++ } ++ } ++ addr = TCG_REG_TMP2; ++ } ++ ++ switch (opc) { ++ case OPC_LD_B: ++ case OPC_LD_BU: ++ case OPC_LD_H: ++ case OPC_LD_HU: ++ case OPC_LD_W: ++ case OPC_LD_WU: ++ case OPC_LD_D: ++ case OPC_ST_B: ++ case OPC_ST_H: ++ case OPC_ST_W: ++ case OPC_ST_D: ++ tcg_out32(s, encode_djsk12_insn(opc, data, addr, imm12)); ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, ++ TCGReg arg1, intptr_t arg2) ++{ ++ bool is_32bit = type == TCG_TYPE_I32; ++ tcg_out_ldst(s, is_32bit ? OPC_LD_W : OPC_LD_D, arg, arg1, arg2); ++} ++ ++static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, ++ TCGReg arg1, intptr_t arg2) ++{ ++ bool is_32bit = type == TCG_TYPE_I32; ++ tcg_out_ldst(s, is_32bit ? OPC_ST_W : OPC_ST_D, arg, arg1, arg2); ++} ++ ++static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, ++ TCGReg base, intptr_t ofs) ++{ ++ if (val == 0) { ++ tcg_out_st(s, type, TCG_REG_ZERO, base, ofs); ++ return true; ++ } ++ return false; ++} ++ ++/* ++ * Load/store helpers for SoftMMU, and qemu_ld/st implementations ++ */ ++ ++#if defined(CONFIG_SOFTMMU) ++/* ++ * helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr, ++ * MemOpIdx oi, uintptr_t ra) ++ */ ++static void * const qemu_ld_helpers[4] = { ++ [MO_8] = helper_ret_ldub_mmu, ++ [MO_16] = helper_le_lduw_mmu, ++ [MO_32] = helper_le_ldul_mmu, ++ [MO_64] = helper_le_ldq_mmu, ++}; ++ ++/* ++ * helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr, ++ * uintxx_t val, MemOpIdx oi, ++ * uintptr_t ra) ++ */ ++static void * const qemu_st_helpers[4] = { ++ [MO_8] = helper_ret_stb_mmu, ++ [MO_16] = helper_le_stw_mmu, ++ [MO_32] = helper_le_stl_mmu, ++ [MO_64] = helper_le_stq_mmu, ++}; ++ ++/* We expect to use a 12-bit negative offset from ENV. */ ++QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0); ++QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11)); ++ ++static bool tcg_out_goto(TCGContext *s, const tcg_insn_unit *target) ++{ ++ tcg_out_opc_b(s, 0); ++ return reloc_br_sd10k16(s->code_ptr - 1, target); ++} ++ ++/* ++ * Emits common code for TLB addend lookup, that eventually loads the ++ * addend in TCG_REG_TMP2. ++ */ ++static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl, MemOpIdx oi, ++ tcg_insn_unit **label_ptr, bool is_load) ++{ ++ MemOp opc = get_memop(oi); ++ unsigned s_bits = opc & MO_SIZE; ++ unsigned a_bits = get_alignment_bits(opc); ++ tcg_target_long compare_mask; ++ int mem_index = get_mmuidx(oi); ++ int fast_ofs = TLB_MASK_TABLE_OFS(mem_index); ++ int mask_ofs = fast_ofs + offsetof(CPUTLBDescFast, mask); ++ int table_ofs = fast_ofs + offsetof(CPUTLBDescFast, table); ++ ++ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs); ++ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs); ++ ++ tcg_out_opc_srli_d(s, TCG_REG_TMP2, addrl, ++ TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); ++ tcg_out_opc_and(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP0); ++ tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP1); ++ ++ /* Load the tlb comparator and the addend. */ ++ tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP0, TCG_REG_TMP2, ++ is_load ? offsetof(CPUTLBEntry, addr_read) ++ : offsetof(CPUTLBEntry, addr_write)); ++ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_REG_TMP2, ++ offsetof(CPUTLBEntry, addend)); ++ ++ /* We don't support unaligned accesses. */ ++ if (a_bits < s_bits) { ++ a_bits = s_bits; ++ } ++ /* Clear the non-page, non-alignment bits from the address. */ ++ compare_mask = (tcg_target_long)TARGET_PAGE_MASK | ((1 << a_bits) - 1); ++ tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_TMP1, compare_mask); ++ tcg_out_opc_and(s, TCG_REG_TMP1, TCG_REG_TMP1, addrl); ++ ++ /* Compare masked address with the TLB entry. */ ++ label_ptr[0] = s->code_ptr; ++ tcg_out_opc_bne(s, TCG_REG_TMP0, TCG_REG_TMP1, 0); ++ ++ /* TLB Hit - addend in TCG_REG_TMP2, ready for use. */ ++} ++ ++static void add_qemu_ldst_label(TCGContext *s, int is_ld, MemOpIdx oi, ++ TCGType type, ++ TCGReg datalo, TCGReg addrlo, ++ void *raddr, tcg_insn_unit **label_ptr) ++{ ++ TCGLabelQemuLdst *label = new_ldst_label(s); ++ ++ label->is_ld = is_ld; ++ label->oi = oi; ++ label->type = type; ++ label->datalo_reg = datalo; ++ label->datahi_reg = 0; /* unused */ ++ label->addrlo_reg = addrlo; ++ label->addrhi_reg = 0; /* unused */ ++ label->raddr = tcg_splitwx_to_rx(raddr); ++ label->label_ptr[0] = label_ptr[0]; ++} ++ ++static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) ++{ ++ MemOpIdx oi = l->oi; ++ MemOp opc = get_memop(oi); ++ MemOp size = opc & MO_SIZE; ++ TCGType type = l->type; ++ ++ /* resolve label address */ ++ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { ++ return false; ++ } ++ ++ /* call load helper */ ++ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); ++ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A1, l->addrlo_reg); ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A2, oi); ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A3, (tcg_target_long)l->raddr); ++ ++ tcg_out_call(s, qemu_ld_helpers[size]); ++ ++ switch (opc & MO_SSIZE) { ++ case MO_SB: ++ tcg_out_ext8s(s, l->datalo_reg, TCG_REG_A0); ++ break; ++ case MO_SW: ++ tcg_out_ext16s(s, l->datalo_reg, TCG_REG_A0); ++ break; ++ case MO_SL: ++ tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0); ++ break; ++ case MO_UL: ++ if (type == TCG_TYPE_I32) { ++ /* MO_UL loads of i32 should be sign-extended too */ ++ tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0); ++ break; ++ } ++ /* fallthrough */ ++ default: ++ tcg_out_mov(s, type, l->datalo_reg, TCG_REG_A0); ++ break; ++ } ++ ++ return tcg_out_goto(s, l->raddr); ++} ++ ++static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) ++{ ++ MemOpIdx oi = l->oi; ++ MemOp opc = get_memop(oi); ++ MemOp size = opc & MO_SIZE; ++ ++ /* resolve label address */ ++ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { ++ return false; ++ } ++ ++ /* call store helper */ ++ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); ++ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A1, l->addrlo_reg); ++ switch (size) { ++ case MO_8: ++ tcg_out_ext8u(s, TCG_REG_A2, l->datalo_reg); ++ break; ++ case MO_16: ++ tcg_out_ext16u(s, TCG_REG_A2, l->datalo_reg); ++ break; ++ case MO_32: ++ tcg_out_ext32u(s, TCG_REG_A2, l->datalo_reg); ++ break; ++ case MO_64: ++ tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_A2, l->datalo_reg); ++ break; ++ default: ++ g_assert_not_reached(); ++ break; ++ } ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A3, oi); ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A4, (tcg_target_long)l->raddr); ++ ++ tcg_out_call(s, qemu_st_helpers[size]); ++ ++ return tcg_out_goto(s, l->raddr); ++} ++#else ++ ++/* ++ * Alignment helpers for user-mode emulation ++ */ ++ ++static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addr_reg, ++ unsigned a_bits) ++{ ++ TCGLabelQemuLdst *l = new_ldst_label(s); ++ ++ l->is_ld = is_ld; ++ l->addrlo_reg = addr_reg; ++ ++ /* ++ * Without micro-architecture details, we don't know which of bstrpick or ++ * andi is faster, so use bstrpick as it's not constrained by imm field ++ * width. (Not to say alignments >= 2^12 are going to happen any time ++ * soon, though) ++ */ ++ tcg_out_opc_bstrpick_d(s, TCG_REG_TMP1, addr_reg, 0, a_bits - 1); ++ ++ l->label_ptr[0] = s->code_ptr; ++ tcg_out_opc_bne(s, TCG_REG_TMP1, TCG_REG_ZERO, 0); ++ ++ l->raddr = tcg_splitwx_to_rx(s->code_ptr); ++} ++ ++static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l) ++{ ++ /* resolve label address */ ++ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { ++ return false; ++ } ++ ++ tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_A1, l->addrlo_reg); ++ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); ++ ++ /* tail call, with the return address back inline. */ ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (uintptr_t)l->raddr); ++ tcg_out_call_int(s, (const void *)(l->is_ld ? helper_unaligned_ld ++ : helper_unaligned_st), true); ++ return true; ++} ++ ++static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) ++{ ++ return tcg_out_fail_alignment(s, l); ++} ++ ++static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) ++{ ++ return tcg_out_fail_alignment(s, l); ++} ++ ++#endif /* CONFIG_SOFTMMU */ ++ ++/* ++ * `ext32u` the address register into the temp register given, ++ * if target is 32-bit, no-op otherwise. ++ * ++ * Returns the address register ready for use with TLB addend. ++ */ ++static TCGReg tcg_out_zext_addr_if_32_bit(TCGContext *s, ++ TCGReg addr, TCGReg tmp) ++{ ++ if (TARGET_LONG_BITS == 32) { ++ tcg_out_ext32u(s, tmp, addr); ++ return tmp; ++ } ++ return addr; ++} ++ ++static void tcg_out_qemu_ld_indexed(TCGContext *s, TCGReg rd, TCGReg rj, ++ TCGReg rk, MemOp opc, TCGType type) ++{ ++ /* Byte swapping is left to middle-end expansion. */ ++ tcg_debug_assert((opc & MO_BSWAP) == 0); ++ ++ switch (opc & MO_SSIZE) { ++ case MO_UB: ++ tcg_out_opc_ldx_bu(s, rd, rj, rk); ++ break; ++ case MO_SB: ++ tcg_out_opc_ldx_b(s, rd, rj, rk); ++ break; ++ case MO_UW: ++ tcg_out_opc_ldx_hu(s, rd, rj, rk); ++ break; ++ case MO_SW: ++ tcg_out_opc_ldx_h(s, rd, rj, rk); ++ break; ++ case MO_UL: ++ if (type == TCG_TYPE_I64) { ++ tcg_out_opc_ldx_wu(s, rd, rj, rk); ++ break; ++ } ++ /* fallthrough */ ++ case MO_SL: ++ tcg_out_opc_ldx_w(s, rd, rj, rk); ++ break; ++ case MO_Q: ++ tcg_out_opc_ldx_d(s, rd, rj, rk); ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGType type) ++{ ++ TCGReg addr_regl; ++ TCGReg data_regl; ++ MemOpIdx oi; ++ MemOp opc; ++#if defined(CONFIG_SOFTMMU) ++ tcg_insn_unit *label_ptr[1]; ++#else ++ unsigned a_bits; ++#endif ++ TCGReg base; ++ ++ data_regl = *args++; ++ addr_regl = *args++; ++ oi = *args++; ++ opc = get_memop(oi); ++ ++#if defined(CONFIG_SOFTMMU) ++ tcg_out_tlb_load(s, addr_regl, oi, label_ptr, 1); ++ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); ++ tcg_out_qemu_ld_indexed(s, data_regl, base, TCG_REG_TMP2, opc, type); ++ add_qemu_ldst_label(s, 1, oi, type, ++ data_regl, addr_regl, ++ s->code_ptr, label_ptr); ++#else ++ a_bits = get_alignment_bits(opc); ++ if (a_bits) { ++ tcg_out_test_alignment(s, true, addr_regl, a_bits); ++ } ++ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); ++ TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO; ++ tcg_out_qemu_ld_indexed(s, data_regl, base, guest_base_reg, opc, type); ++#endif ++} ++ ++static void tcg_out_qemu_st_indexed(TCGContext *s, TCGReg data, ++ TCGReg rj, TCGReg rk, MemOp opc) ++{ ++ /* Byte swapping is left to middle-end expansion. */ ++ tcg_debug_assert((opc & MO_BSWAP) == 0); ++ ++ switch (opc & MO_SIZE) { ++ case MO_8: ++ tcg_out_opc_stx_b(s, data, rj, rk); ++ break; ++ case MO_16: ++ tcg_out_opc_stx_h(s, data, rj, rk); ++ break; ++ case MO_32: ++ tcg_out_opc_stx_w(s, data, rj, rk); ++ break; ++ case MO_64: ++ tcg_out_opc_stx_d(s, data, rj, rk); ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args) ++{ ++ TCGReg addr_regl; ++ TCGReg data_regl; ++ MemOpIdx oi; ++ MemOp opc; ++#if defined(CONFIG_SOFTMMU) ++ tcg_insn_unit *label_ptr[1]; ++#else ++ unsigned a_bits; ++#endif ++ TCGReg base; ++ ++ data_regl = *args++; ++ addr_regl = *args++; ++ oi = *args++; ++ opc = get_memop(oi); ++ ++#if defined(CONFIG_SOFTMMU) ++ tcg_out_tlb_load(s, addr_regl, oi, label_ptr, 0); ++ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); ++ tcg_out_qemu_st_indexed(s, data_regl, base, TCG_REG_TMP2, opc); ++ add_qemu_ldst_label(s, 0, oi, ++ 0, /* type param is unused for stores */ ++ data_regl, addr_regl, ++ s->code_ptr, label_ptr); ++#else ++ a_bits = get_alignment_bits(opc); ++ if (a_bits) { ++ tcg_out_test_alignment(s, false, addr_regl, a_bits); ++ } ++ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); ++ TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO; ++ tcg_out_qemu_st_indexed(s, data_regl, base, guest_base_reg, opc); ++#endif ++} ++ ++/* ++ * Entry-points ++ */ ++ ++static const tcg_insn_unit *tb_ret_addr; ++ ++static void tcg_out_op(TCGContext *s, TCGOpcode opc, ++ const TCGArg args[TCG_MAX_OP_ARGS], ++ const int const_args[TCG_MAX_OP_ARGS]) ++{ ++ TCGArg a0 = args[0]; ++ TCGArg a1 = args[1]; ++ TCGArg a2 = args[2]; ++ int c2 = const_args[2]; ++ ++ switch (opc) { ++ case INDEX_op_exit_tb: ++ /* Reuse the zeroing that exists for goto_ptr. */ ++ if (a0 == 0) { ++ tcg_out_call_int(s, tcg_code_gen_epilogue, true); ++ } else { ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, a0); ++ tcg_out_call_int(s, tb_ret_addr, true); ++ } ++ break; ++ ++ case INDEX_op_goto_tb: ++ assert(s->tb_jmp_insn_offset == 0); ++ /* indirect jump method */ ++ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO, ++ (uintptr_t)(s->tb_jmp_target_addr + a0)); ++ tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_TMP0, 0); ++ set_jmp_reset_offset(s, a0); ++ break; ++ ++ case INDEX_op_mb: ++ tcg_out_mb(s, a0); ++ break; ++ ++ case INDEX_op_goto_ptr: ++ tcg_out_opc_jirl(s, TCG_REG_ZERO, a0, 0); ++ break; ++ ++ case INDEX_op_br: ++ tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SD10K16, arg_label(a0), ++ 0); ++ tcg_out_opc_b(s, 0); ++ break; ++ ++ case INDEX_op_brcond_i32: ++ case INDEX_op_brcond_i64: ++ tcg_out_brcond(s, a2, a0, a1, arg_label(args[3])); ++ break; ++ ++ case INDEX_op_ext8s_i32: ++ case INDEX_op_ext8s_i64: ++ tcg_out_ext8s(s, a0, a1); ++ break; ++ ++ case INDEX_op_ext8u_i32: ++ case INDEX_op_ext8u_i64: ++ tcg_out_ext8u(s, a0, a1); ++ break; ++ ++ case INDEX_op_ext16s_i32: ++ case INDEX_op_ext16s_i64: ++ tcg_out_ext16s(s, a0, a1); ++ break; ++ ++ case INDEX_op_ext16u_i32: ++ case INDEX_op_ext16u_i64: ++ tcg_out_ext16u(s, a0, a1); ++ break; ++ ++ case INDEX_op_ext32u_i64: ++ case INDEX_op_extu_i32_i64: ++ tcg_out_ext32u(s, a0, a1); ++ break; ++ ++ case INDEX_op_ext32s_i64: ++ case INDEX_op_extrl_i64_i32: ++ case INDEX_op_ext_i32_i64: ++ tcg_out_ext32s(s, a0, a1); ++ break; ++ ++ case INDEX_op_extrh_i64_i32: ++ tcg_out_opc_srai_d(s, a0, a1, 32); ++ break; ++ ++ case INDEX_op_not_i32: ++ case INDEX_op_not_i64: ++ tcg_out_opc_nor(s, a0, a1, TCG_REG_ZERO); ++ break; ++ ++ case INDEX_op_nor_i32: ++ case INDEX_op_nor_i64: ++ if (c2) { ++ tcg_out_opc_ori(s, a0, a1, a2); ++ tcg_out_opc_nor(s, a0, a0, TCG_REG_ZERO); ++ } else { ++ tcg_out_opc_nor(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_andc_i32: ++ case INDEX_op_andc_i64: ++ if (c2) { ++ /* guaranteed to fit due to constraint */ ++ tcg_out_opc_andi(s, a0, a1, ~a2); ++ } else { ++ tcg_out_opc_andn(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_orc_i32: ++ case INDEX_op_orc_i64: ++ if (c2) { ++ /* guaranteed to fit due to constraint */ ++ tcg_out_opc_ori(s, a0, a1, ~a2); ++ } else { ++ tcg_out_opc_orn(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_and_i32: ++ case INDEX_op_and_i64: ++ if (c2) { ++ tcg_out_opc_andi(s, a0, a1, a2); ++ } else { ++ tcg_out_opc_and(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_or_i32: ++ case INDEX_op_or_i64: ++ if (c2) { ++ tcg_out_opc_ori(s, a0, a1, a2); ++ } else { ++ tcg_out_opc_or(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_xor_i32: ++ case INDEX_op_xor_i64: ++ if (c2) { ++ tcg_out_opc_xori(s, a0, a1, a2); ++ } else { ++ tcg_out_opc_xor(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_extract_i32: ++ tcg_out_opc_bstrpick_w(s, a0, a1, a2, a2 + args[3] - 1); ++ break; ++ case INDEX_op_extract_i64: ++ tcg_out_opc_bstrpick_d(s, a0, a1, a2, a2 + args[3] - 1); ++ break; ++ ++ case INDEX_op_deposit_i32: ++ tcg_out_opc_bstrins_w(s, a0, a2, args[3], args[3] + args[4] - 1); ++ break; ++ case INDEX_op_deposit_i64: ++ tcg_out_opc_bstrins_d(s, a0, a2, args[3], args[3] + args[4] - 1); ++ break; ++ ++ case INDEX_op_bswap16_i32: ++ case INDEX_op_bswap16_i64: ++ tcg_out_opc_revb_2h(s, a0, a1); ++ if (a2 & TCG_BSWAP_OS) { ++ tcg_out_ext16s(s, a0, a0); ++ } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { ++ tcg_out_ext16u(s, a0, a0); ++ } ++ break; ++ ++ case INDEX_op_bswap32_i32: ++ /* All 32-bit values are computed sign-extended in the register. */ ++ a2 = TCG_BSWAP_OS; ++ /* fallthrough */ ++ case INDEX_op_bswap32_i64: ++ tcg_out_opc_revb_2w(s, a0, a1); ++ if (a2 & TCG_BSWAP_OS) { ++ tcg_out_ext32s(s, a0, a0); ++ } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { ++ tcg_out_ext32u(s, a0, a0); ++ } ++ break; ++ ++ case INDEX_op_bswap64_i64: ++ tcg_out_opc_revb_d(s, a0, a1); ++ break; ++ ++ case INDEX_op_clz_i32: ++ tcg_out_clzctz(s, OPC_CLZ_W, a0, a1, a2, c2, true); ++ break; ++ case INDEX_op_clz_i64: ++ tcg_out_clzctz(s, OPC_CLZ_D, a0, a1, a2, c2, false); ++ break; ++ ++ case INDEX_op_ctz_i32: ++ tcg_out_clzctz(s, OPC_CTZ_W, a0, a1, a2, c2, true); ++ break; ++ case INDEX_op_ctz_i64: ++ tcg_out_clzctz(s, OPC_CTZ_D, a0, a1, a2, c2, false); ++ break; ++ ++ case INDEX_op_shl_i32: ++ if (c2) { ++ tcg_out_opc_slli_w(s, a0, a1, a2 & 0x1f); ++ } else { ++ tcg_out_opc_sll_w(s, a0, a1, a2); ++ } ++ break; ++ case INDEX_op_shl_i64: ++ if (c2) { ++ tcg_out_opc_slli_d(s, a0, a1, a2 & 0x3f); ++ } else { ++ tcg_out_opc_sll_d(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_shr_i32: ++ if (c2) { ++ tcg_out_opc_srli_w(s, a0, a1, a2 & 0x1f); ++ } else { ++ tcg_out_opc_srl_w(s, a0, a1, a2); ++ } ++ break; ++ case INDEX_op_shr_i64: ++ if (c2) { ++ tcg_out_opc_srli_d(s, a0, a1, a2 & 0x3f); ++ } else { ++ tcg_out_opc_srl_d(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_sar_i32: ++ if (c2) { ++ tcg_out_opc_srai_w(s, a0, a1, a2 & 0x1f); ++ } else { ++ tcg_out_opc_sra_w(s, a0, a1, a2); ++ } ++ break; ++ case INDEX_op_sar_i64: ++ if (c2) { ++ tcg_out_opc_srai_d(s, a0, a1, a2 & 0x3f); ++ } else { ++ tcg_out_opc_sra_d(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_rotl_i32: ++ /* transform into equivalent rotr/rotri */ ++ if (c2) { ++ tcg_out_opc_rotri_w(s, a0, a1, (32 - a2) & 0x1f); ++ } else { ++ tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2); ++ tcg_out_opc_rotr_w(s, a0, a1, TCG_REG_TMP0); ++ } ++ break; ++ case INDEX_op_rotl_i64: ++ /* transform into equivalent rotr/rotri */ ++ if (c2) { ++ tcg_out_opc_rotri_d(s, a0, a1, (64 - a2) & 0x3f); ++ } else { ++ tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2); ++ tcg_out_opc_rotr_d(s, a0, a1, TCG_REG_TMP0); ++ } ++ break; ++ ++ case INDEX_op_rotr_i32: ++ if (c2) { ++ tcg_out_opc_rotri_w(s, a0, a1, a2 & 0x1f); ++ } else { ++ tcg_out_opc_rotr_w(s, a0, a1, a2); ++ } ++ break; ++ case INDEX_op_rotr_i64: ++ if (c2) { ++ tcg_out_opc_rotri_d(s, a0, a1, a2 & 0x3f); ++ } else { ++ tcg_out_opc_rotr_d(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_add_i32: ++ if (c2) { ++ tcg_out_opc_addi_w(s, a0, a1, a2); ++ } else { ++ tcg_out_opc_add_w(s, a0, a1, a2); ++ } ++ break; ++ case INDEX_op_add_i64: ++ if (c2) { ++ tcg_out_opc_addi_d(s, a0, a1, a2); ++ } else { ++ tcg_out_opc_add_d(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_sub_i32: ++ if (c2) { ++ tcg_out_opc_addi_w(s, a0, a1, -a2); ++ } else { ++ tcg_out_opc_sub_w(s, a0, a1, a2); ++ } ++ break; ++ case INDEX_op_sub_i64: ++ if (c2) { ++ tcg_out_opc_addi_d(s, a0, a1, -a2); ++ } else { ++ tcg_out_opc_sub_d(s, a0, a1, a2); ++ } ++ break; ++ ++ case INDEX_op_mul_i32: ++ tcg_out_opc_mul_w(s, a0, a1, a2); ++ break; ++ case INDEX_op_mul_i64: ++ tcg_out_opc_mul_d(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_mulsh_i32: ++ tcg_out_opc_mulh_w(s, a0, a1, a2); ++ break; ++ case INDEX_op_mulsh_i64: ++ tcg_out_opc_mulh_d(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_muluh_i32: ++ tcg_out_opc_mulh_wu(s, a0, a1, a2); ++ break; ++ case INDEX_op_muluh_i64: ++ tcg_out_opc_mulh_du(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_div_i32: ++ tcg_out_opc_div_w(s, a0, a1, a2); ++ break; ++ case INDEX_op_div_i64: ++ tcg_out_opc_div_d(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_divu_i32: ++ tcg_out_opc_div_wu(s, a0, a1, a2); ++ break; ++ case INDEX_op_divu_i64: ++ tcg_out_opc_div_du(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_rem_i32: ++ tcg_out_opc_mod_w(s, a0, a1, a2); ++ break; ++ case INDEX_op_rem_i64: ++ tcg_out_opc_mod_d(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_remu_i32: ++ tcg_out_opc_mod_wu(s, a0, a1, a2); ++ break; ++ case INDEX_op_remu_i64: ++ tcg_out_opc_mod_du(s, a0, a1, a2); ++ break; ++ ++ case INDEX_op_setcond_i32: ++ case INDEX_op_setcond_i64: ++ tcg_out_setcond(s, args[3], a0, a1, a2, c2); ++ break; ++ ++ case INDEX_op_ld8s_i32: ++ case INDEX_op_ld8s_i64: ++ tcg_out_ldst(s, OPC_LD_B, a0, a1, a2); ++ break; ++ case INDEX_op_ld8u_i32: ++ case INDEX_op_ld8u_i64: ++ tcg_out_ldst(s, OPC_LD_BU, a0, a1, a2); ++ break; ++ case INDEX_op_ld16s_i32: ++ case INDEX_op_ld16s_i64: ++ tcg_out_ldst(s, OPC_LD_H, a0, a1, a2); ++ break; ++ case INDEX_op_ld16u_i32: ++ case INDEX_op_ld16u_i64: ++ tcg_out_ldst(s, OPC_LD_HU, a0, a1, a2); ++ break; ++ case INDEX_op_ld_i32: ++ case INDEX_op_ld32s_i64: ++ tcg_out_ldst(s, OPC_LD_W, a0, a1, a2); ++ break; ++ case INDEX_op_ld32u_i64: ++ tcg_out_ldst(s, OPC_LD_WU, a0, a1, a2); ++ break; ++ case INDEX_op_ld_i64: ++ tcg_out_ldst(s, OPC_LD_D, a0, a1, a2); ++ break; ++ ++ case INDEX_op_st8_i32: ++ case INDEX_op_st8_i64: ++ tcg_out_ldst(s, OPC_ST_B, a0, a1, a2); ++ break; ++ case INDEX_op_st16_i32: ++ case INDEX_op_st16_i64: ++ tcg_out_ldst(s, OPC_ST_H, a0, a1, a2); ++ break; ++ case INDEX_op_st_i32: ++ case INDEX_op_st32_i64: ++ tcg_out_ldst(s, OPC_ST_W, a0, a1, a2); ++ break; ++ case INDEX_op_st_i64: ++ tcg_out_ldst(s, OPC_ST_D, a0, a1, a2); ++ break; ++ ++ case INDEX_op_qemu_ld_i32: ++ tcg_out_qemu_ld(s, args, TCG_TYPE_I32); ++ break; ++ case INDEX_op_qemu_ld_i64: ++ tcg_out_qemu_ld(s, args, TCG_TYPE_I64); ++ break; ++ case INDEX_op_qemu_st_i32: ++ tcg_out_qemu_st(s, args); ++ break; ++ case INDEX_op_qemu_st_i64: ++ tcg_out_qemu_st(s, args); ++ break; ++ ++ case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ ++ case INDEX_op_mov_i64: ++ case INDEX_op_call: /* Always emitted via tcg_out_call. */ ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) ++{ ++ switch (op) { ++ case INDEX_op_goto_ptr: ++ return C_O0_I1(r); ++ ++ case INDEX_op_st8_i32: ++ case INDEX_op_st8_i64: ++ case INDEX_op_st16_i32: ++ case INDEX_op_st16_i64: ++ case INDEX_op_st32_i64: ++ case INDEX_op_st_i32: ++ case INDEX_op_st_i64: ++ return C_O0_I2(rZ, r); ++ ++ case INDEX_op_brcond_i32: ++ case INDEX_op_brcond_i64: ++ return C_O0_I2(rZ, rZ); ++ ++ case INDEX_op_qemu_st_i32: ++ case INDEX_op_qemu_st_i64: ++ return C_O0_I2(LZ, L); ++ ++ case INDEX_op_ext8s_i32: ++ case INDEX_op_ext8s_i64: ++ case INDEX_op_ext8u_i32: ++ case INDEX_op_ext8u_i64: ++ case INDEX_op_ext16s_i32: ++ case INDEX_op_ext16s_i64: ++ case INDEX_op_ext16u_i32: ++ case INDEX_op_ext16u_i64: ++ case INDEX_op_ext32s_i64: ++ case INDEX_op_ext32u_i64: ++ case INDEX_op_extu_i32_i64: ++ case INDEX_op_extrl_i64_i32: ++ case INDEX_op_extrh_i64_i32: ++ case INDEX_op_ext_i32_i64: ++ case INDEX_op_not_i32: ++ case INDEX_op_not_i64: ++ case INDEX_op_extract_i32: ++ case INDEX_op_extract_i64: ++ case INDEX_op_bswap16_i32: ++ case INDEX_op_bswap16_i64: ++ case INDEX_op_bswap32_i32: ++ case INDEX_op_bswap32_i64: ++ case INDEX_op_bswap64_i64: ++ case INDEX_op_ld8s_i32: ++ case INDEX_op_ld8s_i64: ++ case INDEX_op_ld8u_i32: ++ case INDEX_op_ld8u_i64: ++ case INDEX_op_ld16s_i32: ++ case INDEX_op_ld16s_i64: ++ case INDEX_op_ld16u_i32: ++ case INDEX_op_ld16u_i64: ++ case INDEX_op_ld32s_i64: ++ case INDEX_op_ld32u_i64: ++ case INDEX_op_ld_i32: ++ case INDEX_op_ld_i64: ++ return C_O1_I1(r, r); ++ ++ case INDEX_op_qemu_ld_i32: ++ case INDEX_op_qemu_ld_i64: ++ return C_O1_I1(r, L); ++ ++ case INDEX_op_andc_i32: ++ case INDEX_op_andc_i64: ++ case INDEX_op_orc_i32: ++ case INDEX_op_orc_i64: ++ /* ++ * LoongArch insns for these ops don't have reg-imm forms, but we ++ * can express using andi/ori if ~constant satisfies ++ * TCG_CT_CONST_U12. ++ */ ++ return C_O1_I2(r, r, rC); ++ ++ case INDEX_op_shl_i32: ++ case INDEX_op_shl_i64: ++ case INDEX_op_shr_i32: ++ case INDEX_op_shr_i64: ++ case INDEX_op_sar_i32: ++ case INDEX_op_sar_i64: ++ case INDEX_op_rotl_i32: ++ case INDEX_op_rotl_i64: ++ case INDEX_op_rotr_i32: ++ case INDEX_op_rotr_i64: ++ return C_O1_I2(r, r, ri); ++ ++ case INDEX_op_add_i32: ++ case INDEX_op_add_i64: ++ return C_O1_I2(r, r, rI); ++ ++ case INDEX_op_and_i32: ++ case INDEX_op_and_i64: ++ case INDEX_op_nor_i32: ++ case INDEX_op_nor_i64: ++ case INDEX_op_or_i32: ++ case INDEX_op_or_i64: ++ case INDEX_op_xor_i32: ++ case INDEX_op_xor_i64: ++ /* LoongArch reg-imm bitops have their imms ZERO-extended */ ++ return C_O1_I2(r, r, rU); ++ ++ case INDEX_op_clz_i32: ++ case INDEX_op_clz_i64: ++ case INDEX_op_ctz_i32: ++ case INDEX_op_ctz_i64: ++ return C_O1_I2(r, r, rW); ++ ++ case INDEX_op_setcond_i32: ++ case INDEX_op_setcond_i64: ++ return C_O1_I2(r, r, rZ); ++ ++ case INDEX_op_deposit_i32: ++ case INDEX_op_deposit_i64: ++ /* Must deposit into the same register as input */ ++ return C_O1_I2(r, 0, rZ); ++ ++ case INDEX_op_sub_i32: ++ case INDEX_op_sub_i64: ++ return C_O1_I2(r, rZ, rN); ++ ++ case INDEX_op_mul_i32: ++ case INDEX_op_mul_i64: ++ case INDEX_op_mulsh_i32: ++ case INDEX_op_mulsh_i64: ++ case INDEX_op_muluh_i32: ++ case INDEX_op_muluh_i64: ++ case INDEX_op_div_i32: ++ case INDEX_op_div_i64: ++ case INDEX_op_divu_i32: ++ case INDEX_op_divu_i64: ++ case INDEX_op_rem_i32: ++ case INDEX_op_rem_i64: ++ case INDEX_op_remu_i32: ++ case INDEX_op_remu_i64: ++ return C_O1_I2(r, rZ, rZ); ++ ++ default: ++ g_assert_not_reached(); ++ } ++} ++ ++static const int tcg_target_callee_save_regs[] = { ++ TCG_REG_S0, /* used for the global env (TCG_AREG0) */ ++ TCG_REG_S1, ++ TCG_REG_S2, ++ TCG_REG_S3, ++ TCG_REG_S4, ++ TCG_REG_S5, ++ TCG_REG_S6, ++ TCG_REG_S7, ++ TCG_REG_S8, ++ TCG_REG_S9, ++ TCG_REG_RA, /* should be last for ABI compliance */ ++}; ++ ++/* Stack frame parameters. */ ++#define REG_SIZE (TCG_TARGET_REG_BITS / 8) ++#define SAVE_SIZE ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE) ++#define TEMP_SIZE (CPU_TEMP_BUF_NLONGS * (int)sizeof(long)) ++#define FRAME_SIZE ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE \ ++ + TCG_TARGET_STACK_ALIGN - 1) \ ++ & -TCG_TARGET_STACK_ALIGN) ++#define SAVE_OFS (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE) ++ ++/* We're expecting to be able to use an immediate for frame allocation. */ ++QEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7ff); ++ ++/* Generate global QEMU prologue and epilogue code */ ++static void tcg_target_qemu_prologue(TCGContext *s) ++{ ++ int i; ++ ++ tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE); ++ ++ /* TB prologue */ ++ tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE); ++ for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { ++ tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i], ++ TCG_REG_SP, SAVE_OFS + i * REG_SIZE); ++ } ++ ++#if !defined(CONFIG_SOFTMMU) ++ if (USE_GUEST_BASE) { ++ tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base); ++ tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG); ++ } ++#endif ++ ++ /* Call generated code */ ++ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); ++ tcg_out_opc_jirl(s, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0); ++ ++ /* Return path for goto_ptr. Set return value to 0 */ ++ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr); ++ tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO); ++ ++ /* TB epilogue */ ++ tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr); ++ for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { ++ tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i], ++ TCG_REG_SP, SAVE_OFS + i * REG_SIZE); ++ } ++ ++ tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE); ++ tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_RA, 0); ++} ++ ++static void tcg_target_init(TCGContext *s) ++{ ++ tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS; ++ tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS; ++ ++ tcg_target_call_clobber_regs = ALL_GENERAL_REGS; ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S3); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S4); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S5); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S6); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S7); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S8); ++ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S9); ++ ++ s->reserved_regs = 0; ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP0); ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2); ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP); ++ tcg_regset_set_reg(s->reserved_regs, TCG_REG_RESERVED); ++} ++ ++typedef struct { ++ DebugFrameHeader h; ++ uint8_t fde_def_cfa[4]; ++ uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2]; ++} DebugFrame; ++ ++#define ELF_HOST_MACHINE EM_LOONGARCH ++ ++static const DebugFrame debug_frame = { ++ .h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */ ++ .h.cie.id = -1, ++ .h.cie.version = 1, ++ .h.cie.code_align = 1, ++ .h.cie.data_align = -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */ ++ .h.cie.return_column = TCG_REG_RA, ++ ++ /* Total FDE size does not include the "len" member. */ ++ .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset), ++ ++ .fde_def_cfa = { ++ 12, TCG_REG_SP, /* DW_CFA_def_cfa sp, ... */ ++ (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */ ++ (FRAME_SIZE >> 7) ++ }, ++ .fde_reg_ofs = { ++ 0x80 + 23, 11, /* DW_CFA_offset, s0, -88 */ ++ 0x80 + 24, 10, /* DW_CFA_offset, s1, -80 */ ++ 0x80 + 25, 9, /* DW_CFA_offset, s2, -72 */ ++ 0x80 + 26, 8, /* DW_CFA_offset, s3, -64 */ ++ 0x80 + 27, 7, /* DW_CFA_offset, s4, -56 */ ++ 0x80 + 28, 6, /* DW_CFA_offset, s5, -48 */ ++ 0x80 + 29, 5, /* DW_CFA_offset, s6, -40 */ ++ 0x80 + 30, 4, /* DW_CFA_offset, s7, -32 */ ++ 0x80 + 31, 3, /* DW_CFA_offset, s8, -24 */ ++ 0x80 + 22, 2, /* DW_CFA_offset, s9, -16 */ ++ 0x80 + 1 , 1, /* DW_CFA_offset, ra, -8 */ ++ } ++}; ++ ++void tcg_register_jit(const void *buf, size_t buf_size) ++{ ++ tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); ++} +diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h +new file mode 100644 +index 000000000..d58a6162f +--- /dev/null ++++ b/tcg/loongarch64/tcg-target.h +@@ -0,0 +1,178 @@ ++/* ++ * Tiny Code Generator for QEMU ++ * ++ * Copyright (c) 2021 WANG Xuerui ++ * ++ * Based on tcg/riscv/tcg-target.h ++ * ++ * Copyright (c) 2018 SiFive, Inc ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ ++#ifndef LOONGARCH_TCG_TARGET_H ++#define LOONGARCH_TCG_TARGET_H ++ ++/* ++ * Loongson removed the (incomplete) 32-bit support from kernel and toolchain ++ * for the initial upstreaming of this architecture, so don't bother and just ++ * support the LP64* ABI for now. ++ */ ++#if defined(__loongarch64) ++# define TCG_TARGET_REG_BITS 64 ++#else ++# error unsupported LoongArch register size ++#endif ++ ++#define TCG_TARGET_INSN_UNIT_SIZE 4 ++#define TCG_TARGET_NB_REGS 32 ++#define MAX_CODE_GEN_BUFFER_SIZE SIZE_MAX ++ ++typedef enum { ++ TCG_REG_ZERO, ++ TCG_REG_RA, ++ TCG_REG_TP, ++ TCG_REG_SP, ++ TCG_REG_A0, ++ TCG_REG_A1, ++ TCG_REG_A2, ++ TCG_REG_A3, ++ TCG_REG_A4, ++ TCG_REG_A5, ++ TCG_REG_A6, ++ TCG_REG_A7, ++ TCG_REG_T0, ++ TCG_REG_T1, ++ TCG_REG_T2, ++ TCG_REG_T3, ++ TCG_REG_T4, ++ TCG_REG_T5, ++ TCG_REG_T6, ++ TCG_REG_T7, ++ TCG_REG_T8, ++ TCG_REG_RESERVED, ++ TCG_REG_S9, ++ TCG_REG_S0, ++ TCG_REG_S1, ++ TCG_REG_S2, ++ TCG_REG_S3, ++ TCG_REG_S4, ++ TCG_REG_S5, ++ TCG_REG_S6, ++ TCG_REG_S7, ++ TCG_REG_S8, ++ ++ /* aliases */ ++ TCG_AREG0 = TCG_REG_S0, ++ TCG_REG_TMP0 = TCG_REG_T8, ++ TCG_REG_TMP1 = TCG_REG_T7, ++ TCG_REG_TMP2 = TCG_REG_T6, ++} TCGReg; ++ ++/* used for function call generation */ ++#define TCG_REG_CALL_STACK TCG_REG_SP ++#define TCG_TARGET_STACK_ALIGN 16 ++#define TCG_TARGET_CALL_ALIGN_ARGS 1 ++#define TCG_TARGET_CALL_STACK_OFFSET 0 ++ ++/* optional instructions */ ++#define TCG_TARGET_HAS_movcond_i32 0 ++#define TCG_TARGET_HAS_div_i32 1 ++#define TCG_TARGET_HAS_rem_i32 1 ++#define TCG_TARGET_HAS_div2_i32 0 ++#define TCG_TARGET_HAS_rot_i32 1 ++#define TCG_TARGET_HAS_deposit_i32 1 ++#define TCG_TARGET_HAS_extract_i32 1 ++#define TCG_TARGET_HAS_sextract_i32 0 ++#define TCG_TARGET_HAS_extract2_i32 0 ++#define TCG_TARGET_HAS_add2_i32 0 ++#define TCG_TARGET_HAS_sub2_i32 0 ++#define TCG_TARGET_HAS_mulu2_i32 0 ++#define TCG_TARGET_HAS_muls2_i32 0 ++#define TCG_TARGET_HAS_muluh_i32 1 ++#define TCG_TARGET_HAS_mulsh_i32 1 ++#define TCG_TARGET_HAS_ext8s_i32 1 ++#define TCG_TARGET_HAS_ext16s_i32 1 ++#define TCG_TARGET_HAS_ext8u_i32 1 ++#define TCG_TARGET_HAS_ext16u_i32 1 ++#define TCG_TARGET_HAS_bswap16_i32 1 ++#define TCG_TARGET_HAS_bswap32_i32 1 ++#define TCG_TARGET_HAS_not_i32 1 ++#define TCG_TARGET_HAS_neg_i32 0 ++#define TCG_TARGET_HAS_andc_i32 1 ++#define TCG_TARGET_HAS_orc_i32 1 ++#define TCG_TARGET_HAS_eqv_i32 0 ++#define TCG_TARGET_HAS_nand_i32 0 ++#define TCG_TARGET_HAS_nor_i32 1 ++#define TCG_TARGET_HAS_clz_i32 1 ++#define TCG_TARGET_HAS_ctz_i32 1 ++#define TCG_TARGET_HAS_ctpop_i32 0 ++#define TCG_TARGET_HAS_direct_jump 0 ++#define TCG_TARGET_HAS_brcond2 0 ++#define TCG_TARGET_HAS_setcond2 0 ++#define TCG_TARGET_HAS_qemu_st8_i32 0 ++ ++/* 64-bit operations */ ++#define TCG_TARGET_HAS_movcond_i64 0 ++#define TCG_TARGET_HAS_div_i64 1 ++#define TCG_TARGET_HAS_rem_i64 1 ++#define TCG_TARGET_HAS_div2_i64 0 ++#define TCG_TARGET_HAS_rot_i64 1 ++#define TCG_TARGET_HAS_deposit_i64 1 ++#define TCG_TARGET_HAS_extract_i64 1 ++#define TCG_TARGET_HAS_sextract_i64 0 ++#define TCG_TARGET_HAS_extract2_i64 0 ++#define TCG_TARGET_HAS_extrl_i64_i32 1 ++#define TCG_TARGET_HAS_extrh_i64_i32 1 ++#define TCG_TARGET_HAS_ext8s_i64 1 ++#define TCG_TARGET_HAS_ext16s_i64 1 ++#define TCG_TARGET_HAS_ext32s_i64 1 ++#define TCG_TARGET_HAS_ext8u_i64 1 ++#define TCG_TARGET_HAS_ext16u_i64 1 ++#define TCG_TARGET_HAS_ext32u_i64 1 ++#define TCG_TARGET_HAS_bswap16_i64 1 ++#define TCG_TARGET_HAS_bswap32_i64 1 ++#define TCG_TARGET_HAS_bswap64_i64 1 ++#define TCG_TARGET_HAS_not_i64 1 ++#define TCG_TARGET_HAS_neg_i64 0 ++#define TCG_TARGET_HAS_andc_i64 1 ++#define TCG_TARGET_HAS_orc_i64 1 ++#define TCG_TARGET_HAS_eqv_i64 0 ++#define TCG_TARGET_HAS_nand_i64 0 ++#define TCG_TARGET_HAS_nor_i64 1 ++#define TCG_TARGET_HAS_clz_i64 1 ++#define TCG_TARGET_HAS_ctz_i64 1 ++#define TCG_TARGET_HAS_ctpop_i64 0 ++#define TCG_TARGET_HAS_add2_i64 0 ++#define TCG_TARGET_HAS_sub2_i64 0 ++#define TCG_TARGET_HAS_mulu2_i64 0 ++#define TCG_TARGET_HAS_muls2_i64 0 ++#define TCG_TARGET_HAS_muluh_i64 1 ++#define TCG_TARGET_HAS_mulsh_i64 1 ++ ++/* not defined -- call should be eliminated at compile time */ ++void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t); ++ ++#define TCG_TARGET_DEFAULT_MO (0) ++ ++#define TCG_TARGET_NEED_LDST_LABELS ++ ++#define TCG_TARGET_HAS_MEMORY_BSWAP 0 ++ ++#endif /* LOONGARCH_TCG_TARGET_H */ +-- +2.27.0 + diff --git a/Add-target-loongarch64.patch b/Add-target-loongarch64.patch new file mode 100644 index 00000000..8b1c4b10 --- /dev/null +++ b/Add-target-loongarch64.patch @@ -0,0 +1,16645 @@ +From e79eccfd2aa7a57fa84e8d7d92eb773fd84b9c21 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Wed, 7 Dec 2022 04:26:52 -0500 +Subject: [PATCH 04/11] Add target/loongarch64. + +Signed-off-by: lixianglai +--- + hw/loongarch/acpi-build.c | 46 +- + hw/loongarch/apic.c | 4 +- + hw/loongarch/ioapic.c | 4 +- + hw/loongarch/iocsr.c | 22 +- + hw/loongarch/ipi.c | 4 +- + hw/loongarch/larch_3a.c | 102 +- + hw/loongarch/larch_hotplug.c | 16 +- + hw/loongarch/ls7a_nb.c | 49 - + hw/loongarch/meson.build | 1 + + hw/loongarch/sysbus-fdt.c | 183 ++ + include/hw/loongarch/larch.h | 3 +- + include/hw/loongarch/ls7a.h | 68 +- + include/hw/loongarch/sysbus-fdt.h | 37 + + target/Kconfig | 1 + + target/loongarch64/Kconfig | 2 + + target/loongarch64/arch_dump.c | 175 ++ + target/loongarch64/cpu-csr.h | 869 ++++++++ + target/loongarch64/cpu-param.h | 30 + + target/loongarch64/cpu-qom.h | 54 + + target/loongarch64/cpu.c | 576 +++++ + target/loongarch64/cpu.h | 326 +++ + target/loongarch64/csr_helper.c | 704 ++++++ + target/loongarch64/fpu.c | 28 + + target/loongarch64/fpu_helper.c | 952 ++++++++ + target/loongarch64/fpu_helper.h | 129 ++ + target/loongarch64/gdbstub.c | 109 + + target/loongarch64/helper.c | 727 ++++++ + target/loongarch64/helper.h | 168 ++ + target/loongarch64/insn.decode | 514 +++++ + target/loongarch64/instmap.h | 216 ++ + target/loongarch64/internal.h | 184 ++ + target/loongarch64/kvm.c | 1384 ++++++++++++ + target/loongarch64/kvm_larch.h | 41 + + target/loongarch64/larch-defs.h | 27 + + target/loongarch64/machine.c | 423 ++++ + target/loongarch64/meson.build | 35 + + target/loongarch64/op_helper.c | 533 +++++ + target/loongarch64/stabletimer.c | 122 + + target/loongarch64/tlb_helper.c | 729 ++++++ + target/loongarch64/trace-events | 3 + + target/loongarch64/trans.inc.c | 3472 +++++++++++++++++++++++++++++ + target/loongarch64/translate.c | 2892 ++++++++++++++++++++++++ + target/meson.build | 1 + + 43 files changed, 15838 insertions(+), 127 deletions(-) + create mode 100644 hw/loongarch/sysbus-fdt.c + create mode 100644 include/hw/loongarch/sysbus-fdt.h + create mode 100644 target/loongarch64/Kconfig + create mode 100644 target/loongarch64/arch_dump.c + create mode 100644 target/loongarch64/cpu-csr.h + create mode 100644 target/loongarch64/cpu-param.h + create mode 100644 target/loongarch64/cpu-qom.h + create mode 100644 target/loongarch64/cpu.c + create mode 100644 target/loongarch64/cpu.h + create mode 100644 target/loongarch64/csr_helper.c + create mode 100644 target/loongarch64/fpu.c + create mode 100644 target/loongarch64/fpu_helper.c + create mode 100644 target/loongarch64/fpu_helper.h + create mode 100644 target/loongarch64/gdbstub.c + create mode 100644 target/loongarch64/helper.c + create mode 100644 target/loongarch64/helper.h + create mode 100644 target/loongarch64/insn.decode + create mode 100644 target/loongarch64/instmap.h + create mode 100644 target/loongarch64/internal.h + create mode 100644 target/loongarch64/kvm.c + create mode 100644 target/loongarch64/kvm_larch.h + create mode 100644 target/loongarch64/larch-defs.h + create mode 100644 target/loongarch64/machine.c + create mode 100644 target/loongarch64/meson.build + create mode 100644 target/loongarch64/op_helper.c + create mode 100644 target/loongarch64/stabletimer.c + create mode 100644 target/loongarch64/tlb_helper.c + create mode 100644 target/loongarch64/trace-events + create mode 100644 target/loongarch64/trans.inc.c + create mode 100644 target/loongarch64/translate.c + +diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c +index 6ba637be5..0b1690b0e 100644 +--- a/hw/loongarch/acpi-build.c ++++ b/hw/loongarch/acpi-build.c +@@ -58,6 +58,7 @@ + #include "hw/acpi/aml-build.h" + #include "hw/loongarch/larch.h" + #include "hw/loongarch/ls7a.h" ++#include "hw/platform-bus.h" + + #include "hw/acpi/ipmi.h" + #include "hw/acpi/ls7a.h" +@@ -474,7 +475,40 @@ static void build_ls7a_uart_device_aml(Aml *table) + aml_append(scope, dev); + aml_append(table, scope); + } ++#ifdef CONFIG_TPM ++static void acpi_dsdt_add_tpm(Aml *scope, LoongarchMachineState *vms) ++{ ++ PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev); ++ hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS; ++ SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find()); ++ MemoryRegion *sbdev_mr; ++ hwaddr tpm_base; ++ ++ if (!sbdev) { ++ return; ++ } ++ ++ tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); ++ assert(tpm_base != -1); + ++ tpm_base += pbus_base; ++ ++ sbdev_mr = sysbus_mmio_get_region(sbdev, 0); ++ ++ Aml *dev = aml_device("TPM0"); ++ aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101"))); ++ aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device"))); ++ aml_append(dev, aml_name_decl("_UID", aml_int(0))); ++ ++ Aml *crs = aml_resource_template(); ++ aml_append(crs, ++ aml_memory32_fixed(tpm_base, ++ (uint32_t)memory_region_size(sbdev_mr), ++ AML_READ_WRITE)); ++ aml_append(dev, aml_name_decl("_CRS", crs)); ++ aml_append(scope, dev); ++} ++#endif + static void + build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) + { +@@ -500,6 +534,10 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) + aml_append(dev, aml_name_decl("_UID", aml_int(1))); + aml_append(dev, build_ls7a_osc_method()); + aml_append(sb_scope, dev); ++ ++#ifdef CONFIG_TPM ++ acpi_dsdt_add_tpm(sb_scope, lsms); ++#endif + aml_append(dsdt, sb_scope); + + build_ls7a_pci0_int(dsdt); +@@ -511,7 +549,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) + .acpi_1_compatible = true, .has_legacy_cphp = false + }; + build_cpus_aml(dsdt, machine, opts, CPU_HOTPLUG_BASE, +- "\\_SB.PCI0", "\\_GPE._E02"); ++ "\\_SB.PCI0", "\\_GPE._E02", AML_SYSTEM_MEMORY); + + build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0", + "\\_GPE._E03", AML_SYSTEM_MEMORY, +@@ -633,6 +671,12 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) + lsms->oem_table_id); + } + ++ if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) { ++ acpi_add_table(table_offsets, tables_blob); ++ build_tpm2(tables_blob, tables->linker, tables->tcpalog, ++ lsms->oem_id, lsms->oem_table_id); ++ } ++ + /* Build mcfg */ + acpi_add_table(table_offsets, tables_blob); + { +diff --git a/hw/loongarch/apic.c b/hw/loongarch/apic.c +index d6ba2a2ce..67994d201 100644 +--- a/hw/loongarch/apic.c ++++ b/hw/loongarch/apic.c +@@ -64,7 +64,7 @@ static int ext_irq_pre_save(void *opaque) + struct kvm_loongarch_ls3a_extirq_state *kstate; + int ret, length, i, vcpuid; + #endif +- if (!kvm_irqchip_in_kernel()) { ++ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { + return 0; + } + #ifdef CONFIG_KVM +@@ -112,7 +112,7 @@ static int ext_irq_post_load(void *opaque, int version) + struct kvm_loongarch_ls3a_extirq_state *kstate; + int ret, length, i, vcpuid; + #endif +- if (!kvm_irqchip_in_kernel()) { ++ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { + return 0; + } + #ifdef CONFIG_KVM +diff --git a/hw/loongarch/ioapic.c b/hw/loongarch/ioapic.c +index 3de0ed88d..60abff855 100644 +--- a/hw/loongarch/ioapic.c ++++ b/hw/loongarch/ioapic.c +@@ -253,7 +253,7 @@ static int kvm_ls7a_pre_save(void *opaque) + struct ls7a_ioapic_state *state; + int ret, i, length; + +- if (!kvm_irqchip_in_kernel()) { ++ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { + return 0; + } + +@@ -297,7 +297,7 @@ static int kvm_ls7a_post_load(void *opaque, int version) + struct ls7a_ioapic_state *state; + int ret, i, length; + +- if (!kvm_irqchip_in_kernel()) { ++ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { + return 0; + } + length = sizeof(struct loongarch_kvm_irqchip) + sizeof(struct ls7a_ioapic_state); +diff --git a/hw/loongarch/iocsr.c b/hw/loongarch/iocsr.c +index 14521c2d5..13d356d80 100644 +--- a/hw/loongarch/iocsr.c ++++ b/hw/loongarch/iocsr.c +@@ -59,6 +59,7 @@ enum { + IOCSR_MAX + }; + ++#ifdef CONFIG_KVM + static uint32_t iocsr_array[IOCSR_MAX] = { + [IOCSR_FEATURES] = LOONGARCH_IOCSR_FEATURES, + [IOCSR_VENDOR] = LOONGARCH_IOCSR_VENDOR, +@@ -66,6 +67,7 @@ static uint32_t iocsr_array[IOCSR_MAX] = { + [IOCSR_NODECNT] = LOONGARCH_IOCSR_NODECNT, + [IOCSR_MISC_FUNC] = LOONGARCH_IOCSR_MISC_FUNC, + }; ++#endif + + + #define TYPE_IOCSR "iocsr" +@@ -93,6 +95,11 @@ static int kvm_iocsr_pre_save(void *opaque) + IOCSRState *s = opaque; + struct kvm_iocsr_entry entry; + int i = 0; ++ ++ if ((!kvm_enabled())) { ++ return 0; ++ } ++ + for (i = 0; i < IOCSR_MAX; i++) { + entry.addr = iocsr_array[i]; + kvm_vm_ioctl(kvm_state, KVM_LOONGARCH_GET_IOCSR, &entry); +@@ -170,8 +177,19 @@ static void iocsr_instance_init(Object *obj) + { + IOCSRState *s = IOCSR(obj); + int i; +- LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); +- LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); ++ LoongarchMachineState *lsms; ++ LoongarchMachineClass *lsmc; ++ Object *machine = qdev_get_machine(); ++ ObjectClass *mc = object_get_class(machine); ++ ++ ++ /* 'lams' should be initialized */ ++ if (!strcmp(MACHINE_CLASS(mc)->name, "none")) { ++ return; ++ } ++ ++ lsms = LoongarchMACHINE(machine); ++ lsmc = LoongarchMACHINE_GET_CLASS(lsms); + + init_vendor_cpuname((uint64_t *)&iocsr_init.iocsr_val[IOCSR_VENDOR], + (uint64_t *)&iocsr_init.iocsr_val[IOCSR_CPUNAME], +diff --git a/hw/loongarch/ipi.c b/hw/loongarch/ipi.c +index ade182abc..59186f1de 100644 +--- a/hw/loongarch/ipi.c ++++ b/hw/loongarch/ipi.c +@@ -25,7 +25,7 @@ static int gipi_pre_save(void *opaque) + int ret, i, j, length; + #endif + +- if (!kvm_irqchip_in_kernel()) { ++ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { + return 0; + } + +@@ -67,7 +67,7 @@ static int gipi_post_load(void *opaque, int version) + int ret, i, j, length; + #endif + +- if (!kvm_irqchip_in_kernel()) { ++ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { + return 0; + } + +diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c +index 3db269274..4f1d4cea2 100644 +--- a/hw/loongarch/larch_3a.c ++++ b/hw/loongarch/larch_3a.c +@@ -52,6 +52,7 @@ + #include "hw/rtc/mc146818rtc.h" + #include "hw/irq.h" + #include "net/net.h" ++#include "hw/platform-bus.h" + #include "hw/timer/i8254.h" + #include "hw/loongarch/larch.h" + #include "hw/loongarch/ls7a.h" +@@ -65,6 +66,8 @@ + #include "sysemu/device_tree.h" + #include "qapi/visitor.h" + #include "qapi/qapi-visit-common.h" ++#include "sysemu/tpm.h" ++#include "hw/loongarch/sysbus-fdt.h" + + #include + +@@ -85,10 +88,8 @@ + + #ifdef CONFIG_KVM + #define LS_ISA_IO_SIZE 0x02000000 +-#define LS_ISA_MEM_SIZE 0x40000000 + #else + #define LS_ISA_IO_SIZE 0x00010000 +-#define LS_ISA_MEM_SIZE 0x01000000 + #endif + + #ifdef CONFIG_KVM +@@ -546,7 +547,15 @@ static char *get_host_cpu_model_name(void) + fprintf(stderr, "read err...\n"); + } + close(fd); +- buf_p = strstr(buf, "name"); ++ buf_p = strstr(buf, "Name"); ++ if (!buf_p) { ++ buf_p = strstr(buf, "name"); ++ } ++ if (!buf_p) { ++ fprintf(stderr, "Can't find cpu name\n"); ++ return 0; ++ } ++ + + while (*buf_p != ':') { + buf_p++; +@@ -623,8 +632,8 @@ static struct irq_source_routing_table *init_irq_source(void *g_irq_source) + irq_info->ht_enable = 0x0000d17b; + irq_info->node_id = 0; + +- irq_info->pci_mem_start_addr = LS_ISA_MEM_BASE; +- irq_info->pci_mem_end_addr = irq_info->pci_mem_start_addr + LS_ISA_MEM_SIZE - 1; ++ irq_info->pci_mem_start_addr = PCIE_MEMORY_BASE; ++ irq_info->pci_mem_end_addr = irq_info->pci_mem_start_addr + PCIE_MEMORY_SIZE - 1; + + if (strstr(lsmc->cpu_name, "5000")) { + irq_info->pci_io_start_addr = LS3A5K_ISA_IO_BASE; +@@ -846,7 +855,7 @@ static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg, + if (0 < initrd_size) { + if (initrd_size > highram_size) { + error_report("initrd size is too big, should below %ld MB", +- highram_size / S_1MiB); ++ highram_size / MiB); + /*prevent write io memory address space*/ + exit(1); + } +@@ -1033,7 +1042,9 @@ static void *ls3a_intctl_init(MachineState *machine, CPULOONGARCHState *env[]) + SysBusDevice *busdev; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *iomem = NULL; ++#ifdef CONFIG_KVM + int i; ++#endif + + s = g_malloc0(sizeof(ls3a_intctlstate)); + +@@ -1214,10 +1225,8 @@ static void loongarch_build_smbios(LoongarchMachineState *lsms) + product = "Loongarch-3A5K-7A1000-TCG"; + } + +- host_cpufreq = get_host_cpu_freq(); +- + smbios_set_defaults("Loongson", product, lsmc->cpu_name, false, +- true, NULL, NULL, SMBIOS_ENTRY_POINT_30); ++ true, SMBIOS_ENTRY_POINT_30); + + smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len, + &smbios_anchor, &smbios_anchor_len, &error_fatal); +@@ -1235,6 +1244,19 @@ void loongarch_machine_done(Notifier *notifier, void *data) + { + LoongarchMachineState *lsms = container_of(notifier, + LoongarchMachineState, machine_done); ++ ++ platform_bus_add_all_fdt_nodes(lsms->fdt, NULL, ++ VIRT_PLATFORM_BUS_BASEADDRESS, ++ VIRT_PLATFORM_BUS_SIZE, ++ VIRT_PLATFORM_BUS_IRQ); ++ ++ qemu_fdt_dumpdtb(lsms->fdt, lsms->fdt_size); ++ /* load fdt */ ++ MemoryRegion *fdt_rom = g_new(MemoryRegion, 1); ++ memory_region_init_rom(fdt_rom, NULL, "fdt", LS_FDT_SIZE, &error_fatal); ++ memory_region_add_subregion(get_system_memory(), LS_FDT_BASE, fdt_rom); ++ rom_add_blob_fixed("fdt", lsms->fdt, lsms->fdt_size, LS_FDT_BASE); ++ + loongarch_acpi_setup(); + loongarch_build_smbios(lsms); + } +@@ -1421,9 +1443,6 @@ static void ls3a5k_bios_init(LoongarchMachineState *lsms, + + if (kernel_filename) { + lsms->reset_info[0]->vector = load_kernel(); +- } else { +- error_report("Please specify at lease one of -bios and -kernel"); +- exit(1); + } + } + } +@@ -1535,8 +1554,8 @@ static void fdt_add_fw_cfg_node(const LoongarchMachineState *lsms) + static void fdt_add_pcie_node(const LoongarchMachineState *lsms) + { + char *nodename; +- hwaddr base_mmio = LS_ISA_MEM_BASE; +- hwaddr size_mmio = LS_ISA_MEM_SIZE; ++ hwaddr base_mmio = PCIE_MEMORY_BASE; ++ hwaddr size_mmio = PCIE_MEMORY_SIZE; + hwaddr base_pio = LS3A5K_ISA_IO_BASE; + hwaddr size_pio = LS_ISA_IO_SIZE; + hwaddr base_pcie = LS_PCIECFG_BASE; +@@ -1562,7 +1581,31 @@ static void fdt_add_pcie_node(const LoongarchMachineState *lsms) + 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, + 2, base_mmio, 2, size_mmio); + g_free(nodename); +- qemu_fdt_dumpdtb(lsms->fdt, lsms->fdt_size); ++} ++ ++static void create_platform_bus(LoongarchMachineState *s, qemu_irq *pic) ++{ ++ DeviceState *dev; ++ SysBusDevice *sysbus; ++ int i; ++ MemoryRegion *sysmem = get_system_memory(); ++ ++ dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE); ++ dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE); ++ qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS); ++ qdev_prop_set_uint32(dev, "mmio_size", VIRT_PLATFORM_BUS_SIZE); ++ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); ++ s->platform_bus_dev = dev; ++ ++ sysbus = SYS_BUS_DEVICE(dev); ++ for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) { ++ int irq = VIRT_PLATFORM_BUS_IRQ + i; ++ sysbus_connect_irq(sysbus, i, pic[irq - LOONGARCH_PCH_IRQ_BASE]); ++ } ++ ++ memory_region_add_subregion(sysmem, ++ VIRT_PLATFORM_BUS_BASEADDRESS, ++ sysbus_mmio_get_region(sysbus, 0)); + } + + static void ls3a5k_init(MachineState *args) +@@ -1610,7 +1653,6 @@ static void ls3a5k_init(MachineState *args) + create_fdt(lsms); + + DPRINTF("isa 0x%lx\n", lsmc->isa_io_base); +- DPRINTF("ht1lo 0x%lx\n", lsmc->ht1lo_pcicfg_base); + DPRINTF("cpu_name %s bridge_name %s\n", + lsmc->cpu_name, lsmc->bridge_name); + +@@ -1672,15 +1714,15 @@ static void ls3a5k_init(MachineState *args) + + offset += lowram_size; + if (nb_numa_nodes > 0) { +- highram_size = numa_info[0].node_mem - S_256MiB; +- if (numa_info[0].node_mem > S_1GiB) { +- memmap_size = numa_info[0].node_mem - S_1GiB; ++ highram_size = numa_info[0].node_mem - 256 * MiB; ++ if (numa_info[0].node_mem > GiB) { ++ memmap_size = numa_info[0].node_mem - GiB; + la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); + } + } else { +- highram_size = ram_size - S_256MiB; +- if (ram_size > S_1GiB) { +- memmap_size = ram_size - S_1GiB; ++ highram_size = ram_size - 256 * MiB; ++ if (ram_size > GiB) { ++ memmap_size = ram_size - GiB; + la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); + } + } +@@ -1760,9 +1802,9 @@ static void ls3a5k_init(MachineState *args) + + memory_region_init_alias(isa_io, NULL, "isa-io", + get_system_io(), 0, LS_ISA_IO_SIZE); +- memory_region_init(isa_mem, NULL, "isa-mem", LS_ISA_MEM_SIZE); ++ memory_region_init(isa_mem, NULL, "isa-mem", PCIE_MEMORY_SIZE); + memory_region_add_subregion(get_system_memory(), lsmc->isa_io_base, isa_io); +- memory_region_add_subregion(get_system_memory(), LS_ISA_MEM_BASE, isa_mem); ++ memory_region_add_subregion(get_system_memory(), PCIE_MEMORY_BASE, isa_mem); + + if (!strcmp(lsmc->bridge_name, "ls7a")) { + /*Initialize the 7A IO interrupt subsystem*/ +@@ -1784,6 +1826,8 @@ static void ls3a5k_init(MachineState *args) + object_property_set_link(OBJECT(machine), LOONGARCH_MACHINE_ACPI_DEVICE_PROP, + OBJECT(ls7a_dev), &error_abort); + ++ create_platform_bus(lsms, ls7a_apic); ++ + #ifdef CONFIG_KVM + if (kvm_enabled()) { + kvm_direct_msi_allowed = (kvm_check_extension(kvm_state, +@@ -1835,11 +1879,6 @@ static void ls3a5k_init(MachineState *args) + + fdt_add_pcie_node(lsms); + +- /* load fdt */ +- MemoryRegion *fdt_rom = g_new(MemoryRegion, 1); +- memory_region_init_rom(fdt_rom, NULL, "fdt", LS_FDT_SIZE, &error_fatal); +- memory_region_add_subregion(get_system_memory(), LS_FDT_BASE, fdt_rom); +- rom_add_blob_fixed("fdt", lsms->fdt, lsms->fdt_size, LS_FDT_BASE); + } + + static const CPUArchIdList *loongarch_possible_cpu_arch_ids(MachineState *ms) +@@ -1913,7 +1952,6 @@ static void ls3a5k_ls7a_machine_options(MachineClass *m) + m->alias = "loongson7a"; + m->is_default = 1; + lsmc->isa_io_base = LS3A5K_ISA_IO_BASE; +- lsmc->ht1lo_pcicfg_base = LS3A5K_HT1LO_PCICFG_BASE; + lsmc->pciecfg_base = LS_PCIECFG_BASE; + lsmc->ls7a_ioapic_reg_base = LS3A5K_LS7A_IOAPIC_REG_BASE; + lsmc->node_shift = 44; +@@ -1986,6 +2024,10 @@ static void loongarch_class_init(ObjectClass *oc, void *data) + mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("Loongson-3A5000"); + mc->default_ram_id = "loongarch_ls3a.ram"; + ++#ifdef CONFIG_TPM ++ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); ++#endif ++ + mc->reset = ls3a_board_reset; + mc->max_cpus = LOONGARCH_MAX_VCPUS; + hc->pre_plug = loongarch_machine_device_pre_plug; +diff --git a/hw/loongarch/larch_hotplug.c b/hw/loongarch/larch_hotplug.c +index 7bce95712..bb3e9826b 100644 +--- a/hw/loongarch/larch_hotplug.c ++++ b/hw/loongarch/larch_hotplug.c +@@ -32,6 +32,7 @@ + #include "hw/loongarch/larch.h" + #include "hw/cpu/core.h" + #include "hw/nvram/fw_cfg.h" ++#include "hw/platform-bus.h" + + /* find cpu slot in machine->possible_cpus by core_id */ + static CPUArchId *loongarch_find_cpu_slot(MachineState *ms, uint32_t id, +@@ -327,7 +328,8 @@ HotplugHandler *loongarch_get_hotpug_handler(MachineState *machine, + DeviceState *dev) + { + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || +- object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { ++ object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU) || ++ object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) { + return HOTPLUG_HANDLER(machine); + } + return NULL; +@@ -346,6 +348,18 @@ void loongarch_machine_device_pre_plug(HotplugHandler *hotplug_dev, + void loongarch_machine_device_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) + { ++ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); ++ ++ if (lsms->platform_bus_dev) { ++ MachineClass *mc = MACHINE_GET_CLASS(lsms); ++ ++ if (device_is_dynamic_sysbus(mc, dev)) { ++ platform_bus_link_device( ++ PLATFORM_BUS_DEVICE(lsms->platform_bus_dev), ++ SYS_BUS_DEVICE(dev)); ++ } ++ } ++ + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + loongarch_memory_plug(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { +diff --git a/hw/loongarch/ls7a_nb.c b/hw/loongarch/ls7a_nb.c +index 5a500fbd5..5a231e6f0 100644 +--- a/hw/loongarch/ls7a_nb.c ++++ b/hw/loongarch/ls7a_nb.c +@@ -108,7 +108,6 @@ static const VMStateDescription vmstate_ls7a_pcie = { + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(dev, LS7APCIState), + VMSTATE_STRUCT(pm, LS7APCIState, 0, vmstate_ls7a_pm, LS7APCIPMRegs), +- VMSTATE_UINT32_ARRAY(regs, LS7APCIState, LS7A_REGS), + VMSTATE_END_OF_LIST() + } + }; +@@ -153,47 +152,6 @@ static void ls7a_pcie_realize(PCIDevice *dev, Error **errp) + qemu_register_reset(ls7a_reset, s); + } + +-static void pci_ls7a_config_write(void *opaque, hwaddr addr, +- uint64_t val, unsigned size) +-{ +- hwaddr tmp_addr; +- tmp_addr = addr & 0xffffff; +- +- pci_data_write(opaque, tmp_addr, val, size); +-} +- +-static uint64_t pci_ls7a_config_read(void *opaque, +- hwaddr addr, unsigned size) +-{ +- uint64_t val; +- hwaddr tmp_addr; +- +- tmp_addr = addr & 0xffffff; +- val = pci_data_read(opaque, tmp_addr, size); +- +- if (addr & 0x3c) { +- DPRINTF(TARGET_FMT_plx" val %lx\n", addr, val); +- } +- return val; +-} +- +-static const MemoryRegionOps pci_ls7a_config_ops = { +- .read = pci_ls7a_config_read, +- .write = pci_ls7a_config_write, +- /* Set to access 64bits data, because default to 32bits*/ +- .valid = { +- .min_access_size = 1, +- .max_access_size = 4, +- }, +- /* Set to access 64bits data, because default to 32bits*/ +- .impl = { +- .min_access_size = 1, +- .max_access_size = 4, +- }, +- .endianness = DEVICE_NATIVE_ENDIAN, +- +-}; +- + static AddressSpace *ls7a_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) + { + return &address_space_memory; +@@ -205,12 +163,9 @@ static PCIBus *pci_ls7a_init(MachineState *machine, DeviceState *dev, + LoongarchMachineState *lsms = LoongarchMACHINE(machine); + LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); + PCIExpressHost *e; +- SysBusDevice *sysbus; +- MemoryRegion *iomem = g_new(MemoryRegion, 1); + PCIHostState *phb; + + e = PCIE_HOST_BRIDGE(dev); +- sysbus = SYS_BUS_DEVICE(e); + phb = PCI_HOST_BRIDGE(e); + phb->bus = pci_register_root_bus(dev, "pcie.0", pci_ls7a_set_irq, + pci_ls7a_map_irq, pic, +@@ -220,10 +175,6 @@ static PCIBus *pci_ls7a_init(MachineState *machine, DeviceState *dev, + DPRINTF("------ %d\n", __LINE__); + + pci_bus_set_route_irq_fn(phb->bus, ls7a_route_intx_pin_to_irq); +- memory_region_init_io(iomem, NULL, &pci_ls7a_config_ops, phb->bus, +- "ls7a_pci_conf", HT1LO_PCICFG_SIZE); +- sysbus_init_mmio(sysbus, iomem); +- sysbus_mmio_map(sysbus, 0, lsmc->ht1lo_pcicfg_base); + + return phb->bus; + } +diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build +index 81ee99a02..47d886ddd 100644 +--- a/hw/loongarch/meson.build ++++ b/hw/loongarch/meson.build +@@ -9,6 +9,7 @@ loongarch_ss.add(files( + 'ipi.c', + 'apic.c', + 'iocsr.c', ++ 'sysbus-fdt.c', + )) + + hw_arch += {'loongarch64': loongarch_ss} +diff --git a/hw/loongarch/sysbus-fdt.c b/hw/loongarch/sysbus-fdt.c +new file mode 100644 +index 000000000..f750ad6b6 +--- /dev/null ++++ b/hw/loongarch/sysbus-fdt.c +@@ -0,0 +1,183 @@ ++/* ++ * Loongarch Platform Bus device tree generation helpers ++ * ++ * Copyright (c) 2014 Linaro Limited ++ * ++ * Authors: ++ * Alex Graf ++ * Eric Auger ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2 or later, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program. If not, see . ++ * ++ */ ++ ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include ++#include "qemu/error-report.h" ++#include "sysemu/device_tree.h" ++#include "hw/platform-bus.h" ++#include "hw/display/ramfb.h" ++#include "hw/loongarch/sysbus-fdt.h" ++#include "sysemu/tpm.h" ++ ++/* ++ * internal struct that contains the information to create dynamic ++ * sysbus device node ++ */ ++typedef struct PlatformBusFDTData { ++ void *fdt; /* device tree handle */ ++ int irq_start; /* index of the first IRQ usable by platform bus devices */ ++ const char *pbus_node_name; /* name of the platform bus node */ ++ PlatformBusDevice *pbus; ++} PlatformBusFDTData; ++ ++/* struct that allows to match a device and create its FDT node */ ++typedef struct BindingEntry { ++ const char *typename; ++ const char *compat; ++ int (*add_fn)(SysBusDevice *sbdev, void *opaque); ++ bool (*match_fn)(SysBusDevice *sbdev, const struct BindingEntry *combo); ++} BindingEntry; ++ ++ ++ ++static int no_fdt_node(SysBusDevice *sbdev, void *opaque) ++{ ++ return 0; ++} ++ ++/* Device type based matching */ ++static bool type_match(SysBusDevice *sbdev, const BindingEntry *entry) ++{ ++ return !strcmp(object_get_typename(OBJECT(sbdev)), entry->typename); ++} ++ ++#define TYPE_BINDING(type, add_fn) {(type), NULL, (add_fn), NULL} ++ ++#ifdef CONFIG_TPM ++/* ++ * add_tpm_tis_fdt_node: Create a DT node for TPM TIS ++ * ++ * See kernel documentation: ++ * Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt ++ * Optional interrupt for command completion is not exposed ++ */ ++static int add_tpm_tis_fdt_node(SysBusDevice *sbdev, void *opaque) ++{ ++ PlatformBusFDTData *data = opaque; ++ PlatformBusDevice *pbus = data->pbus; ++ void *fdt = data->fdt; ++ const char *parent_node = data->pbus_node_name; ++ char *nodename; ++ uint32_t reg_attr[2]; ++ uint64_t mmio_base; ++ ++ mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); ++ nodename = g_strdup_printf("%s/tpm_tis@%" PRIx64, parent_node, mmio_base); ++ qemu_fdt_add_subnode(fdt, nodename); ++ ++ qemu_fdt_setprop_string(fdt, nodename, "compatible", "tcg,tpm-tis-mmio"); ++ ++ reg_attr[0] = cpu_to_be32(mmio_base); ++ reg_attr[1] = cpu_to_be32(0x5000); ++ qemu_fdt_setprop(fdt, nodename, "reg", reg_attr, 2 * sizeof(uint32_t)); ++ ++ g_free(nodename); ++ ++ return 0; ++} ++#endif ++ ++/* list of supported dynamic sysbus bindings */ ++static const BindingEntry bindings[] = { ++#ifdef CONFIG_TPM ++ TYPE_BINDING(TYPE_TPM_TIS_SYSBUS, add_tpm_tis_fdt_node), ++#endif ++ TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node), ++ TYPE_BINDING("", NULL), /* last element */ ++}; ++ ++/* Generic Code */ ++ ++/** ++ * add_fdt_node - add the device tree node of a dynamic sysbus device ++ * ++ * @sbdev: handle to the sysbus device ++ * @opaque: handle to the PlatformBusFDTData ++ * ++ * Checks the sysbus type belongs to the list of device types that ++ * are dynamically instantiable and if so call the node creation ++ * function. ++ */ ++static void add_fdt_node(SysBusDevice *sbdev, void *opaque) ++{ ++ int i, ret; ++ ++ for (i = 0; i < ARRAY_SIZE(bindings); i++) { ++ const BindingEntry *iter = &bindings[i]; ++ ++ if (type_match(sbdev, iter)) { ++ if (!iter->match_fn || iter->match_fn(sbdev, iter)) { ++ ret = iter->add_fn(sbdev, opaque); ++ assert(!ret); ++ return; ++ } ++ } ++ } ++ error_report("Device %s can not be dynamically instantiated", ++ qdev_fw_name(DEVICE(sbdev))); ++ exit(1); ++} ++ ++void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr, ++ hwaddr bus_size, int irq_start) ++{ ++ const char platcomp[] = "qemu,platform\0simple-bus"; ++ PlatformBusDevice *pbus; ++ DeviceState *dev; ++ gchar *node; ++ ++ assert(fdt); ++ ++ node = g_strdup_printf("/platform@%"PRIx64, addr); ++ ++ /* Create a /platform node that we can put all devices into */ ++ qemu_fdt_add_subnode(fdt, node); ++ qemu_fdt_setprop(fdt, node, "compatible", platcomp, sizeof(platcomp)); ++ ++ /* ++ * Our platform bus region is less than 32bits, so 1 cell is enough for ++ * address and size ++ */ ++ qemu_fdt_setprop_cells(fdt, node, "#size-cells", 1); ++ qemu_fdt_setprop_cells(fdt, node, "#address-cells", 1); ++ qemu_fdt_setprop_cells(fdt, node, "ranges", 0, addr >> 32, addr, bus_size); ++ if (intc != NULL) { ++ qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", intc); ++ } ++ dev = qdev_find_recursive(sysbus_get_default(), TYPE_PLATFORM_BUS_DEVICE); ++ pbus = PLATFORM_BUS_DEVICE(dev); ++ ++ PlatformBusFDTData data = { ++ .fdt = fdt, ++ .irq_start = irq_start, ++ .pbus_node_name = node, ++ .pbus = pbus, ++ }; ++ ++ /* Loop through all dynamic sysbus devices and create their node */ ++ foreach_dynamic_sysbus_device(add_fdt_node, &data); ++ ++ g_free(node); ++} +diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h +index 0886ed52a..b8f28e330 100644 +--- a/include/hw/loongarch/larch.h ++++ b/include/hw/loongarch/larch.h +@@ -64,7 +64,6 @@ typedef struct LoongarchMachineClass { + uint64_t ht_control_regs_base; + uint64_t hpet_mmio_addr; + uint64_t smbus_cfg_base; +- uint64_t ht1lo_pcicfg_base; + uint64_t pciecfg_base; + uint64_t ls7a_ioapic_reg_base; + uint32_t node_shift; +@@ -103,6 +102,7 @@ typedef struct LoongarchMachineState { + void *fdt; + int fdt_size; + unsigned int hotpluged_cpu_num; ++ DeviceState *platform_bus_dev; + OnOffAuto acpi; + char *oem_id; + char *oem_table_id; +@@ -159,5 +159,4 @@ bool loongarch_is_acpi_enabled(LoongarchMachineState *vms); + void ls7a_madt_cpu_entry(AcpiDeviceIf *adev, int uid, + const CPUArchIdList *apic_ids, GArray *entry, bool force_enabled); + void slave_cpu_reset(void *opaque); +-extern uint64_t host_cpufreq; + #endif +diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h +index 686af763a..63a070296 100644 +--- a/include/hw/loongarch/ls7a.h ++++ b/include/hw/loongarch/ls7a.h +@@ -39,44 +39,33 @@ + #define ACPI_IO_SIZE (LS7A_ACPI_IO_SIZE) + #define ACPI_SCI_IRQ (LS7A_SCI_IRQ) + +-#define LS3A5K_ISA_IO_BASE 0x18000000UL +-#define LS_ISA_MEM_BASE 0x40000000 +-#define LS3A5K_HT1LO_PCICFG_BASE 0x1a000000 +-#define HT1LO_PCICFG_SIZE 0x02000000 ++#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000 ++#define VIRT_PLATFORM_BUS_SIZE 0x02000000 ++#define VIRT_PLATFORM_BUS_NUM_IRQS 2 ++#define VIRT_PLATFORM_BUS_IRQ (LOONGARCH_PCH_IRQ_BASE + 5) ++ ++#define LS3A5K_ISA_IO_BASE 0x18000000UL + #define LS_BIOS_BASE 0x1c000000 + #define LS_BIOS_VAR_BASE 0x1c3a0000 +-#define LS_BIOS_SIZE (4 * 1024 * 1024) +- +-#define FW_CFG_ADDR 0x1e020000 +-#define LS7A_REG_BASE 0x1FE00000 +-#define LS7A_PCICONFIG_BASE (LS7A_REG_BASE + 0x30) +-#define LS7A_PCICONFIG_SIZE (0x100) +-#define LS7A_INTERNAL_REG_BASE (LS7A_REG_BASE + 0x100) +-#define LS7A_INTERNAL_REG_SIZE (0xE0) +-#define LS7A_REGS (0xE0 >> 2) +-#define LS7A_UART_BASE 0x1fe001e0 +-#define LS7A_UART_LEN 0x8 +- +-#define LS_FDT_BASE 0x1c400000 +-#define LS_FDT_SIZE 0x100000 +- +-#define LS_PCIECFG_BASE 0x20000000 +-#define LS_PCIECFG_SIZE 0x08000000 +-#define MSI_ADDR_LOW 0x2FF00000 +-#define MSI_ADDR_HI 0x0 +- ++#define LS_BIOS_SIZE (4 * 1024 * 1024) ++#define LS_FDT_BASE 0x1c400000 ++#define LS_FDT_SIZE 0x00100000 ++ ++#define FW_CFG_ADDR 0x1e020000 ++#define LS7A_REG_BASE 0x1FE00000 ++#define LS7A_UART_BASE 0x1fe001e0 ++#define LS7A_UART_LEN 0x8 + #define SMP_GIPI_MAILBOX 0x1f000000ULL +-#define CORE0_STATUS_OFF 0x000 +-#define CORE0_EN_OFF 0x004 +-#define CORE0_SET_OFF 0x008 +-#define CORE0_CLEAR_OFF 0x00c +-#define CORE0_BUF_20 0x020 +-#define CORE0_BUF_28 0x028 +-#define CORE0_BUF_30 0x030 +-#define CORE0_BUF_38 0x038 +-#define CORE0_IPI_SEND 0x040 +-#define CORE0_MAIL_SEND 0x048 +- ++#define CORE0_STATUS_OFF 0x000 ++#define CORE0_EN_OFF 0x004 ++#define CORE0_SET_OFF 0x008 ++#define CORE0_CLEAR_OFF 0x00c ++#define CORE0_BUF_20 0x020 ++#define CORE0_BUF_28 0x028 ++#define CORE0_BUF_30 0x030 ++#define CORE0_BUF_38 0x038 ++#define CORE0_IPI_SEND 0x040 ++#define CORE0_MAIL_SEND 0x048 + #define INT_ROUTER_REGS_BASE 0x1fe01400UL + #define INT_ROUTER_REGS_SIZE 0x100 + #define INT_ROUTER_REGS_SYS_INT0 0x00 +@@ -121,6 +110,14 @@ + #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; +@@ -131,7 +128,6 @@ struct LS7APCIState { + PCIDevice dev; + + LS7APCIEHost *pciehost; +- uint32_t regs[LS7A_REGS]; + + /* LS7A registers */ + MemoryRegion iomem; +diff --git a/include/hw/loongarch/sysbus-fdt.h b/include/hw/loongarch/sysbus-fdt.h +new file mode 100644 +index 000000000..340c382cd +--- /dev/null ++++ b/include/hw/loongarch/sysbus-fdt.h +@@ -0,0 +1,37 @@ ++/* ++ * Dynamic sysbus device tree node generation API ++ * ++ * Copyright Linaro Limited, 2014 ++ * ++ * Authors: ++ * Alex Graf ++ * Eric Auger ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2 or later, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program. If not, see . ++ * ++ */ ++ ++#ifndef HW_ARM_SYSBUS_FDT_H ++#define HW_ARM_SYSBUS_FDT_H ++ ++#include "exec/hwaddr.h" ++ ++/** ++ * platform_bus_add_all_fdt_nodes - create all the platform bus nodes ++ * ++ * builds the parent platform bus node and all the nodes of dynamic ++ * sysbus devices attached to it. ++ */ ++void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr, ++ hwaddr bus_size, int irq_start); ++#endif +diff --git a/target/Kconfig b/target/Kconfig +index a8d6cb1e9..b2abc7b60 100644 +--- a/target/Kconfig ++++ b/target/Kconfig +@@ -4,6 +4,7 @@ source avr/Kconfig + source cris/Kconfig + source hppa/Kconfig + source i386/Kconfig ++source loongarch64/Kconfig + source m68k/Kconfig + source microblaze/Kconfig + source mips/Kconfig +diff --git a/target/loongarch64/Kconfig b/target/loongarch64/Kconfig +new file mode 100644 +index 000000000..46b26b1a8 +--- /dev/null ++++ b/target/loongarch64/Kconfig +@@ -0,0 +1,2 @@ ++config LOONGARCH64 ++ bool +diff --git a/target/loongarch64/arch_dump.c b/target/loongarch64/arch_dump.c +new file mode 100644 +index 000000000..9fb43b33d +--- /dev/null ++++ b/target/loongarch64/arch_dump.c +@@ -0,0 +1,175 @@ ++/* Support for writing ELF notes for RM architectures ++ * ++ * Copyright (C) 2015 Red Hat Inc. ++ * ++ * Author: Andrew Jones ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, see . ++ */ ++ ++#include "qemu/osdep.h" ++#include "cpu.h" ++#include "elf.h" ++#include "sysemu/dump.h" ++#include "internal.h" ++ ++/* struct user_pt_regs from arch/loongarch/include/uapi/asm/ptrace.h */ ++struct loongarch_user_regs { ++ uint64_t gpr[32]; ++ uint64_t lo; ++ uint64_t hi; ++ uint64_t csr_era; ++ uint64_t csr_badvaddr; ++ uint64_t csr_crmd; ++ uint64_t csr_ecfg; ++ uint64_t pad[7]; ++} QEMU_PACKED; ++ ++QEMU_BUILD_BUG_ON(sizeof(struct loongarch_user_regs) != 360); ++ ++/* struct elf_prstatus from include/uapi/linux/elfcore.h */ ++struct loongarch_elf_prstatus { ++ char pad1[32]; /* 32 == offsetof(struct elf_prstatus, pr_pid) */ ++ uint32_t pr_pid; ++ char pad2[76]; /* 76 == offsetof(struct elf_prstatus, pr_reg) - ++ offsetof(struct elf_prstatus, pr_ppid) */ ++ struct loongarch_user_regs pr_reg; ++ uint32_t pr_fpvalid; ++ char pad3[4]; ++} QEMU_PACKED; ++ ++QEMU_BUILD_BUG_ON(sizeof(struct loongarch_elf_prstatus) != 480); ++ ++/* struct user_fpsimd_state from arch/arm64/include/uapi/asm/ptrace.h ++ * ++ * While the vregs member of user_fpsimd_state is of type __uint128_t, ++ * QEMU uses an array of uint64_t, where the high half of the 128-bit ++ * value is always in the 2n+1'th index. Thus we also break the 128- ++ * bit values into two halves in this reproduction of user_fpsimd_state. ++ */ ++ ++struct loongarch_fpu_struct { ++ uint64_t fpr[32]; ++ unsigned int fir; ++ unsigned int fcsr; ++} QEMU_PACKED; ++ ++QEMU_BUILD_BUG_ON(sizeof(struct loongarch_fpu_struct) != 264); ++ ++struct loongarch_note { ++ Elf64_Nhdr hdr; ++ char name[8]; /* align_up(sizeof("CORE"), 4) */ ++ union { ++ struct loongarch_elf_prstatus prstatus; ++ struct loongarch_fpu_struct fpu; ++ }; ++} QEMU_PACKED; ++ ++#define LOONGARCH_NOTE_HEADER_SIZE offsetof(struct loongarch_note, prstatus) ++#define LOONGARCH_PRSTATUS_NOTE_SIZE (LOONGARCH_NOTE_HEADER_SIZE + \ ++ sizeof(struct loongarch_elf_prstatus)) ++#define LOONGARCH_PRFPREG_NOTE_SIZE (LOONGARCH_NOTE_HEADER_SIZE + \ ++ sizeof(struct loongarch_fpu_struct)) ++ ++static void loongarch_note_init(struct loongarch_note *note, DumpState *s, ++ const char *name, Elf64_Word namesz, ++ Elf64_Word type, Elf64_Word descsz) ++{ ++ memset(note, 0, sizeof(*note)); ++ ++ note->hdr.n_namesz = cpu_to_dump32(s, namesz); ++ note->hdr.n_descsz = cpu_to_dump32(s, descsz); ++ note->hdr.n_type = cpu_to_dump32(s, type); ++ ++ memcpy(note->name, name, namesz); ++} ++ ++static int loongarch_write_elf64_fprpreg(WriteCoreDumpFunction f, ++ CPULOONGARCHState *env, int cpuid, ++ DumpState *s) ++{ ++ struct loongarch_note note; ++ int ret, i; ++ ++ loongarch_note_init(¬e, s, "CORE", 5, NT_PRFPREG, sizeof(note.fpu)); ++ ++ note.fpu.fcsr = cpu_to_dump64(s, env->active_fpu.fcsr0); ++ ++ for (i = 0; i < 32; ++i) { ++ note.fpu.fpr[i] = cpu_to_dump64(s, env->active_fpu.fpr[i].fd); ++ } ++ ++ ret = f(¬e, LOONGARCH_PRFPREG_NOTE_SIZE, s); ++ if (ret < 0) { ++ return -1; ++ } ++ ++ return 0; ++} ++ ++int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, ++ int cpuid, void *opaque) ++{ ++ struct loongarch_note note; ++ CPULOONGARCHState *env = &LOONGARCH_CPU(cs)->env; ++ DumpState *s = opaque; ++ int ret, i; ++ ++ loongarch_note_init(¬e, s, "CORE", 5, NT_PRSTATUS, sizeof(note.prstatus)); ++ ++ note.prstatus.pr_pid = cpu_to_dump32(s, cpuid); ++ note.prstatus.pr_fpvalid = cpu_to_dump32(s, 1); ++ ++ for (i = 0; i < 32; ++i) { ++ note.prstatus.pr_reg.gpr[i] = cpu_to_dump64(s, env->active_tc.gpr[i]); ++ } ++ note.prstatus.pr_reg.csr_era = cpu_to_dump64(s, env->CSR_ERA); ++ note.prstatus.pr_reg.csr_badvaddr = cpu_to_dump64(s, env->CSR_BADV); ++ note.prstatus.pr_reg.csr_crmd = cpu_to_dump64(s, env->CSR_CRMD); ++ note.prstatus.pr_reg.csr_ecfg = cpu_to_dump64(s, env->CSR_ECFG); ++ ++ ret = f(¬e, LOONGARCH_PRSTATUS_NOTE_SIZE, s); ++ if (ret < 0) { ++ return -1; ++ } ++ ++ ret = loongarch_write_elf64_fprpreg(f, env, cpuid, s); ++ if (ret < 0) { ++ return -1; ++ } ++ ++ return ret; ++} ++ ++int cpu_get_dump_info(ArchDumpInfo *info, ++ const GuestPhysBlockList *guest_phys_blocks) ++{ ++ info->d_machine = EM_LOONGARCH; ++ info->d_endian = ELFDATA2LSB; ++ info->d_class = ELFCLASS64; ++ ++ return 0; ++} ++ ++ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) ++{ ++ size_t note_size = 0; ++ ++ if (class == ELFCLASS64) { ++ note_size = LOONGARCH_PRSTATUS_NOTE_SIZE + LOONGARCH_PRFPREG_NOTE_SIZE; ++ } ++ ++ return note_size * nr_cpus; ++} ++ +diff --git a/target/loongarch64/cpu-csr.h b/target/loongarch64/cpu-csr.h +new file mode 100644 +index 000000000..e549bb46b +--- /dev/null ++++ b/target/loongarch64/cpu-csr.h +@@ -0,0 +1,869 @@ ++#ifndef _CPU_CSR_H_ ++#define _CPU_CSR_H_ ++ ++/* basic CSR register */ ++#define LOONGARCH_CSR_CRMD 0x0 /* 32 current mode info */ ++#define CSR_CRMD_DACM_SHIFT 7 ++#define CSR_CRMD_DACM_WIDTH 2 ++#define CSR_CRMD_DACM (0x3UL << CSR_CRMD_DACM_SHIFT) ++#define CSR_CRMD_DACF_SHIFT 5 ++#define CSR_CRMD_DACF_WIDTH 2 ++#define CSR_CRMD_DACF (0x3UL << CSR_CRMD_DACF_SHIFT) ++#define CSR_CRMD_PG_SHIFT 4 ++#define CSR_CRMD_PG (0x1UL << CSR_CRMD_PG_SHIFT) ++#define CSR_CRMD_DA_SHIFT 3 ++#define CSR_CRMD_DA (0x1UL << CSR_CRMD_DA_SHIFT) ++#define CSR_CRMD_IE_SHIFT 2 ++#define CSR_CRMD_IE (0x1UL << CSR_CRMD_IE_SHIFT) ++#define CSR_CRMD_PLV_SHIFT 0 ++#define CSR_CRMD_PLV_WIDTH 2 ++#define CSR_CRMD_PLV (0x3UL << CSR_CRMD_PLV_SHIFT) ++ ++#define PLV_USER 3 ++#define PLV_KERN 0 ++#define PLV_MASK 0x3 ++ ++#define LOONGARCH_CSR_PRMD 0x1 /* 32 prev-exception mode info */ ++#define CSR_PRMD_PIE_SHIFT 2 ++#define CSR_PRMD_PIE (0x1UL << CSR_PRMD_PIE_SHIFT) ++#define CSR_PRMD_PPLV_SHIFT 0 ++#define CSR_PRMD_PPLV_WIDTH 2 ++#define CSR_PRMD_PPLV (0x3UL << CSR_PRMD_PPLV_SHIFT) ++ ++#define LOONGARCH_CSR_EUEN 0x2 /* 32 coprocessor enable */ ++#define CSR_EUEN_LBTEN_SHIFT 3 ++#define CSR_EUEN_LBTEN (0x1UL << CSR_EUEN_LBTEN_SHIFT) ++#define CSR_EUEN_LASXEN_SHIFT 2 ++#define CSR_EUEN_LASXEN (0x1UL << CSR_EUEN_LASXEN_SHIFT) ++#define CSR_EUEN_LSXEN_SHIFT 1 ++#define CSR_EUEN_LSXEN (0x1UL << CSR_EUEN_LSXEN_SHIFT) ++#define CSR_EUEN_FPEN_SHIFT 0 ++#define CSR_EUEN_FPEN (0x1UL << CSR_EUEN_FPEN_SHIFT) ++ ++#define LOONGARCH_CSR_MISC 0x3 /* 32 misc config */ ++ ++#define LOONGARCH_CSR_ECFG 0x4 /* 32 exception config */ ++#define CSR_ECFG_VS_SHIFT 16 ++#define CSR_ECFG_VS_WIDTH 3 ++#define CSR_ECFG_VS (0x7UL << CSR_ECFG_VS_SHIFT) ++#define CSR_ECFG_IM_SHIFT 0 ++#define CSR_ECFG_IM_WIDTH 13 ++#define CSR_ECFG_IM (0x1fffUL << CSR_ECFG_IM_SHIFT) ++ ++#define CSR_ECFG_IPMASK 0x00001fff ++ ++#define LOONGARCH_CSR_ESTAT 0x5 /* Exception status */ ++#define CSR_ESTAT_ESUBCODE_SHIFT 22 ++#define CSR_ESTAT_ESUBCODE_WIDTH 9 ++#define CSR_ESTAT_ESUBCODE (0x1ffULL << CSR_ESTAT_ESUBCODE_SHIFT) ++#define CSR_ESTAT_EXC_SH 16 ++#define CSR_ESTAT_EXC_WIDTH 5 ++#define CSR_ESTAT_EXC (0x1fULL << CSR_ESTAT_EXC_SH) ++#define CSR_ESTAT_IS_SHIFT 0 ++#define CSR_ESTAT_IS_WIDTH 15 ++#define CSR_ESTAT_IS (0x7fffULL << CSR_ESTAT_IS_SHIFT) ++ ++#define CSR_ESTAT_IPMASK 0x00001fff ++ ++#define EXCODE_IP 64 ++#define EXCCODE_RSV 0 ++#define EXCCODE_TLBL 1 ++#define EXCCODE_TLBS 2 ++#define EXCCODE_TLBI 3 ++#define EXCCODE_MOD 4 ++#define EXCCODE_TLBRI 5 ++#define EXCCODE_TLBXI 6 ++#define EXCCODE_TLBPE 7 ++#define EXCCODE_ADE 8 ++#define EXCCODE_UNALIGN 9 ++#define EXCCODE_OOB 10 ++#define EXCCODE_SYS 11 ++#define EXCCODE_BP 12 ++#define EXCCODE_RI 13 ++#define EXCCODE_IPE 14 ++#define EXCCODE_FPDIS 15 ++#define EXCCODE_LSXDIS 16 ++#define EXCCODE_LASXDIS 17 ++#define EXCCODE_FPE 18 ++#define EXCCODE_WATCH 19 ++#define EXCCODE_BTDIS 20 ++#define EXCCODE_BTE 21 ++#define EXCCODE_PSI 22 ++#define EXCCODE_HYP 23 ++#define EXCCODE_FC 24 ++#define EXCCODE_SE 25 ++ ++#define LOONGARCH_CSR_ERA 0x6 /* 64 error PC */ ++ ++#define LOONGARCH_CSR_BADV 0x7 /* 64 bad virtual address */ ++ ++#define LOONGARCH_CSR_BADI 0x8 /* 32 bad instruction */ ++ ++#define LOONGARCH_CSR_EEPN 0xc /* 64 exception enter base address */ ++#define LOONGARCH_EEPN_CPUID (0x3ffULL << 0) ++ ++#define CU_FPE 1 ++#define CU_LSXE (1 << 1) ++#define CU_LASXE (1 << 2) ++#define CU_LBTE (1 << 3) ++ ++/* TLB related CSR register : start with TLB if no pagewalk */ ++/* 32 TLB Index, EHINV, PageSize, is_gtlb */ ++#define LOONGARCH_CSR_TLBIDX 0x10 ++#define CSR_TLBIDX_EHINV_SHIFT 31 ++#define CSR_TLBIDX_EHINV (0x1ULL << CSR_TLBIDX_EHINV_SHIFT) ++#define CSR_TLBIDX_PS_SHIFT 24 ++#define CSR_TLBIDX_PS_WIDTH 6 ++#define CSR_TLBIDX_PS (0x3fULL << CSR_TLBIDX_PS_SHIFT) ++#define CSR_TLBIDX_IDX_SHIFT 0 ++#define CSR_TLBIDX_IDX_WIDTH 12 ++#define CSR_TLBIDX_IDX (0xfffULL << CSR_TLBIDX_IDX_SHIFT) ++#define CSR_TLBIDX_SIZEM 0x3f000000 ++#define CSR_TLBIDX_SIZE CSR_TLBIDX_PS_SHIFT ++#define CSR_TLBIDX_IDXM 0xfff ++ ++#define LOONGARCH_CSR_TLBEHI 0x11 /* 64 TLB EntryHi without ASID */ ++ ++#define LOONGARCH_CSR_TLBELO0 0x12 /* 64 TLB EntryLo0 */ ++#define CSR_TLBLO0_RPLV_SHIFT 63 ++#define CSR_TLBLO0_RPLV (0x1ULL << CSR_TLBLO0_RPLV_SHIFT) ++#define CSR_TLBLO0_XI_SHIFT 62 ++#define CSR_TLBLO0_XI (0x1ULL << CSR_TLBLO0_XI_SHIFT) ++#define CSR_TLBLO0_RI_SHIFT 61 ++#define CSR_TLBLO0_RI (0x1ULL << CSR_TLBLO0_RI_SHIFT) ++#define CSR_TLBLO0_PPN_SHIFT 12 ++#define CSR_TLBLO0_PPN_WIDTH 36 /* ignore lower 12bits */ ++#define CSR_TLBLO0_PPN (0xfffffffffULL << CSR_TLBLO0_PPN_SHIFT) ++#define CSR_TLBLO0_GLOBAL_SHIFT 6 ++#define CSR_TLBLO0_GLOBAL (0x1ULL << CSR_TLBLO0_GLOBAL_SHIFT) ++#define CSR_TLBLO0_CCA_SHIFT 4 ++#define CSR_TLBLO0_CCA_WIDTH 2 ++#define CSR_TLBLO0_CCA (0x3ULL << CSR_TLBLO0_CCA_SHIFT) ++#define CSR_TLBLO0_PLV_SHIFT 2 ++#define CSR_TLBLO0_PLV_WIDTH 2 ++#define CSR_TLBLO0_PLV (0x3ULL << CSR_TLBLO0_PLV_SHIFT) ++#define CSR_TLBLO0_WE_SHIFT 1 ++#define CSR_TLBLO0_WE (0x1ULL << CSR_TLBLO0_WE_SHIFT) ++#define CSR_TLBLO0_V_SHIFT 0 ++#define CSR_TLBLO0_V (0x1ULL << CSR_TLBLO0_V_SHIFT) ++ ++#define LOONGARCH_CSR_TLBELO1 0x13 /* 64 TLB EntryLo1 */ ++#define CSR_TLBLO1_RPLV_SHIFT 63 ++#define CSR_TLBLO1_RPLV (0x1ULL << CSR_TLBLO1_RPLV_SHIFT) ++#define CSR_TLBLO1_XI_SHIFT 62 ++#define CSR_TLBLO1_XI (0x1ULL << CSR_TLBLO1_XI_SHIFT) ++#define CSR_TLBLO1_RI_SHIFT 61 ++#define CSR_TLBLO1_RI (0x1ULL << CSR_TLBLO1_RI_SHIFT) ++#define CSR_TLBLO1_PPN_SHIFT 12 ++#define CSR_TLBLO1_PPN_WIDTH 36 /* ignore lower 12bits */ ++#define CSR_TLBLO1_PPN (0xfffffffffULL << CSR_TLBLO1_PPN_SHIFT) ++#define CSR_TLBLO1_GLOBAL_SHIFT 6 ++#define CSR_TLBLO1_GLOBAL (0x1ULL << CSR_TLBLO1_GLOBAL_SHIFT) ++#define CSR_TLBLO1_CCA_SHIFT 4 ++#define CSR_TLBLO1_CCA_WIDTH 2 ++#define CSR_TLBLO1_CCA (0x3ULL << CSR_TLBLO1_CCA_SHIFT) ++#define CSR_TLBLO1_PLV_SHIFT 2 ++#define CSR_TLBLO1_PLV_WIDTH 2 ++#define CSR_TLBLO1_PLV (0x3ULL << CSR_TLBLO1_PLV_SHIFT) ++#define CSR_TLBLO1_WE_SHIFT 1 ++#define CSR_TLBLO1_WE (0x1ULL << CSR_TLBLO1_WE_SHIFT) ++#define CSR_TLBLO1_V_SHIFT 0 ++#define CSR_TLBLO1_V (0x1ULL << CSR_TLBLO1_V_SHIFT) ++ ++#define LOONGARCH_ENTRYLO_RI (1ULL << 61) ++#define LOONGARCH_ENTRYLO_XI (1ULL << 62) ++ ++#define LOONGARCH_CSR_TLBWIRED 0x14 /* 32 TLB wired */ ++#define LOONGARCH_CSR_GTLBC 0x15 /* guest-related TLB */ ++#define CSR_GTLBC_RID_SHIFT 16 ++#define CSR_GTLBC_RID_WIDTH 8 ++#define CSR_GTLBC_RID (0xffULL << CSR_GTLBC_RID_SHIFT) ++#define CSR_GTLBC_TOTI_SHIFT 13 ++#define CSR_GTLBC_TOTI (0x1ULL << CSR_GTLBC_TOTI_SHIFT) ++#define CSR_GTLBC_USERID_SHIFT 12 ++#define CSR_GTLBC_USERID (0x1ULL << CSR_GTLBC_USERID_SHIFT) ++#define CSR_GTLBC_GMTLBSZ_SHIFT 0 ++#define CSR_GTLBC_GMTLBSZ_WIDTH 6 ++#define CSR_GTLBC_GMTLBSZ (0x3fULL << CSR_GTLBC_GVTLBSZ_SHIFT) ++ ++#define LOONGARCH_CSR_TRGP 0x16 /* guest-related TLB */ ++#define CSR_TRGP_RID_SHIFT 16 ++#define CSR_TRGP_RID_WIDTH 8 ++#define CSR_TRGP_RID (0xffULL << CSR_TRGP_RID_SHIFT) ++#define CSR_TRGP_GTLB_SHIFT 0 ++#define CSR_TRGP_GTLB (1 << CSR_TRGP_GTLB_SHIFT) ++ ++#define LOONGARCH_CSR_ASID 0x18 /* 64 ASID */ ++#define CSR_ASID_BIT_SHIFT 16 /* ASIDBits */ ++#define CSR_ASID_BIT_WIDTH 8 ++#define CSR_ASID_BIT (0xffULL << CSR_ASID_BIT_SHIFT) ++#define CSR_ASID_ASID_SHIFT 0 ++#define CSR_ASID_ASID_WIDTH 10 ++#define CSR_ASID_ASID (0x3ffULL << CSR_ASID_ASID_SHIFT) ++ ++/* 64 page table base address when badv[47] = 0 */ ++#define LOONGARCH_CSR_PGDL 0x19 ++/* 64 page table base address when badv[47] = 1 */ ++#define LOONGARCH_CSR_PGDH 0x1a ++ ++#define LOONGARCH_CSR_PGD 0x1b /* 64 page table base */ ++ ++#define LOONGARCH_CSR_PWCTL0 0x1c /* 64 PWCtl0 */ ++#define CSR_PWCTL0_PTEW_SHIFT 30 ++#define CSR_PWCTL0_PTEW_WIDTH 2 ++#define CSR_PWCTL0_PTEW (0x3ULL << CSR_PWCTL0_PTEW_SHIFT) ++#define CSR_PWCTL0_DIR1WIDTH_SHIFT 25 ++#define CSR_PWCTL0_DIR1WIDTH_WIDTH 5 ++#define CSR_PWCTL0_DIR1WIDTH (0x1fULL << CSR_PWCTL0_DIR1WIDTH_SHIFT) ++#define CSR_PWCTL0_DIR1BASE_SHIFT 20 ++#define CSR_PWCTL0_DIR1BASE_WIDTH 5 ++#define CSR_PWCTL0_DIR1BASE (0x1fULL << CSR_PWCTL0_DIR1BASE_SHIFT) ++#define CSR_PWCTL0_DIR0WIDTH_SHIFT 15 ++#define CSR_PWCTL0_DIR0WIDTH_WIDTH 5 ++#define CSR_PWCTL0_DIR0WIDTH (0x1fULL << CSR_PWCTL0_DIR0WIDTH_SHIFT) ++#define CSR_PWCTL0_DIR0BASE_SHIFT 10 ++#define CSR_PWCTL0_DIR0BASE_WIDTH 5 ++#define CSR_PWCTL0_DIR0BASE (0x1fULL << CSR_PWCTL0_DIR0BASE_SHIFT) ++#define CSR_PWCTL0_PTWIDTH_SHIFT 5 ++#define CSR_PWCTL0_PTWIDTH_WIDTH 5 ++#define CSR_PWCTL0_PTWIDTH (0x1fULL << CSR_PWCTL0_PTWIDTH_SHIFT) ++#define CSR_PWCTL0_PTBASE_SHIFT 0 ++#define CSR_PWCTL0_PTBASE_WIDTH 5 ++#define CSR_PWCTL0_PTBASE (0x1fULL << CSR_PWCTL0_PTBASE_SHIFT) ++ ++#define LOONGARCH_CSR_PWCTL1 0x1d /* 64 PWCtl1 */ ++#define CSR_PWCTL1_DIR3WIDTH_SHIFT 18 ++#define CSR_PWCTL1_DIR3WIDTH_WIDTH 5 ++#define CSR_PWCTL1_DIR3WIDTH (0x1fULL << CSR_PWCTL1_DIR3WIDTH_SHIFT) ++#define CSR_PWCTL1_DIR3BASE_SHIFT 12 ++#define CSR_PWCTL1_DIR3BASE_WIDTH 5 ++#define CSR_PWCTL1_DIR3BASE (0x1fULL << CSR_PWCTL0_DIR3BASE_SHIFT) ++#define CSR_PWCTL1_DIR2WIDTH_SHIFT 6 ++#define CSR_PWCTL1_DIR2WIDTH_WIDTH 5 ++#define CSR_PWCTL1_DIR2WIDTH (0x1fULL << CSR_PWCTL1_DIR2WIDTH_SHIFT) ++#define CSR_PWCTL1_DIR2BASE_SHIFT 0 ++#define CSR_PWCTL1_DIR2BASE_WIDTH 5 ++#define CSR_PWCTL1_DIR2BASE (0x1fULL << CSR_PWCTL0_DIR2BASE_SHIFT) ++ ++#define LOONGARCH_CSR_STLBPGSIZE 0x1e /* 64 */ ++#define CSR_STLBPGSIZE_PS_WIDTH 6 ++#define CSR_STLBPGSIZE_PS (0x3f) ++ ++#define LOONGARCH_CSR_RVACFG 0x1f ++#define CSR_RVACFG_RDVA_WIDTH 4 ++#define CSR_RVACFG_RDVA (0xf) ++ ++/* read only CSR register : start with CPU */ ++#define LOONGARCH_CSR_CPUID 0x20 /* 32 CPU core number */ ++#define CSR_CPUID_CID_WIDTH 9 ++#define CSR_CPUID_CID (0x1ff) ++ ++#define LOONGARCH_CSR_PRCFG1 0x21 /* 32 CPU info */ ++#define CSR_CONF1_VSMAX_SHIFT 12 ++#define CSR_CONF1_VSMAX_WIDTH 3 ++#define CSR_CONF1_VSMAX (7ULL << CSR_CONF1_VSMAX_SHIFT) ++/* stable timer bits - 1, 0x2f = 47*/ ++#define CSR_CONF1_TMRBITS_SHIFT 4 ++#define CSR_CONF1_TMRBITS_WIDTH 8 ++#define CSR_CONF1_TMRBITS (0xffULL << CSR_CONF1_TMRBITS_SHIFT) ++#define CSR_CONF1_KSNUM_SHIFT 0 ++#define CSR_CONF1_KSNUM_WIDTH 4 ++#define CSR_CONF1_KSNUM (0x8) ++ ++#define LOONGARCH_CSR_PRCFG2 0x22 ++#define CSR_CONF2_PGMASK_SUPP 0x3ffff000 ++ ++#define LOONGARCH_CSR_PRCFG3 0x23 ++#define CSR_CONF3_STLBIDX_SHIFT 20 ++#define CSR_CONF3_STLBIDX_WIDTH 6 ++#define CSR_CONF3_STLBIDX (0x3fULL << CSR_CONF3_STLBIDX_SHIFT) ++#define CSR_STLB_SETS 256 ++#define CSR_CONF3_STLBWAYS_SHIFT 12 ++#define CSR_CONF3_STLBWAYS_WIDTH 8 ++#define CSR_CONF3_STLBWAYS (0xffULL << CSR_CONF3_STLBWAYS_SHIFT) ++#define CSR_STLBWAYS_SIZE 8 ++#define CSR_CONF3_MTLBSIZE_SHIFT 4 ++#define CSR_CONF3_MTLBSIZE_WIDTH 8 ++#define CSR_CONF3_MTLBSIZE (0xffULL << CSR_CONF3_MTLBSIZE_SHIFT) ++/* mean VTLB 64 index */ ++#define CSR_MTLB_SIZE 64 ++#define CSR_CONF3_TLBORG_SHIFT 0 ++#define CSR_CONF3_TLBORG_WIDTH 4 ++#define CSR_CONF3_TLBORG (0xfULL << CSR_CONF3_TLBORG_SHIFT) ++/* mean use MTLB+STLB */ ++#define TLB_ORG 2 ++ ++/* Kscratch : start with KS */ ++#define LOONGARCH_CSR_KS0 0x30 /* 64 */ ++#define LOONGARCH_CSR_KS1 0x31 /* 64 */ ++#define LOONGARCH_CSR_KS2 0x32 /* 64 */ ++#define LOONGARCH_CSR_KS3 0x33 /* 64 */ ++#define LOONGARCH_CSR_KS4 0x34 /* 64 */ ++#define LOONGARCH_CSR_KS5 0x35 /* 64 */ ++#define LOONGARCH_CSR_KS6 0x36 /* 64 */ ++#define LOONGARCH_CSR_KS7 0x37 /* 64 */ ++#define LOONGARCH_CSR_KS8 0x38 /* 64 */ ++ ++/* timer : start with TM */ ++#define LOONGARCH_CSR_TMID 0x40 /* 32 timer ID */ ++ ++#define LOONGARCH_CSR_TCFG 0x41 /* 64 timer config */ ++#define CSR_TCFG_VAL_SHIFT 2 ++#define CSR_TCFG_VAL_WIDTH 48 ++#define CSR_TCFG_VAL (0x3fffffffffffULL << CSR_TCFG_VAL_SHIFT) ++#define CSR_TCFG_PERIOD_SHIFT 1 ++#define CSR_TCFG_PERIOD (0x1ULL << CSR_TCFG_PERIOD_SHIFT) ++#define CSR_TCFG_EN (0x1) ++ ++#define LOONGARCH_CSR_TVAL 0x42 /* 64 timer ticks remain */ ++ ++#define LOONGARCH_CSR_CNTC 0x43 /* 64 timer offset */ ++ ++#define LOONGARCH_CSR_TINTCLR 0x44 /* 64 timer interrupt clear */ ++#define CSR_TINTCLR_TI_SHIFT 0 ++#define CSR_TINTCLR_TI (1 << CSR_TINTCLR_TI_SHIFT) ++ ++/* guest : start with GST */ ++#define LOONGARCH_CSR_GSTAT 0x50 /* 32 basic guest info */ ++#define CSR_GSTAT_GID_SHIFT 16 ++#define CSR_GSTAT_GID_WIDTH 8 ++#define CSR_GSTAT_GID (0xffULL << CSR_GSTAT_GID_SHIFT) ++#define CSR_GSTAT_GIDBIT_SHIFT 4 ++#define CSR_GSTAT_GIDBIT_WIDTH 6 ++#define CSR_GSTAT_GIDBIT (0x3fULL << CSR_GSTAT_GIDBIT_SHIFT) ++#define CSR_GSTAT_PVM_SHIFT 1 ++#define CSR_GSTAT_PVM (0x1ULL << CSR_GSTAT_PVM_SHIFT) ++#define CSR_GSTAT_VM_SHIFT 0 ++#define CSR_GSTAT_VM (0x1ULL << CSR_GSTAT_VM_SHIFT) ++ ++#define LOONGARCH_CSR_GCFG 0x51 /* 32 guest config */ ++#define CSR_GCFG_GPERF_SHIFT 24 ++#define CSR_GCFG_GPERF_WIDTH 3 ++#define CSR_GCFG_GPERF (0x7ULL << CSR_GCFG_GPERF_SHIFT) ++#define CSR_GCFG_GCI_SHIFT 20 ++#define CSR_GCFG_GCI_WIDTH 2 ++#define CSR_GCFG_GCI (0x3ULL << CSR_GCFG_GCI_SHIFT) ++#define CSR_GCFG_GCI_ALL (0x0ULL << CSR_GCFG_GCI_SHIFT) ++#define CSR_GCFG_GCI_HIT (0x1ULL << CSR_GCFG_GCI_SHIFT) ++#define CSR_GCFG_GCI_SECURE (0x2ULL << CSR_GCFG_GCI_SHIFT) ++#define CSR_GCFG_GCIP_SHIFT 16 ++#define CSR_GCFG_GCIP (0xfULL << CSR_GCFG_GCIP_SHIFT) ++#define CSR_GCFG_GCIP_ALL (0x1ULL << CSR_GCFG_GCIP_SHIFT) ++#define CSR_GCFG_GCIP_HIT (0x1ULL << (CSR_GCFG_GCIP_SHIFT + 1)) ++#define CSR_GCFG_GCIP_SECURE (0x1ULL << (CSR_GCFG_GCIP_SHIFT + 2)) ++#define CSR_GCFG_TORU_SHIFT 15 ++#define CSR_GCFG_TORU (0x1ULL << CSR_GCFG_TORU_SHIFT) ++#define CSR_GCFG_TORUP_SHIFT 14 ++#define CSR_GCFG_TORUP (0x1ULL << CSR_GCFG_TORUP_SHIFT) ++#define CSR_GCFG_TOP_SHIFT 13 ++#define CSR_GCFG_TOP (0x1ULL << CSR_GCFG_TOP_SHIFT) ++#define CSR_GCFG_TOPP_SHIFT 12 ++#define CSR_GCFG_TOPP (0x1ULL << CSR_GCFG_TOPP_SHIFT) ++#define CSR_GCFG_TOE_SHIFT 11 ++#define CSR_GCFG_TOE (0x1ULL << CSR_GCFG_TOE_SHIFT) ++#define CSR_GCFG_TOEP_SHIFT 10 ++#define CSR_GCFG_TOEP (0x1ULL << CSR_GCFG_TOEP_SHIFT) ++#define CSR_GCFG_TIT_SHIFT 9 ++#define CSR_GCFG_TIT (0x1ULL << CSR_GCFG_TIT_SHIFT) ++#define CSR_GCFG_TITP_SHIFT 8 ++#define CSR_GCFG_TITP (0x1ULL << CSR_GCFG_TITP_SHIFT) ++#define CSR_GCFG_SIT_SHIFT 7 ++#define CSR_GCFG_SIT (0x1ULL << CSR_GCFG_SIT_SHIFT) ++#define CSR_GCFG_SITP_SHIFT 6 ++#define CSR_GCFG_SITP (0x1ULL << CSR_GCFG_SITP_SHIFT) ++#define CSR_GCFG_CACTRL_SHIFT 4 ++#define CSR_GCFG_CACTRL_WIDTH 2 ++#define CSR_GCFG_CACTRL (0x3ULL << CSR_GCFG_CACTRL_SHIFT) ++#define CSR_GCFG_CACTRL_GUEST (0x0ULL << CSR_GCFG_CACTRL_SHIFT) ++#define CSR_GCFG_CACTRL_ROOT (0x1ULL << CSR_GCFG_CACTRL_SHIFT) ++#define CSR_GCFG_CACTRL_NEST (0x2ULL << CSR_GCFG_CACTRL_SHIFT) ++#define CSR_GCFG_CCCP_WIDTH 4 ++#define CSR_GCFG_CCCP (0xf) ++#define CSR_GCFG_CCCP_GUEST (0x1ULL << 0) ++#define CSR_GCFG_CCCP_ROOT (0x1ULL << 1) ++#define CSR_GCFG_CCCP_NEST (0x1ULL << 2) ++ ++#define LOONGARCH_CSR_GINTC 0x52 /* 64 guest exception control */ ++#define CSR_GINTC_HC_SHIFT 16 ++#define CSR_GINTC_HC_WIDTH 8 ++#define CSR_GINTC_HC (0xffULL << CSR_GINTC_HC_SHIFT) ++#define CSR_GINTC_PIP_SHIFT 8 ++#define CSR_GINTC_PIP_WIDTH 8 ++#define CSR_GINTC_PIP (0xffULL << CSR_GINTC_PIP_SHIFT) ++#define CSR_GINTC_VIP_SHIFT 0 ++#define CSR_GINTC_VIP_WIDTH 8 ++#define CSR_GINTC_VIP (0xff) ++ ++#define LOONGARCH_CSR_GCNTC 0x53 /* 64 guest timer offset */ ++ ++/* LLBCTL */ ++#define LOONGARCH_CSR_LLBCTL 0x60 /* 32 csr number to be changed */ ++#define CSR_LLBCTL_ROLLB_SHIFT 0 ++#define CSR_LLBCTL_ROLLB (1ULL << CSR_LLBCTL_ROLLB_SHIFT) ++#define CSR_LLBCTL_WCLLB_SHIFT 1 ++#define CSR_LLBCTL_WCLLB (1ULL << CSR_LLBCTL_WCLLB_SHIFT) ++#define CSR_LLBCTL_KLO_SHIFT 2 ++#define CSR_LLBCTL_KLO (1ULL << CSR_LLBCTL_KLO_SHIFT) ++ ++/* implement dependent */ ++#define LOONGARCH_CSR_IMPCTL1 0x80 /* 32 loongarch config */ ++#define CSR_MISPEC_SHIFT 20 ++#define CSR_MISPEC_WIDTH 8 ++#define CSR_MISPEC (0xffULL << CSR_MISPEC_SHIFT) ++#define CSR_SSEN_SHIFT 18 ++#define CSR_SSEN (1ULL << CSR_SSEN_SHIFT) ++#define CSR_SCRAND_SHIFT 17 ++#define CSR_SCRAND (1ULL << CSR_SCRAND_SHIFT) ++#define CSR_LLEXCL_SHIFT 16 ++#define CSR_LLEXCL (1ULL << CSR_LLEXCL_SHIFT) ++#define CSR_DISVC_SHIFT 15 ++#define CSR_DISVC (1ULL << CSR_DISVC_SHIFT) ++#define CSR_VCLRU_SHIFT 14 ++#define CSR_VCLRU (1ULL << CSR_VCLRU_SHIFT) ++#define CSR_DCLRU_SHIFT 13 ++#define CSR_DCLRU (1ULL << CSR_DCLRU_SHIFT) ++#define CSR_FASTLDQ_SHIFT 12 ++#define CSR_FASTLDQ (1ULL << CSR_FASTLDQ_SHIFT) ++#define CSR_USERCAC_SHIFT 11 ++#define CSR_USERCAC (1ULL << CSR_USERCAC_SHIFT) ++#define CSR_ANTI_MISPEC_SHIFT 10 ++#define CSR_ANTI_MISPEC (1ULL << CSR_ANTI_MISPEC_SHIFT) ++#define CSR_ANTI_FLUSHSFB_SHIFT 9 ++#define CSR_ANTI_FLUSHSFB (1ULL << CSR_ANTI_FLUSHSFB_SHIFT) ++#define CSR_STFILL_SHIFT 8 ++#define CSR_STFILL (1ULL << CSR_STFILL_SHIFT) ++#define CSR_LIFEP_SHIFT 7 ++#define CSR_LIFEP (1ULL << CSR_LIFEP_SHIFT) ++#define CSR_LLSYNC_SHIFT 6 ++#define CSR_LLSYNC (1ULL << CSR_LLSYNC_SHIFT) ++#define CSR_BRBTDIS_SHIFT 5 ++#define CSR_BRBTDIS (1ULL << CSR_BRBTDIS_SHIFT) ++#define CSR_RASDIS_SHIFT 4 ++#define CSR_RASDIS (1ULL << CSR_RASDIS_SHIFT) ++#define CSR_STPRE_SHIFT 2 ++#define CSR_STPRE_WIDTH 2 ++#define CSR_STPRE (3ULL << CSR_STPRE_SHIFT) ++#define CSR_INSTPRE_SHIFT 1 ++#define CSR_INSTPRE (1ULL << CSR_INSTPRE_SHIFT) ++#define CSR_DATAPRE_SHIFT 0 ++#define CSR_DATAPRE (1ULL << CSR_DATAPRE_SHIFT) ++ ++#define LOONGARCH_CSR_IMPCTL2 0x81 /* 32 Flush */ ++#define CSR_IMPCTL2_MTLB_SHIFT 0 ++#define CSR_IMPCTL2_MTLB (1ULL << CSR_IMPCTL2_MTLB_SHIFT) ++#define CSR_IMPCTL2_STLB_SHIFT 1 ++#define CSR_IMPCTL2_STLB (1ULL << CSR_IMPCTL2_STLB_SHIFT) ++#define CSR_IMPCTL2_DTLB_SHIFT 2 ++#define CSR_IMPCTL2_DTLB (1ULL << CSR_IMPCTL2_DTLB_SHIFT) ++#define CSR_IMPCTL2_ITLB_SHIFT 3 ++#define CSR_IMPCTL2_ITLB (1ULL << CSR_IMPCTL2_ITLB_SHIFT) ++#define CSR_IMPCTL2_BTAC_SHIFT 4 ++#define CSR_IMPCTL2_BTAC (1ULL << CSR_IMPCTL2_BTAC_SHIFT) ++ ++#define LOONGARCH_FLUSH_VTLB 1 ++#define LOONGARCH_FLUSH_FTLB (1 << 1) ++#define LOONGARCH_FLUSH_DTLB (1 << 2) ++#define LOONGARCH_FLUSH_ITLB (1 << 3) ++#define LOONGARCH_FLUSH_BTAC (1 << 4) ++ ++#define LOONGARCH_CSR_GNMI 0x82 ++ ++/* TLB Refill Only */ ++#define LOONGARCH_CSR_TLBRENT 0x88 /* 64 TLB refill exception address */ ++#define LOONGARCH_CSR_TLBRBADV 0x89 /* 64 TLB refill badvaddr */ ++#define LOONGARCH_CSR_TLBRERA 0x8a /* 64 TLB refill ERA */ ++#define LOONGARCH_CSR_TLBRSAVE 0x8b /* 64 KScratch for TLB refill */ ++#define LOONGARCH_CSR_TLBRELO0 0x8c /* 64 TLB refill entrylo0 */ ++#define LOONGARCH_CSR_TLBRELO1 0x8d /* 64 TLB refill entrylo1 */ ++#define LOONGARCH_CSR_TLBREHI 0x8e /* 64 TLB refill entryhi */ ++#define LOONGARCH_CSR_TLBRPRMD 0x8f /* 64 TLB refill mode info */ ++ ++/* error related */ ++#define LOONGARCH_CSR_ERRCTL 0x90 /* 32 ERRCTL */ ++#define LOONGARCH_CSR_ERRINFO 0x91 ++#define LOONGARCH_CSR_ERRINFO1 0x92 ++#define LOONGARCH_CSR_ERRENT 0x93 /* 64 error exception base */ ++#define LOONGARCH_CSR_ERRERA 0x94 /* 64 error exception PC */ ++#define LOONGARCH_CSR_ERRSAVE 0x95 /* 64 KScratch for error exception */ ++ ++#define LOONGARCH_CSR_CTAG 0x98 /* 64 TagLo + TagHi */ ++ ++/* direct map windows */ ++#define LOONGARCH_CSR_DMWIN0 0x180 /* 64 direct map win0: MEM & IF */ ++#define LOONGARCH_CSR_DMWIN1 0x181 /* 64 direct map win1: MEM & IF */ ++#define LOONGARCH_CSR_DMWIN2 0x182 /* 64 direct map win2: MEM */ ++#define LOONGARCH_CSR_DMWIN3 0x183 /* 64 direct map win3: MEM */ ++#define CSR_DMW_PLV0 0x1 ++#define CSR_DMW_PLV1 0x2 ++#define CSR_DMW_PLV2 0x4 ++#define CSR_DMW_PLV3 0x8 ++#define CSR_DMW_BASE_SH 48 ++#define dmwin_va2pa(va) \ ++ (va & (((unsigned long)1 << CSR_DMW_BASE_SH) - 1)) ++ ++/* performance counter */ ++#define LOONGARCH_CSR_PERFCTRL0 0x200 /* 32 perf event 0 config */ ++#define LOONGARCH_CSR_PERFCNTR0 0x201 /* 64 perf event 0 count value */ ++#define LOONGARCH_CSR_PERFCTRL1 0x202 /* 32 perf event 1 config */ ++#define LOONGARCH_CSR_PERFCNTR1 0x203 /* 64 perf event 1 count value */ ++#define LOONGARCH_CSR_PERFCTRL2 0x204 /* 32 perf event 2 config */ ++#define LOONGARCH_CSR_PERFCNTR2 0x205 /* 64 perf event 2 count value */ ++#define LOONGARCH_CSR_PERFCTRL3 0x206 /* 32 perf event 3 config */ ++#define LOONGARCH_CSR_PERFCNTR3 0x207 /* 64 perf event 3 count value */ ++#define CSR_PERFCTRL_PLV0 (1ULL << 16) ++#define CSR_PERFCTRL_PLV1 (1ULL << 17) ++#define CSR_PERFCTRL_PLV2 (1ULL << 18) ++#define CSR_PERFCTRL_PLV3 (1ULL << 19) ++#define CSR_PERFCTRL_IE (1ULL << 20) ++#define CSR_PERFCTRL_EVENT 0x3ff ++ ++/* debug */ ++#define LOONGARCH_CSR_MWPC 0x300 /* data breakpoint config */ ++#define LOONGARCH_CSR_MWPS 0x301 /* data breakpoint status */ ++ ++#define LOONGARCH_CSR_DB0ADDR 0x310 /* data breakpoint 0 address */ ++#define LOONGARCH_CSR_DB0MASK 0x311 /* data breakpoint 0 mask */ ++#define LOONGARCH_CSR_DB0CTL 0x312 /* data breakpoint 0 control */ ++#define LOONGARCH_CSR_DB0ASID 0x313 /* data breakpoint 0 asid */ ++ ++#define LOONGARCH_CSR_DB1ADDR 0x318 /* data breakpoint 1 address */ ++#define LOONGARCH_CSR_DB1MASK 0x319 /* data breakpoint 1 mask */ ++#define LOONGARCH_CSR_DB1CTL 0x31a /* data breakpoint 1 control */ ++#define LOONGARCH_CSR_DB1ASID 0x31b /* data breakpoint 1 asid */ ++ ++#define LOONGARCH_CSR_DB2ADDR 0x320 /* data breakpoint 2 address */ ++#define LOONGARCH_CSR_DB2MASK 0x321 /* data breakpoint 2 mask */ ++#define LOONGARCH_CSR_DB2CTL 0x322 /* data breakpoint 2 control */ ++#define LOONGARCH_CSR_DB2ASID 0x323 /* data breakpoint 2 asid */ ++ ++#define LOONGARCH_CSR_DB3ADDR 0x328 /* data breakpoint 3 address */ ++#define LOONGARCH_CSR_DB3MASK 0x329 /* data breakpoint 3 mask */ ++#define LOONGARCH_CSR_DB3CTL 0x32a /* data breakpoint 3 control */ ++#define LOONGARCH_CSR_DB3ASID 0x32b /* data breakpoint 3 asid */ ++ ++#define LOONGARCH_CSR_FWPC 0x380 /* instruction breakpoint config */ ++#define LOONGARCH_CSR_FWPS 0x381 /* instruction breakpoint status */ ++ ++#define LOONGARCH_CSR_IB0ADDR 0x390 /* inst breakpoint 0 address */ ++#define LOONGARCH_CSR_IB0MASK 0x391 /* inst breakpoint 0 mask */ ++#define LOONGARCH_CSR_IB0CTL 0x392 /* inst breakpoint 0 control */ ++#define LOONGARCH_CSR_IB0ASID 0x393 /* inst breakpoint 0 asid */ ++#define LOONGARCH_CSR_IB1ADDR 0x398 /* inst breakpoint 1 address */ ++#define LOONGARCH_CSR_IB1MASK 0x399 /* inst breakpoint 1 mask */ ++#define LOONGARCH_CSR_IB1CTL 0x39a /* inst breakpoint 1 control */ ++#define LOONGARCH_CSR_IB1ASID 0x39b /* inst breakpoint 1 asid */ ++ ++#define LOONGARCH_CSR_IB2ADDR 0x3a0 /* inst breakpoint 2 address */ ++#define LOONGARCH_CSR_IB2MASK 0x3a1 /* inst breakpoint 2 mask */ ++#define LOONGARCH_CSR_IB2CTL 0x3a2 /* inst breakpoint 2 control */ ++#define LOONGARCH_CSR_IB2ASID 0x3a3 /* inst breakpoint 2 asid */ ++ ++#define LOONGARCH_CSR_IB3ADDR 0x3a8 /* inst breakpoint 3 address */ ++#define LOONGARCH_CSR_IB3MASK 0x3a9 /* inst breakpoint 3 mask */ ++#define LOONGARCH_CSR_IB3CTL 0x3aa /* inst breakpoint 3 control */ ++#define LOONGARCH_CSR_IB3ASID 0x3ab /* inst breakpoint 3 asid */ ++ ++#define LOONGARCH_CSR_IB4ADDR 0x3b0 /* inst breakpoint 4 address */ ++#define LOONGARCH_CSR_IB4MASK 0x3b1 /* inst breakpoint 4 mask */ ++#define LOONGARCH_CSR_IB4CTL 0x3b2 /* inst breakpoint 4 control */ ++#define LOONGARCH_CSR_IB4ASID 0x3b3 /* inst breakpoint 4 asid */ ++ ++#define LOONGARCH_CSR_IB5ADDR 0x3b8 /* inst breakpoint 5 address */ ++#define LOONGARCH_CSR_IB5MASK 0x3b9 /* inst breakpoint 5 mask */ ++#define LOONGARCH_CSR_IB5CTL 0x3ba /* inst breakpoint 5 control */ ++#define LOONGARCH_CSR_IB5ASID 0x3bb /* inst breakpoint 5 asid */ ++ ++#define LOONGARCH_CSR_IB6ADDR 0x3c0 /* inst breakpoint 6 address */ ++#define LOONGARCH_CSR_IB6MASK 0x3c1 /* inst breakpoint 6 mask */ ++#define LOONGARCH_CSR_IB6CTL 0x3c2 /* inst breakpoint 6 control */ ++#define LOONGARCH_CSR_IB6ASID 0x3c3 /* inst breakpoint 6 asid */ ++ ++#define LOONGARCH_CSR_IB7ADDR 0x3c8 /* inst breakpoint 7 address */ ++#define LOONGARCH_CSR_IB7MASK 0x3c9 /* inst breakpoint 7 mask */ ++#define LOONGARCH_CSR_IB7CTL 0x3ca /* inst breakpoint 7 control */ ++#define LOONGARCH_CSR_IB7ASID 0x3cb /* inst breakpoint 7 asid */ ++ ++#define LOONGARCH_CSR_DEBUG 0x500 /* debug config */ ++#define CSR_DEBUG_DM 0 ++#define CSR_DEBUG_DMVER 1 ++#define CSR_DEBUG_DINT 8 ++#define CSR_DEBUG_DBP 9 ++#define CSR_DEBUG_DIB 10 ++#define CSR_DEBUG_DDB 11 ++ ++#define LOONGARCH_CSR_DERA 0x501 /* debug era */ ++#define LOONGARCH_CSR_DESAVE 0x502 /* debug save */ ++ ++#define LOONGARCH_CSR_PRID 0xc0 /* 32 LOONGARCH CP0 PRID */ ++ ++#define LOONGARCH_CPUCFG0 0x0 ++#define CPUCFG0_3A5000_PRID 0x0014c010 ++ ++#define LOONGARCH_CPUCFG1 0x1 ++#define CPUCFG1_ISGR32 BIT(0) ++#define CPUCFG1_ISGR64 BIT(1) ++#define CPUCFG1_PAGING BIT(2) ++#define CPUCFG1_IOCSR BIT(3) ++#define CPUCFG1_PABITS (47 << 4) ++#define CPUCFG1_VABITS (47 << 12) ++#define CPUCFG1_UAL BIT(20) ++#define CPUCFG1_RI BIT(21) ++#define CPUCFG1_XI BIT(22) ++#define CPUCFG1_RPLV BIT(23) ++#define CPUCFG1_HUGEPG BIT(24) ++#define CPUCFG1_IOCSRBRD BIT(25) ++#define CPUCFG1_MSGINT BIT(26) ++ ++#define LOONGARCH_CPUCFG2 0x2 ++#define CPUCFG2_FP BIT(0) ++#define CPUCFG2_FPSP BIT(1) ++#define CPUCFG2_FPDP BIT(2) ++#define CPUCFG2_FPVERS (0 << 3) ++#define CPUCFG2_LSX BIT(6) ++#define CPUCFG2_LASX BIT(7) ++#define CPUCFG2_COMPLEX BIT(8) ++#define CPUCFG2_CRYPTO BIT(9) ++#define CPUCFG2_LVZP BIT(10) ++#define CPUCFG2_LVZVER (0 << 11) ++#define CPUCFG2_LLFTP BIT(14) ++#define CPUCFG2_LLFTPREV (1 << 15) ++#define CPUCFG2_X86BT BIT(18) ++#define CPUCFG2_ARMBT BIT(19) ++#define CPUCFG2_MIPSBT BIT(20) ++#define CPUCFG2_LSPW BIT(21) ++#define CPUCFG2_LAM BIT(22) ++ ++#define LOONGARCH_CPUCFG3 0x3 ++#define CPUCFG3_CCDMA BIT(0) ++#define CPUCFG3_SFB BIT(1) ++#define CPUCFG3_UCACC BIT(2) ++#define CPUCFG3_LLEXC BIT(3) ++#define CPUCFG3_SCDLY BIT(4) ++#define CPUCFG3_LLDBAR BIT(5) ++#define CPUCFG3_ITLBT BIT(6) ++#define CPUCFG3_ICACHET BIT(7) ++#define CPUCFG3_SPW_LVL (4 << 8) ++#define CPUCFG3_SPW_HG_HF BIT(11) ++#define CPUCFG3_RVA BIT(12) ++#define CPUCFG3_RVAMAX (7 << 13) ++ ++#define LOONGARCH_CPUCFG4 0x4 ++#define CCFREQ_100M 100000000 /* 100M */ ++ ++#define LOONGARCH_CPUCFG5 0x5 ++#define CPUCFG5_CCMUL 1 ++#define CPUCFG5_CCDIV (1 << 16) ++ ++#define LOONGARCH_CPUCFG6 0x6 ++#define CPUCFG6_PMP BIT(0) ++#define CPUCFG6_PAMVER (1 << 1) ++#define CPUCFG6_PMNUM (3 << 4) ++#define CPUCFG6_PMBITS (63 << 8) ++#define CPUCFG6_UPM BIT(14) ++ ++#define LOONGARCH_CPUCFG16 0x10 ++#define CPUCFG16_L1_IUPRE BIT(0) ++#define CPUCFG16_L1_UNIFY BIT(1) ++#define CPUCFG16_L1_DPRE BIT(2) ++#define CPUCFG16_L2_IUPRE BIT(3) ++#define CPUCFG16_L2_IUUNIFY BIT(4) ++#define CPUCFG16_L2_IUPRIV BIT(5) ++#define CPUCFG16_L2_IUINCL BIT(6) ++#define CPUCFG16_L2_DPRE BIT(7) ++#define CPUCFG16_L2_DPRIV BIT(8) ++#define CPUCFG16_L2_DINCL BIT(9) ++#define CPUCFG16_L3_IUPRE BIT(10) ++#define CPUCFG16_L3_IUUNIFY BIT(11) ++#define CPUCFG16_L3_IUPRIV BIT(12) ++#define CPUCFG16_L3_IUINCL BIT(13) ++#define CPUCFG16_L3_DPRE BIT(14) ++#define CPUCFG16_L3_DPRIV BIT(15) ++#define CPUCFG16_L3_DINCL BIT(16) ++ ++#define LOONGARCH_CPUCFG17 0x11 ++#define CPUCFG17_L1I_WAYS_M (3 << 0) ++#define CPUCFG17_L1I_SETS_M (8 << 16) ++#define CPUCFG17_L1I_SIZE_M (6 << 24) ++ ++#define LOONGARCH_CPUCFG18 0x12 ++#define CPUCFG18_L1D_WAYS_M (3 << 0) ++#define CPUCFG18_L1D_SETS_M (8 << 16) ++#define CPUCFG18_L1D_SIZE_M (6 << 24) ++ ++#define LOONGARCH_CPUCFG19 0x13 ++#define CPUCFG19_L2_WAYS_M (0xf << 0) ++#define CPUCFG19_L2_SETS_M (8 << 16) ++#define CPUCFG19_L2_SIZE_M (6 << 24) ++ ++#define LOONGARCH_CPUCFG20 0x14 ++#define CPUCFG20_L3_WAYS_M (0xf << 0) ++#define CPUCFG20_L3_SETS_M (0xe << 16) ++#define CPUCFG20_L3_SIZE_M (0x6 << 24) ++ ++#define LOONGARCH_PAGE_HUGE 0x40 ++#define LOONGARCH_HUGE_GLOBAL 0x1000 ++#define LOONGARCH_HUGE_GLOBAL_SH 12 ++ ++/* All CSR register ++ * ++ * default value in target/loongarch/cpu.c ++ * reset function in target/loongarch/translate.c:cpu_state_reset() ++ * ++ * This macro will be used only twice. ++ * > In target/loongarch/cpu.h:CPULOONGARCHState ++ * > In target/loongarch/internal.h:loongarch_def_t ++ * ++ * helper_function to rd/wr: ++ * > declare in target/loongarch/helper.h ++ * > realize in target/loongarch/op_helper.c ++ * ++ * during translate: ++ * > gen_csr_rdl() ++ * > gen_csr_wrl() ++ * > gen_csr_rdq() ++ * > gen_csr_wrq() ++ */ ++#define CPU_LOONGARCH_CSR \ ++ uint64_t CSR_CRMD; \ ++ uint64_t CSR_PRMD; \ ++ uint64_t CSR_EUEN; \ ++ uint64_t CSR_MISC; \ ++ uint64_t CSR_ECFG; \ ++ uint64_t CSR_ESTAT; \ ++ uint64_t CSR_ERA; \ ++ uint64_t CSR_BADV; \ ++ uint64_t CSR_BADI; \ ++ uint64_t CSR_EEPN; \ ++ uint64_t CSR_TLBIDX; \ ++ uint64_t CSR_TLBEHI; \ ++ uint64_t CSR_TLBELO0; \ ++ uint64_t CSR_TLBELO1; \ ++ uint64_t CSR_TLBWIRED; \ ++ uint64_t CSR_GTLBC; \ ++ uint64_t CSR_TRGP; \ ++ uint64_t CSR_ASID; \ ++ uint64_t CSR_PGDL; \ ++ uint64_t CSR_PGDH; \ ++ uint64_t CSR_PGD; \ ++ uint64_t CSR_PWCTL0; \ ++ uint64_t CSR_PWCTL1; \ ++ uint64_t CSR_STLBPGSIZE; \ ++ uint64_t CSR_RVACFG; \ ++ uint64_t CSR_CPUID; \ ++ uint64_t CSR_PRCFG1; \ ++ uint64_t CSR_PRCFG2; \ ++ uint64_t CSR_PRCFG3; \ ++ uint64_t CSR_KS0; \ ++ uint64_t CSR_KS1; \ ++ uint64_t CSR_KS2; \ ++ uint64_t CSR_KS3; \ ++ uint64_t CSR_KS4; \ ++ uint64_t CSR_KS5; \ ++ uint64_t CSR_KS6; \ ++ uint64_t CSR_KS7; \ ++ uint64_t CSR_KS8; \ ++ uint64_t CSR_TMID; \ ++ uint64_t CSR_TCFG; \ ++ uint64_t CSR_TVAL; \ ++ uint64_t CSR_CNTC; \ ++ uint64_t CSR_TINTCLR; \ ++ uint64_t CSR_GSTAT; \ ++ uint64_t CSR_GCFG; \ ++ uint64_t CSR_GINTC; \ ++ uint64_t CSR_GCNTC; \ ++ uint64_t CSR_LLBCTL; \ ++ uint64_t CSR_IMPCTL1; \ ++ uint64_t CSR_IMPCTL2; \ ++ uint64_t CSR_GNMI; \ ++ uint64_t CSR_TLBRENT; \ ++ uint64_t CSR_TLBRBADV; \ ++ uint64_t CSR_TLBRERA; \ ++ uint64_t CSR_TLBRSAVE; \ ++ uint64_t CSR_TLBRELO0; \ ++ uint64_t CSR_TLBRELO1; \ ++ uint64_t CSR_TLBREHI; \ ++ uint64_t CSR_TLBRPRMD; \ ++ uint64_t CSR_ERRCTL; \ ++ uint64_t CSR_ERRINFO; \ ++ uint64_t CSR_ERRINFO1; \ ++ uint64_t CSR_ERRENT; \ ++ uint64_t CSR_ERRERA; \ ++ uint64_t CSR_ERRSAVE; \ ++ uint64_t CSR_CTAG; \ ++ uint64_t CSR_DMWIN0; \ ++ uint64_t CSR_DMWIN1; \ ++ uint64_t CSR_DMWIN2; \ ++ uint64_t CSR_DMWIN3; \ ++ uint64_t CSR_PERFCTRL0; \ ++ uint64_t CSR_PERFCNTR0; \ ++ uint64_t CSR_PERFCTRL1; \ ++ uint64_t CSR_PERFCNTR1; \ ++ uint64_t CSR_PERFCTRL2; \ ++ uint64_t CSR_PERFCNTR2; \ ++ uint64_t CSR_PERFCTRL3; \ ++ uint64_t CSR_PERFCNTR3; \ ++ uint64_t CSR_MWPC; \ ++ uint64_t CSR_MWPS; \ ++ uint64_t CSR_DB0ADDR; \ ++ uint64_t CSR_DB0MASK; \ ++ uint64_t CSR_DB0CTL; \ ++ uint64_t CSR_DB0ASID; \ ++ uint64_t CSR_DB1ADDR; \ ++ uint64_t CSR_DB1MASK; \ ++ uint64_t CSR_DB1CTL; \ ++ uint64_t CSR_DB1ASID; \ ++ uint64_t CSR_DB2ADDR; \ ++ uint64_t CSR_DB2MASK; \ ++ uint64_t CSR_DB2CTL; \ ++ uint64_t CSR_DB2ASID; \ ++ uint64_t CSR_DB3ADDR; \ ++ uint64_t CSR_DB3MASK; \ ++ uint64_t CSR_DB3CTL; \ ++ uint64_t CSR_DB3ASID; \ ++ uint64_t CSR_FWPC; \ ++ uint64_t CSR_FWPS; \ ++ uint64_t CSR_IB0ADDR; \ ++ uint64_t CSR_IB0MASK; \ ++ uint64_t CSR_IB0CTL; \ ++ uint64_t CSR_IB0ASID; \ ++ uint64_t CSR_IB1ADDR; \ ++ uint64_t CSR_IB1MASK; \ ++ uint64_t CSR_IB1CTL; \ ++ uint64_t CSR_IB1ASID; \ ++ uint64_t CSR_IB2ADDR; \ ++ uint64_t CSR_IB2MASK; \ ++ uint64_t CSR_IB2CTL; \ ++ uint64_t CSR_IB2ASID; \ ++ uint64_t CSR_IB3ADDR; \ ++ uint64_t CSR_IB3MASK; \ ++ uint64_t CSR_IB3CTL; \ ++ uint64_t CSR_IB3ASID; \ ++ uint64_t CSR_IB4ADDR; \ ++ uint64_t CSR_IB4MASK; \ ++ uint64_t CSR_IB4CTL; \ ++ uint64_t CSR_IB4ASID; \ ++ uint64_t CSR_IB5ADDR; \ ++ uint64_t CSR_IB5MASK; \ ++ uint64_t CSR_IB5CTL; \ ++ uint64_t CSR_IB5ASID; \ ++ uint64_t CSR_IB6ADDR; \ ++ uint64_t CSR_IB6MASK; \ ++ uint64_t CSR_IB6CTL; \ ++ uint64_t CSR_IB6ASID; \ ++ uint64_t CSR_IB7ADDR; \ ++ uint64_t CSR_IB7MASK; \ ++ uint64_t CSR_IB7CTL; \ ++ uint64_t CSR_IB7ASID; \ ++ uint64_t CSR_DEBUG; \ ++ uint64_t CSR_DERA; \ ++ uint64_t CSR_DESAVE; \ ++ ++#define LOONGARCH_CSR_32(_R, _S) \ ++ (KVM_REG_LOONGARCH_CSR | KVM_REG_SIZE_U32 | (8 * (_R) + (_S))) ++ ++#define LOONGARCH_CSR_64(_R, _S) \ ++ (KVM_REG_LOONGARCH_CSR | KVM_REG_SIZE_U64 | (8 * (_R) + (_S))) ++ ++#define KVM_IOC_CSRID(id) LOONGARCH_CSR_64(id, 0) ++ ++#endif +diff --git a/target/loongarch64/cpu-param.h b/target/loongarch64/cpu-param.h +new file mode 100644 +index 000000000..24ca458af +--- /dev/null ++++ b/target/loongarch64/cpu-param.h +@@ -0,0 +1,30 @@ ++#ifndef CPU_PARAM_H ++#define CPU_PARAM_H ++ ++/* If we want to use host float regs... */ ++/* #define USE_HOST_FLOAT_REGS */ ++ ++/* Real pages are variable size... */ ++#define TARGET_PAGE_BITS 14 ++ ++#define LOONGARCH_TLB_MAX 2112 ++ ++#define TARGET_LONG_BITS 64 ++#define TARGET_PHYS_ADDR_SPACE_BITS 48 ++#define TARGET_VIRT_ADDR_SPACE_BITS 48 ++ ++/* ++ * bit definitions for insn_flags (ISAs/ASEs flags) ++ * ------------------------------------------------ ++ */ ++#define ISA_LARCH32 0x00000001ULL ++#define ISA_LARCH64 0x00000002ULL ++#define INSN_LOONGARCH 0x00010000ULL ++ ++#define CPU_LARCH32 (ISA_LARCH32) ++#define CPU_LARCH64 (ISA_LARCH32 | ISA_LARCH64) ++ ++#define NB_MMU_MODES 4 ++ ++#endif /* QEMU_LOONGARCH_DEFS_H */ ++ +diff --git a/target/loongarch64/cpu-qom.h b/target/loongarch64/cpu-qom.h +new file mode 100644 +index 000000000..ee9c1de57 +--- /dev/null ++++ b/target/loongarch64/cpu-qom.h +@@ -0,0 +1,54 @@ ++/* ++ * QEMU LOONGARCH CPU ++ * ++ * Copyright (c) 2012 SUSE LINUX Products GmbH ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see ++ * ++ */ ++#ifndef QEMU_LOONGARCH_CPU_QOM_H ++#define QEMU_LOONGARCH_CPU_QOM_H ++ ++#include "hw/core/cpu.h" ++ ++#define TYPE_LOONGARCH_CPU "loongarch-cpu" ++ ++#define LOONGARCH_CPU_CLASS(klass) \ ++ OBJECT_CLASS_CHECK(LOONGARCHCPUClass, (klass), TYPE_LOONGARCH_CPU) ++#define LOONGARCH_CPU(obj) \ ++ OBJECT_CHECK(LOONGARCHCPU, (obj), TYPE_LOONGARCH_CPU) ++#define LOONGARCH_CPU_GET_CLASS(obj) \ ++ OBJECT_GET_CLASS(LOONGARCHCPUClass, (obj), TYPE_LOONGARCH_CPU) ++ ++/** ++ * LOONGARCHCPUClass: ++ * @parent_realize: The parent class' realize handler. ++ * @parent_reset: The parent class' reset handler. ++ * ++ * A LOONGARCH CPU model. ++ */ ++typedef struct LOONGARCHCPUClass { ++ /*< private >*/ ++ CPUClass parent_class; ++ /*< public >*/ ++ ++ DeviceRealize parent_realize; ++ DeviceUnrealize parent_unrealize; ++ DeviceReset parent_reset; ++ const struct loongarch_def_t *cpu_def; ++} LOONGARCHCPUClass; ++ ++typedef struct LOONGARCHCPU LOONGARCHCPU; ++ ++#endif +diff --git a/target/loongarch64/cpu.c b/target/loongarch64/cpu.c +new file mode 100644 +index 000000000..a4535d34a +--- /dev/null ++++ b/target/loongarch64/cpu.c +@@ -0,0 +1,576 @@ ++/* ++ * QEMU LOONGARCH CPU ++ * ++ * Copyright (c) 2012 SUSE LINUX Products GmbH ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see ++ * ++ */ ++ ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include "qapi/visitor.h" ++#include "cpu.h" ++#include "internal.h" ++#include "kvm_larch.h" ++#include "qemu-common.h" ++#include "hw/qdev-properties.h" ++#include "sysemu/kvm.h" ++#include "exec/exec-all.h" ++#include "sysemu/arch_init.h" ++#include "cpu-csr.h" ++#include "qemu/qemu-print.h" ++#include "qapi/qapi-commands-machine-target.h" ++#ifdef CONFIG_TCG ++#include "hw/core/tcg-cpu-ops.h" ++#endif /* CONFIG_TCG */ ++ ++#define LOONGARCH_CONFIG1 \ ++((0x8 << CSR_CONF1_KSNUM_SHIFT) | (0x2f << CSR_CONF1_TMRBITS_SHIFT) | \ ++ (0x7 << CSR_CONF1_VSMAX_SHIFT)) ++ ++#define LOONGARCH_CONFIG3 \ ++((0x2 << CSR_CONF3_TLBORG_SHIFT) | (0x3f << CSR_CONF3_MTLBSIZE_SHIFT) | \ ++ (0x7 << CSR_CONF3_STLBWAYS_SHIFT) | (0x8 << CSR_CONF3_STLBIDX_SHIFT)) ++ ++/*****************************************************************************/ ++/* LOONGARCH CPU definitions */ ++const loongarch_def_t loongarch_defs[] = { ++ { ++ .name = "Loongson-3A5000", ++ ++ /* for LoongISA CSR */ ++ .CSR_PRCFG1 = LOONGARCH_CONFIG1, ++ .CSR_PRCFG2 = 0x3ffff000, ++ .CSR_PRCFG3 = LOONGARCH_CONFIG3, ++ .CSR_CRMD = (0 << CSR_CRMD_PLV_SHIFT) | (0 << CSR_CRMD_IE_SHIFT) | ++ (1 << CSR_CRMD_DA_SHIFT) | (0 << CSR_CRMD_PG_SHIFT) | ++ (1 << CSR_CRMD_DACF_SHIFT) | (1 << CSR_CRMD_DACM_SHIFT) , ++ .CSR_ECFG = 0x7 << 16, ++ .CSR_STLBPGSIZE = 0xe, ++ .CSR_RVACFG = 0x0, ++ .CSR_ASID = 0xa0000, ++ .FCSR0 = 0x0, ++ .FCSR0_rw_bitmask = 0x1f1f03df, ++ .PABITS = 48, ++ .insn_flags = CPU_LARCH64 | INSN_LOONGARCH, ++ .mmu_type = MMU_TYPE_LS3A5K, ++ }, ++ { ++ .name = "host", ++ ++ /* for LoongISA CSR */ ++ .CSR_PRCFG1 = LOONGARCH_CONFIG1, ++ .CSR_PRCFG2 = 0x3ffff000, ++ .CSR_PRCFG3 = LOONGARCH_CONFIG3, ++ .CSR_CRMD = (0 << CSR_CRMD_PLV_SHIFT) | (0 << CSR_CRMD_IE_SHIFT) | ++ (1 << CSR_CRMD_DA_SHIFT) | (0 << CSR_CRMD_PG_SHIFT) | ++ (1 << CSR_CRMD_DACF_SHIFT) | (1 << CSR_CRMD_DACM_SHIFT) , ++ .CSR_ECFG = 0x7 << 16, ++ .CSR_STLBPGSIZE = 0xe, ++ .CSR_RVACFG = 0x0, ++ .FCSR0 = 0x0, ++ .FCSR0_rw_bitmask = 0x1f1f03df, ++ .PABITS = 48, ++ .insn_flags = CPU_LARCH64 | INSN_LOONGARCH, ++ .mmu_type = MMU_TYPE_LS3A5K, ++ }, ++}; ++const int loongarch_defs_number = ARRAY_SIZE(loongarch_defs); ++ ++void loongarch_cpu_list(void) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(loongarch_defs); i++) { ++ qemu_printf("LOONGARCH '%s'\n", ++ loongarch_defs[i].name); ++ } ++} ++ ++CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) ++{ ++ CpuDefinitionInfoList *cpu_list = NULL; ++ const loongarch_def_t *def; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(loongarch_defs); i++) { ++ CpuDefinitionInfoList *entry; ++ CpuDefinitionInfo *info; ++ ++ def = &loongarch_defs[i]; ++ info = g_malloc0(sizeof(*info)); ++ info->name = g_strdup(def->name); ++ ++ entry = g_malloc0(sizeof(*entry)); ++ entry->value = info; ++ entry->next = cpu_list; ++ cpu_list = entry; ++ } ++ ++ return cpu_list; ++} ++ ++static void loongarch_cpu_set_pc(CPUState *cs, vaddr value) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ ++ env->active_tc.PC = value & ~(target_ulong)1; ++} ++ ++static bool loongarch_cpu_has_work(CPUState *cs) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ bool has_work = false; ++ ++ /* It is implementation dependent if non-enabled ++ interrupts wake-up the CPU, however most of the implementations only ++ check for interrupts that can be taken. */ ++ if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && ++ cpu_loongarch_hw_interrupts_pending(env)) { ++ has_work = true; ++ } ++ ++ return has_work; ++} ++ ++const char * const regnames[] = { ++ "r0", "ra", "tp", "sp", "a0", "a1", "a2", "a3", ++ "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", ++ "t4", "t5", "t6", "t7", "t8", "x0", "fp", "s0", ++ "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", ++}; ++ ++const char * const fregnames[] = { ++ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", ++ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", ++ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", ++ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", ++}; ++ ++static void fpu_dump_state(CPULOONGARCHState *env, FILE *f, ++ fprintf_function fpu_fprintf, int flags) ++{ ++ int i; ++ int is_fpu64 = 1; ++ ++#define printfpr(fp) \ ++ do { \ ++ if (is_fpu64) \ ++ fpu_fprintf(f, "w:%08x d:%016" PRIx64 \ ++ " fd:%13g fs:%13g psu: %13g\n", \ ++ (fp)->w[FP_ENDIAN_IDX], (fp)->d, \ ++ (double)(fp)->fd, \ ++ (double)(fp)->fs[FP_ENDIAN_IDX], \ ++ (double)(fp)->fs[!FP_ENDIAN_IDX]); \ ++ else { \ ++ fpr_t tmp; \ ++ tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \ ++ tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \ ++ fpu_fprintf(f, "w:%08x d:%016" PRIx64 \ ++ " fd:%13g fs:%13g psu:%13g\n", \ ++ tmp.w[FP_ENDIAN_IDX], tmp.d, \ ++ (double)tmp.fd, \ ++ (double)tmp.fs[FP_ENDIAN_IDX], \ ++ (double)tmp.fs[!FP_ENDIAN_IDX]); \ ++ } \ ++ } while (0) ++ ++ ++ fpu_fprintf(f, "FCSR0 0x%08x SR.FR %d fp_status 0x%02x\n", ++ env->active_fpu.fcsr0, is_fpu64, ++ get_float_exception_flags(&env->active_fpu.fp_status)); ++ for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) { ++ fpu_fprintf(f, "%3s: ", fregnames[i]); ++ printfpr(&env->active_fpu.fpr[i]); ++ } ++ ++#undef printfpr ++} ++ ++void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ int i; ++ ++ qemu_fprintf(f, "pc:\t %lx\n", env->active_tc.PC); ++ for (i = 0; i < 32; i++) { ++ if ((i & 3) == 0) { ++ qemu_fprintf(f, "GPR%02d:", i); ++ } ++ qemu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], ++ env->active_tc.gpr[i]); ++ if ((i & 3) == 3) { ++ qemu_fprintf(f, "\n"); ++ } ++ } ++ qemu_fprintf(f, "EUEN 0x%lx\n", env->CSR_EUEN); ++ qemu_fprintf(f, "ESTAT 0x%lx\n", env->CSR_ESTAT); ++ qemu_fprintf(f, "ERA 0x%lx\n", env->CSR_ERA); ++ qemu_fprintf(f, "CRMD 0x%lx\n", env->CSR_CRMD); ++ qemu_fprintf(f, "PRMD 0x%lx\n", env->CSR_PRMD); ++ qemu_fprintf(f, "BadVAddr 0x%lx\n", env->CSR_BADV); ++ qemu_fprintf(f, "TLB refill ERA 0x%lx\n", env->CSR_TLBRERA); ++ qemu_fprintf(f, "TLB refill BadV 0x%lx\n", env->CSR_TLBRBADV); ++ qemu_fprintf(f, "EEPN 0x%lx\n", env->CSR_EEPN); ++ qemu_fprintf(f, "BadInstr 0x%lx\n", env->CSR_BADI); ++ qemu_fprintf(f, "PRCFG1 0x%lx\nPRCFG2 0x%lx\nPRCFG3 0x%lx\n", ++ env->CSR_PRCFG1, env->CSR_PRCFG3, env->CSR_PRCFG3); ++ if ((flags & CPU_DUMP_FPU) && (env->hflags & LARCH_HFLAG_FPU)) { ++ fpu_dump_state(env, f, qemu_fprintf, flags); ++ } ++} ++ ++void cpu_state_reset(CPULOONGARCHState *env) ++{ ++ LOONGARCHCPU *cpu = loongarch_env_get_cpu(env); ++ CPUState *cs = CPU(cpu); ++ ++ /* Reset registers to their default values */ ++ env->CSR_PRCFG1 = env->cpu_model->CSR_PRCFG1; ++ env->CSR_PRCFG2 = env->cpu_model->CSR_PRCFG2; ++ env->CSR_PRCFG3 = env->cpu_model->CSR_PRCFG3; ++ env->CSR_CRMD = env->cpu_model->CSR_CRMD; ++ env->CSR_ECFG = env->cpu_model->CSR_ECFG; ++ env->CSR_STLBPGSIZE = env->cpu_model->CSR_STLBPGSIZE; ++ env->CSR_RVACFG = env->cpu_model->CSR_RVACFG; ++ env->CSR_ASID = env->cpu_model->CSR_ASID; ++ ++ env->current_tc = 0; ++ env->active_fpu.fcsr0_rw_bitmask = env->cpu_model->FCSR0_rw_bitmask; ++ env->active_fpu.fcsr0 = env->cpu_model->FCSR0; ++ env->insn_flags = env->cpu_model->insn_flags; ++ ++#if !defined(CONFIG_USER_ONLY) ++ env->CSR_ERA = env->active_tc.PC; ++ env->active_tc.PC = env->exception_base; ++#ifdef CONFIG_TCG ++ env->tlb->tlb_in_use = env->tlb->nb_tlb; ++#endif ++ env->CSR_TLBWIRED = 0; ++ env->CSR_TMID = cs->cpu_index; ++ env->CSR_CPUID = (cs->cpu_index & 0x1ff); ++ env->CSR_EEPN |= (uint64_t)0x80000000; ++ env->CSR_TLBRENT |= (uint64_t)0x80000000; ++#endif ++ ++ /* Count register increments in debug mode, EJTAG version 1 */ ++ env->CSR_DEBUG = (1 << CSR_DEBUG_DINT) | (0x1 << CSR_DEBUG_DMVER); ++ ++ compute_hflags(env); ++ restore_fp_status(env); ++ cs->exception_index = EXCP_NONE; ++} ++ ++/* CPUClass::reset() */ ++static void loongarch_cpu_reset(DeviceState *dev) ++{ ++ CPUState *s = CPU(dev); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(s); ++ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(cpu); ++ CPULOONGARCHState *env = &cpu->env; ++ ++ mcc->parent_reset(dev); ++ ++ memset(env, 0, offsetof(CPULOONGARCHState, end_reset_fields)); ++ ++ cpu_state_reset(env); ++ ++#ifndef CONFIG_USER_ONLY ++ if (kvm_enabled()) { ++ kvm_loongarch_reset_vcpu(cpu); ++ } ++#endif ++} ++ ++static void loongarch_cpu_disas_set_info(CPUState *s, disassemble_info *info) ++{ ++ info->print_insn = print_insn_loongarch; ++} ++ ++static void fpu_init(CPULOONGARCHState *env, const loongarch_def_t *def) ++{ ++ memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu)); ++} ++ ++void cpu_loongarch_realize_env(CPULOONGARCHState *env) ++{ ++ env->exception_base = 0x1C000000; ++ ++#ifdef CONFIG_TCG ++#ifndef CONFIG_USER_ONLY ++ mmu_init(env, env->cpu_model); ++#endif ++#endif ++ fpu_init(env, env->cpu_model); ++} ++ ++static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp) ++{ ++ CPUState *cs = CPU(dev); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); ++ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(dev); ++ Error *local_err = NULL; ++ ++ cpu_exec_realizefn(cs, &local_err); ++ if (local_err != NULL) { ++ error_propagate(errp, local_err); ++ return; ++ } ++ ++ cpu_loongarch_realize_env(&cpu->env); ++ ++ loongarch_cpu_register_gdb_regs_for_features(cs); ++ ++ cpu_reset(cs); ++ qemu_init_vcpu(cs); ++ ++ mcc->parent_realize(dev, errp); ++ cpu->hotplugged = 1; ++} ++ ++static void loongarch_cpu_unrealizefn(DeviceState *dev) ++{ ++ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(dev); ++ ++#ifndef CONFIG_USER_ONLY ++ cpu_remove_sync(CPU(dev)); ++#endif ++ ++ mcc->parent_unrealize(dev); ++} ++static void loongarch_cpu_initfn(Object *obj) ++{ ++ CPUState *cs = CPU(obj); ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(obj); ++ CPULOONGARCHState *env = &cpu->env; ++ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(obj); ++ cpu_set_cpustate_pointers(cpu); ++ cs->env_ptr = env; ++ env->cpu_model = mcc->cpu_def; ++ cs->halted = 1; ++ cpu->dtb_compatible = "loongarch,Loongson-3A5000"; ++} ++ ++static char *loongarch_cpu_type_name(const char *cpu_model) ++{ ++ return g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"), cpu_model); ++} ++ ++static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model) ++{ ++ ObjectClass *oc; ++ char *typename; ++ ++ typename = loongarch_cpu_type_name(cpu_model); ++ oc = object_class_by_name(typename); ++ g_free(typename); ++ return oc; ++} ++ ++static int64_t loongarch_cpu_get_arch_id(CPUState *cs) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ ++ return cpu->id; ++} ++ ++static Property loongarch_cpu_properties[] = { ++ DEFINE_PROP_INT32("core-id", LOONGARCHCPU, core_id, -1), ++ DEFINE_PROP_INT32("id", LOONGARCHCPU, id, UNASSIGNED_CPU_ID), ++ DEFINE_PROP_INT32("node-id", LOONGARCHCPU, node_id, CPU_UNSET_NUMA_NODE_ID), ++ ++ DEFINE_PROP_END_OF_LIST() ++}; ++ ++#ifdef CONFIG_TCG ++static void loongarch_cpu_synchronize_from_tb(CPUState *cs,const TranslationBlock *tb) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ ++ env->active_tc.PC = tb->pc; ++ env->hflags &= ~LARCH_HFLAG_BMASK; ++ env->hflags |= tb->flags & LARCH_HFLAG_BMASK; ++} ++ ++static const struct TCGCPUOps loongarch_tcg_ops = { ++ .initialize = loongarch_tcg_init, ++ .synchronize_from_tb = loongarch_cpu_synchronize_from_tb, ++ ++ .tlb_fill = loongarch_cpu_tlb_fill, ++ .cpu_exec_interrupt = loongarch_cpu_exec_interrupt, ++ .do_interrupt = loongarch_cpu_do_interrupt, ++ ++#ifndef CONFIG_USER_ONLY ++ .do_unaligned_access = loongarch_cpu_do_unaligned_access, ++#endif /* !CONFIG_USER_ONLY */ ++}; ++#endif /* CONFIG_TCG */ ++ ++ ++#if !defined(CONFIG_USER_ONLY) ++static int get_physical_address(CPULOONGARCHState *env, hwaddr *physical, ++ int *prot, target_ulong real_address, ++ int rw, int access_type, int mmu_idx) ++{ ++ int user_mode = mmu_idx == LARCH_HFLAG_UM; ++ int kernel_mode = !user_mode; ++ unsigned plv, base_c, base_v, tmp; ++ ++ /* effective address (modified for KVM T&E kernel segments) */ ++ target_ulong address = real_address; ++ ++ /* Check PG */ ++ if (!(env->CSR_CRMD & CSR_CRMD_PG)) { ++ /* DA mode */ ++ *physical = address & 0xffffffffffffUL; ++ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ++ return TLBRET_MATCH; ++ } ++ ++ plv = kernel_mode | (user_mode << 3); ++ base_v = address >> CSR_DMW_BASE_SH; ++ /* Check direct map window 0 */ ++ base_c = env->CSR_DMWIN0 >> CSR_DMW_BASE_SH; ++ if ((plv & env->CSR_DMWIN0) && (base_c == base_v)) { ++ *physical = dmwin_va2pa(address); ++ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ++ return TLBRET_MATCH; ++ } ++ /* Check direct map window 1 */ ++ base_c = env->CSR_DMWIN1 >> CSR_DMW_BASE_SH; ++ if ((plv & env->CSR_DMWIN1) && (base_c == base_v)) { ++ *physical = dmwin_va2pa(address); ++ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ++ return TLBRET_MATCH; ++ } ++ /* Check valid extension */ ++ tmp = address >> 47; ++ if (!(tmp == 0 || tmp == 0x1ffff)) { ++ return TLBRET_BADADDR; ++ } ++ /* mapped address */ ++ return env->tlb->map_address(env, physical, prot, real_address, rw, ++ access_type); ++} ++ ++hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ hwaddr phys_addr; ++ int prot; ++ ++ if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT, ++ cpu_mmu_index(env, false)) != 0) { ++ return -1; ++ } ++ return phys_addr; ++} ++#endif ++ ++ ++#ifndef CONFIG_USER_ONLY ++#include "hw/core/sysemu-cpu-ops.h" ++ ++static const struct SysemuCPUOps loongarch_sysemu_ops = { ++ .write_elf64_note = loongarch_cpu_write_elf64_note, ++ .get_phys_page_debug = loongarch_cpu_get_phys_page_debug, ++ .legacy_vmsd = &vmstate_loongarch_cpu, ++}; ++#endif ++ ++ ++static void loongarch_cpu_class_init(ObjectClass *c, void *data) ++{ ++ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_CLASS(c); ++ CPUClass *cc = CPU_CLASS(c); ++ DeviceClass *dc = DEVICE_CLASS(c); ++ ++ device_class_set_props(dc, loongarch_cpu_properties); ++ device_class_set_parent_realize(dc, loongarch_cpu_realizefn, ++ &mcc->parent_realize); ++ ++ device_class_set_parent_unrealize(dc, loongarch_cpu_unrealizefn, ++ &mcc->parent_unrealize); ++ ++ device_class_set_parent_reset(dc, loongarch_cpu_reset, &mcc->parent_reset); ++ cc->get_arch_id = loongarch_cpu_get_arch_id; ++ ++ cc->class_by_name = loongarch_cpu_class_by_name; ++ cc->has_work = loongarch_cpu_has_work; ++ cc->dump_state = loongarch_cpu_dump_state; ++ cc->set_pc = loongarch_cpu_set_pc; ++ cc->gdb_read_register = loongarch_cpu_gdb_read_register; ++ cc->gdb_write_register = loongarch_cpu_gdb_write_register; ++ cc->disas_set_info = loongarch_cpu_disas_set_info; ++#ifndef CONFIG_USER_ONLY ++ cc->sysemu_ops = &loongarch_sysemu_ops; ++#endif /* !CONFIG_USER_ONLY */ ++ ++ cc->gdb_num_core_regs = 33; ++ cc->gdb_core_xml_file = "loongarch-base64.xml"; ++ cc->gdb_stop_before_watchpoint = true; ++ ++ dc->user_creatable = true; ++#ifdef CONFIG_TCG ++ cc->tcg_ops = &loongarch_tcg_ops; ++#endif /* CONFIG_TCG */ ++} ++ ++static const TypeInfo loongarch_cpu_type_info = { ++ .name = TYPE_LOONGARCH_CPU, ++ .parent = TYPE_CPU, ++ .instance_size = sizeof(LOONGARCHCPU), ++ .instance_init = loongarch_cpu_initfn, ++ .abstract = true, ++ .class_size = sizeof(LOONGARCHCPUClass), ++ .class_init = loongarch_cpu_class_init, ++}; ++ ++static void loongarch_cpu_cpudef_class_init(ObjectClass *oc, void *data) ++{ ++ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_CLASS(oc); ++ mcc->cpu_def = data; ++} ++ ++static void loongarch_register_cpudef_type(const struct loongarch_def_t *def) ++{ ++ char *typename = loongarch_cpu_type_name(def->name); ++ TypeInfo ti = { ++ .name = typename, ++ .parent = TYPE_LOONGARCH_CPU, ++ .class_init = loongarch_cpu_cpudef_class_init, ++ .class_data = (void *)def, ++ }; ++ ++ type_register(&ti); ++ g_free(typename); ++} ++ ++static void loongarch_cpu_register_types(void) ++{ ++ int i; ++ ++ type_register_static(&loongarch_cpu_type_info); ++ for (i = 0; i < loongarch_defs_number; i++) { ++ loongarch_register_cpudef_type(&loongarch_defs[i]); ++ } ++} ++ ++type_init(loongarch_cpu_register_types) +diff --git a/target/loongarch64/cpu.h b/target/loongarch64/cpu.h +new file mode 100644 +index 000000000..078556a22 +--- /dev/null ++++ b/target/loongarch64/cpu.h +@@ -0,0 +1,326 @@ ++#ifndef LOONGARCH_CPU_H ++#define LOONGARCH_CPU_H ++ ++ ++#define CPUArchState struct CPULOONGARCHState ++ ++#include "qemu-common.h" ++#include "cpu-qom.h" ++#include "larch-defs.h" ++#include "exec/cpu-defs.h" ++#include "fpu/softfloat.h" ++#include "sysemu/sysemu.h" ++#include "cpu-csr.h" ++ ++#define TCG_GUEST_DEFAULT_MO (0) ++ ++struct CPULOONGARCHState; ++typedef LOONGARCHCPU ArchCPU; ++typedef struct CPULOONGARCHTLBContext CPULOONGARCHTLBContext; ++ ++#define LASX_REG_WIDTH (256) ++typedef union lasx_reg_t lasx_reg_t; ++union lasx_reg_t { ++ int64_t val64[LASX_REG_WIDTH / 64]; ++}; ++ ++typedef union fpr_t fpr_t; ++union fpr_t { ++ float64 fd; /* ieee double precision */ ++ float32 fs[2];/* ieee single precision */ ++ uint64_t d; /* binary double fixed-point */ ++ uint32_t w[2]; /* binary single fixed-point */ ++/* FPU/LASX register mapping is not tested on big-endian hosts. */ ++ lasx_reg_t lasx; /* vector data */ ++}; ++/* define FP_ENDIAN_IDX to access the same location ++ * in the fpr_t union regardless of the host endianness ++ */ ++#if defined(HOST_WORDS_BIGENDIAN) ++# define FP_ENDIAN_IDX 1 ++#else ++# define FP_ENDIAN_IDX 0 ++#endif ++ ++typedef struct CPULOONGARCHFPUContext { ++ /* Floating point registers */ ++ fpr_t fpr[32]; ++ float_status fp_status; ++ ++ bool cf[8]; ++ /* fcsr0 ++ * 31:29 |28:24 |23:21 |20:16 |15:10 |9:8 |7 |6 |5 |4:0 ++ * Cause Flags RM DAE TM Enables ++ */ ++ uint32_t fcsr0; ++ uint32_t fcsr0_rw_bitmask; ++ uint32_t vcsr16; ++} CPULOONGARCHFPUContext; ++ ++/* fp control and status register definition */ ++#define FCSR0_M1 0xdf /* DAE, TM and Enables */ ++#define FCSR0_M2 0x1f1f0000 /* Cause and Flags */ ++#define FCSR0_M3 0x300 /* Round Mode */ ++#define FCSR0_RM 8 /* Round Mode bit num on fcsr0 */ ++#define GET_FP_CAUSE(reg) (((reg) >> 24) & 0x1f) ++#define GET_FP_ENABLE(reg) (((reg) >> 0) & 0x1f) ++#define GET_FP_FLAGS(reg) (((reg) >> 16) & 0x1f) ++#define SET_FP_CAUSE(reg, v) do { (reg) = ((reg) & ~(0x1f << 24)) | \ ++ ((v & 0x1f) << 24); \ ++ } while (0) ++#define SET_FP_ENABLE(reg, v) do { (reg) = ((reg) & ~(0x1f << 0)) | \ ++ ((v & 0x1f) << 0); \ ++ } while (0) ++#define SET_FP_FLAGS(reg, v) do { (reg) = ((reg) & ~(0x1f << 16)) | \ ++ ((v & 0x1f) << 16); \ ++ } while (0) ++#define UPDATE_FP_FLAGS(reg, v) do { (reg) |= ((v & 0x1f) << 16); } while (0) ++#define FP_INEXACT 1 ++#define FP_UNDERFLOW 2 ++#define FP_OVERFLOW 4 ++#define FP_DIV0 8 ++#define FP_INVALID 16 ++ ++#define TARGET_INSN_START_EXTRA_WORDS 2 ++ ++typedef struct loongarch_def_t loongarch_def_t; ++ ++#define LOONGARCH_FPU_MAX 1 ++#define LOONGARCH_KSCRATCH_NUM 8 ++ ++typedef struct TCState TCState; ++struct TCState { ++ target_ulong gpr[32]; ++ target_ulong PC; ++}; ++ ++#define N_IRQS 14 ++#define IRQ_TIMER 11 ++#define IRQ_IPI 12 ++#define IRQ_UART 2 ++ ++typedef struct CPULOONGARCHState CPULOONGARCHState; ++struct CPULOONGARCHState { ++ TCState active_tc; ++ CPULOONGARCHFPUContext active_fpu; ++ ++ uint32_t current_tc; ++ uint64_t scr[4]; ++ uint32_t PABITS; ++ ++ /* LoongISA CSR register */ ++ CPU_LOONGARCH_CSR ++ uint64_t lladdr; ++ target_ulong llval; ++ uint64_t llval_wp; ++ uint32_t llnewval_wp; ++ ++ CPULOONGARCHFPUContext fpus[LOONGARCH_FPU_MAX]; ++ /* QEMU */ ++ int error_code; ++#define EXCP_TLB_NOMATCH 0x1 ++#define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */ ++ uint32_t hflags; /* CPU State */ ++ /* TMASK defines different execution modes */ ++#define LARCH_HFLAG_TMASK 0x5F5807FF ++ /* ++ * The KSU flags must be the lowest bits in hflags. The flag order ++ * must be the same as defined for CP0 Status. This allows to use ++ * the bits as the value of mmu_idx. ++ */ ++#define LARCH_HFLAG_KSU 0x00003 /* kernel/user mode mask */ ++#define LARCH_HFLAG_UM 0x00003 /* user mode flag */ ++#define LARCH_HFLAG_KM 0x00000 /* kernel mode flag */ ++#define LARCH_HFLAG_64 0x00008 /* 64-bit instructions enabled */ ++#define LARCH_HFLAG_FPU 0x00020 /* FPU enabled */ ++#define LARCH_HFLAG_AWRAP 0x00200 /* 32-bit compatibility address wrapping */ ++ /* If translation is interrupted between the branch instruction and ++ * the delay slot, record what type of branch it is so that we can ++ * resume translation properly. It might be possible to reduce ++ * this from three bits to two. */ ++#define LARCH_HFLAG_BMASK 0x03800 ++#define LARCH_HFLAG_B 0x00800 /* Unconditional branch */ ++#define LARCH_HFLAG_BC 0x01000 /* Conditional branch */ ++#define LARCH_HFLAG_BR 0x02000 /* branch to register (can't link TB) */ ++#define LARCH_HFLAG_LSX 0x1000000 ++#define LARCH_HFLAG_LASX 0x2000000 ++#define LARCH_HFLAG_LBT 0x40000000 ++ target_ulong btarget; /* Jump / branch target */ ++ target_ulong bcond; /* Branch condition (if needed) */ ++ ++ uint64_t insn_flags; /* Supported instruction set */ ++ int cpu_cfg[64]; ++ ++ /* Fields up to this point are cleared by a CPU reset */ ++ struct {} end_reset_fields; ++ ++ /* Fields from here on are preserved across CPU reset. */ ++#if !defined(CONFIG_USER_ONLY) ++ CPULOONGARCHTLBContext *tlb; ++#endif ++ ++ const loongarch_def_t *cpu_model; ++ void *irq[N_IRQS]; ++ QEMUTimer *timer; /* Internal timer */ ++ MemoryRegion *itc_tag; /* ITC Configuration Tags */ ++ target_ulong exception_base; /* ExceptionBase input to the core */ ++ struct { ++ uint64_t guest_addr; ++ } st; ++}; ++ ++ ++/* CPU can't have 0xFFFFFFFF APIC ID, use that value to distinguish ++ * that ID hasn't been set yet ++ */ ++#define UNASSIGNED_CPU_ID 0xFFFFFFFF ++ ++/** ++ * LOONGARCHCPU: ++ * @env: #CPULOONGARCHState ++ * ++ * A LOONGARCH CPU. ++ */ ++struct LOONGARCHCPU { ++ /*< private >*/ ++ CPUState parent_obj; ++ /*< public >*/ ++ CPUNegativeOffsetState neg; ++ CPULOONGARCHState env; ++ int32_t id; ++ int hotplugged; ++ uint8_t online_vcpus; ++ uint8_t is_migrate; ++ uint64_t counter_value; ++ uint32_t cpu_freq; ++ uint32_t count_ctl; ++ uint64_t pending_exceptions; ++ uint64_t pending_exceptions_clr; ++ uint64_t core_ext_ioisr[4]; ++ VMChangeStateEntry *cpuStateEntry; ++ int32_t node_id; /* NUMA node this CPU belongs to */ ++ int32_t core_id; ++ struct kvm_msrs *kvm_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, /* 7 */ ++ EXCP_AdEL, ++ EXCP_AdES, ++ EXCP_TLBF, ++ EXCP_IBE, ++ EXCP_SYSCALL, ++ EXCP_BREAK, ++ EXCP_FPDIS, ++ EXCP_LSXDIS, ++ EXCP_LASXDIS, ++ EXCP_RI, ++ EXCP_OVERFLOW, ++ EXCP_TRAP, ++ EXCP_FPE, ++ EXCP_LTLBL, ++ EXCP_TLBL, ++ EXCP_TLBS, ++ EXCP_DBE, ++ EXCP_TLBXI, ++ EXCP_TLBRI, ++ EXCP_TLBPE, ++ EXCP_BTDIS, ++ ++ EXCP_LAST = EXCP_BTDIS, ++}; ++ ++/* ++ * This is an internally generated WAKE request line. ++ * It is driven by the CPU itself. Raised when the MT ++ * block wants to wake a VPE from an inactive state and ++ * cleared when VPE goes from active to inactive. ++ */ ++#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0 ++ ++int cpu_loongarch_signal_handler(int host_signum, void *pinfo, void *puc); ++ ++#define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU ++#define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX ++#define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU ++ ++/* helper.c */ ++target_ulong exception_resume_pc(CPULOONGARCHState *env); ++ ++/* gdbstub.c */ ++void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs); ++void mmu_init(CPULOONGARCHState *env, const loongarch_def_t *def); ++ ++static inline void cpu_get_tb_cpu_state(CPULOONGARCHState *env, target_ulong *pc, ++ target_ulong *cs_base, uint32_t *flags) ++{ ++ *pc = env->active_tc.PC; ++ *cs_base = 0; ++ *flags = env->hflags & (LARCH_HFLAG_TMASK | LARCH_HFLAG_BMASK); ++} ++ ++static inline bool cpu_refill_state(CPULOONGARCHState *env) ++{ ++ return env->CSR_TLBRERA & 0x1; ++} ++ ++extern const char * const regnames[]; ++extern const char * const fregnames[]; ++#endif /* LOONGARCH_CPU_H */ +diff --git a/target/loongarch64/csr_helper.c b/target/loongarch64/csr_helper.c +new file mode 100644 +index 000000000..182e59e92 +--- /dev/null ++++ b/target/loongarch64/csr_helper.c +@@ -0,0 +1,704 @@ ++/* ++ * loongarch tlb emulation helpers for qemu. ++ * ++ * Copyright (c) 2020 - 2021 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++ ++#include "qemu/osdep.h" ++#include "qemu/main-loop.h" ++#include "cpu.h" ++#include "internal.h" ++#include "qemu/host-utils.h" ++#include "exec/helper-proto.h" ++#include "exec/exec-all.h" ++#include "exec/cpu_ldst.h" ++#include "sysemu/kvm.h" ++#include "hw/irq.h" ++#include "cpu-csr.h" ++#include "instmap.h" ++ ++#ifndef CONFIG_USER_ONLY ++target_ulong helper_csr_rdq(CPULOONGARCHState *env, uint64_t csr) ++{ ++ int64_t v; ++ ++#define CASE_CSR_RDQ(csr) \ ++ case LOONGARCH_CSR_ ## csr: \ ++ { \ ++ v = env->CSR_ ## csr; \ ++ break; \ ++ }; \ ++ ++ switch (csr) { ++ CASE_CSR_RDQ(CRMD) ++ CASE_CSR_RDQ(PRMD) ++ CASE_CSR_RDQ(EUEN) ++ CASE_CSR_RDQ(MISC) ++ CASE_CSR_RDQ(ECFG) ++ CASE_CSR_RDQ(ESTAT) ++ CASE_CSR_RDQ(ERA) ++ CASE_CSR_RDQ(BADV) ++ CASE_CSR_RDQ(BADI) ++ CASE_CSR_RDQ(EEPN) ++ CASE_CSR_RDQ(TLBIDX) ++ CASE_CSR_RDQ(TLBEHI) ++ CASE_CSR_RDQ(TLBELO0) ++ CASE_CSR_RDQ(TLBELO1) ++ CASE_CSR_RDQ(TLBWIRED) ++ CASE_CSR_RDQ(GTLBC) ++ CASE_CSR_RDQ(TRGP) ++ CASE_CSR_RDQ(ASID) ++ CASE_CSR_RDQ(PGDL) ++ CASE_CSR_RDQ(PGDH) ++ CASE_CSR_RDQ(PGD) ++ CASE_CSR_RDQ(PWCTL0) ++ CASE_CSR_RDQ(PWCTL1) ++ CASE_CSR_RDQ(STLBPGSIZE) ++ CASE_CSR_RDQ(RVACFG) ++ CASE_CSR_RDQ(CPUID) ++ CASE_CSR_RDQ(PRCFG1) ++ CASE_CSR_RDQ(PRCFG2) ++ CASE_CSR_RDQ(PRCFG3) ++ CASE_CSR_RDQ(KS0) ++ CASE_CSR_RDQ(KS1) ++ CASE_CSR_RDQ(KS2) ++ CASE_CSR_RDQ(KS3) ++ CASE_CSR_RDQ(KS4) ++ CASE_CSR_RDQ(KS5) ++ CASE_CSR_RDQ(KS6) ++ CASE_CSR_RDQ(KS7) ++ CASE_CSR_RDQ(KS8) ++ CASE_CSR_RDQ(TMID) ++ CASE_CSR_RDQ(TCFG) ++ case LOONGARCH_CSR_TVAL: ++ v = cpu_loongarch_get_stable_timer_ticks(env); ++ break; ++ CASE_CSR_RDQ(CNTC) ++ CASE_CSR_RDQ(TINTCLR) ++ CASE_CSR_RDQ(GSTAT) ++ CASE_CSR_RDQ(GCFG) ++ CASE_CSR_RDQ(GINTC) ++ CASE_CSR_RDQ(GCNTC) ++ CASE_CSR_RDQ(LLBCTL) ++ CASE_CSR_RDQ(IMPCTL1) ++ CASE_CSR_RDQ(IMPCTL2) ++ CASE_CSR_RDQ(GNMI) ++ CASE_CSR_RDQ(TLBRENT) ++ CASE_CSR_RDQ(TLBRBADV) ++ CASE_CSR_RDQ(TLBRERA) ++ CASE_CSR_RDQ(TLBRSAVE) ++ CASE_CSR_RDQ(TLBRELO0) ++ CASE_CSR_RDQ(TLBRELO1) ++ CASE_CSR_RDQ(TLBREHI) ++ CASE_CSR_RDQ(TLBRPRMD) ++ CASE_CSR_RDQ(ERRCTL) ++ CASE_CSR_RDQ(ERRINFO) ++ CASE_CSR_RDQ(ERRINFO1) ++ CASE_CSR_RDQ(ERRENT) ++ CASE_CSR_RDQ(ERRERA) ++ CASE_CSR_RDQ(ERRSAVE) ++ CASE_CSR_RDQ(CTAG) ++ CASE_CSR_RDQ(DMWIN0) ++ CASE_CSR_RDQ(DMWIN1) ++ CASE_CSR_RDQ(DMWIN2) ++ CASE_CSR_RDQ(DMWIN3) ++ CASE_CSR_RDQ(PERFCTRL0) ++ CASE_CSR_RDQ(PERFCNTR0) ++ CASE_CSR_RDQ(PERFCTRL1) ++ CASE_CSR_RDQ(PERFCNTR1) ++ CASE_CSR_RDQ(PERFCTRL2) ++ CASE_CSR_RDQ(PERFCNTR2) ++ CASE_CSR_RDQ(PERFCTRL3) ++ CASE_CSR_RDQ(PERFCNTR3) ++ /* debug */ ++ CASE_CSR_RDQ(MWPC) ++ CASE_CSR_RDQ(MWPS) ++ CASE_CSR_RDQ(DB0ADDR) ++ CASE_CSR_RDQ(DB0MASK) ++ CASE_CSR_RDQ(DB0CTL) ++ CASE_CSR_RDQ(DB0ASID) ++ CASE_CSR_RDQ(DB1ADDR) ++ CASE_CSR_RDQ(DB1MASK) ++ CASE_CSR_RDQ(DB1CTL) ++ CASE_CSR_RDQ(DB1ASID) ++ CASE_CSR_RDQ(DB2ADDR) ++ CASE_CSR_RDQ(DB2MASK) ++ CASE_CSR_RDQ(DB2CTL) ++ CASE_CSR_RDQ(DB2ASID) ++ CASE_CSR_RDQ(DB3ADDR) ++ CASE_CSR_RDQ(DB3MASK) ++ CASE_CSR_RDQ(DB3CTL) ++ CASE_CSR_RDQ(DB3ASID) ++ CASE_CSR_RDQ(FWPC) ++ CASE_CSR_RDQ(FWPS) ++ CASE_CSR_RDQ(IB0ADDR) ++ CASE_CSR_RDQ(IB0MASK) ++ CASE_CSR_RDQ(IB0CTL) ++ CASE_CSR_RDQ(IB0ASID) ++ CASE_CSR_RDQ(IB1ADDR) ++ CASE_CSR_RDQ(IB1MASK) ++ CASE_CSR_RDQ(IB1CTL) ++ CASE_CSR_RDQ(IB1ASID) ++ CASE_CSR_RDQ(IB2ADDR) ++ CASE_CSR_RDQ(IB2MASK) ++ CASE_CSR_RDQ(IB2CTL) ++ CASE_CSR_RDQ(IB2ASID) ++ CASE_CSR_RDQ(IB3ADDR) ++ CASE_CSR_RDQ(IB3MASK) ++ CASE_CSR_RDQ(IB3CTL) ++ CASE_CSR_RDQ(IB3ASID) ++ CASE_CSR_RDQ(IB4ADDR) ++ CASE_CSR_RDQ(IB4MASK) ++ CASE_CSR_RDQ(IB4CTL) ++ CASE_CSR_RDQ(IB4ASID) ++ CASE_CSR_RDQ(IB5ADDR) ++ CASE_CSR_RDQ(IB5MASK) ++ CASE_CSR_RDQ(IB5CTL) ++ CASE_CSR_RDQ(IB5ASID) ++ CASE_CSR_RDQ(IB6ADDR) ++ CASE_CSR_RDQ(IB6MASK) ++ CASE_CSR_RDQ(IB6CTL) ++ CASE_CSR_RDQ(IB6ASID) ++ CASE_CSR_RDQ(IB7ADDR) ++ CASE_CSR_RDQ(IB7MASK) ++ CASE_CSR_RDQ(IB7CTL) ++ CASE_CSR_RDQ(IB7ASID) ++ CASE_CSR_RDQ(DEBUG) ++ CASE_CSR_RDQ(DERA) ++ CASE_CSR_RDQ(DESAVE) ++ default : ++ assert(0); ++ } ++ ++#undef CASE_CSR_RDQ ++ compute_hflags(env); ++ return v; ++} ++ ++target_ulong helper_csr_wrq(CPULOONGARCHState *env, target_ulong val, ++ uint64_t csr) ++{ ++ int64_t old_v, v; ++ old_v = -1; ++ v = val; ++ ++#define CASE_CSR_WRQ(csr) \ ++ case LOONGARCH_CSR_ ## csr: \ ++ { \ ++ old_v = env->CSR_ ## csr; \ ++ env->CSR_ ## csr = v; \ ++ break; \ ++ }; \ ++ ++ switch (csr) { ++ CASE_CSR_WRQ(CRMD) ++ CASE_CSR_WRQ(PRMD) ++ CASE_CSR_WRQ(EUEN) ++ CASE_CSR_WRQ(MISC) ++ CASE_CSR_WRQ(ECFG) ++ CASE_CSR_WRQ(ESTAT) ++ CASE_CSR_WRQ(ERA) ++ CASE_CSR_WRQ(BADV) ++ CASE_CSR_WRQ(BADI) ++ CASE_CSR_WRQ(EEPN) ++ CASE_CSR_WRQ(TLBIDX) ++ CASE_CSR_WRQ(TLBEHI) ++ CASE_CSR_WRQ(TLBELO0) ++ CASE_CSR_WRQ(TLBELO1) ++ CASE_CSR_WRQ(TLBWIRED) ++ CASE_CSR_WRQ(GTLBC) ++ CASE_CSR_WRQ(TRGP) ++ CASE_CSR_WRQ(ASID) ++ CASE_CSR_WRQ(PGDL) ++ CASE_CSR_WRQ(PGDH) ++ CASE_CSR_WRQ(PGD) ++ CASE_CSR_WRQ(PWCTL0) ++ CASE_CSR_WRQ(PWCTL1) ++ CASE_CSR_WRQ(STLBPGSIZE) ++ CASE_CSR_WRQ(RVACFG) ++ CASE_CSR_WRQ(CPUID) ++ CASE_CSR_WRQ(PRCFG1) ++ CASE_CSR_WRQ(PRCFG2) ++ CASE_CSR_WRQ(PRCFG3) ++ CASE_CSR_WRQ(KS0) ++ CASE_CSR_WRQ(KS1) ++ CASE_CSR_WRQ(KS2) ++ CASE_CSR_WRQ(KS3) ++ CASE_CSR_WRQ(KS4) ++ CASE_CSR_WRQ(KS5) ++ CASE_CSR_WRQ(KS6) ++ CASE_CSR_WRQ(KS7) ++ CASE_CSR_WRQ(KS8) ++ CASE_CSR_WRQ(TMID) ++ case LOONGARCH_CSR_TCFG: ++ old_v = env->CSR_TCFG; ++ cpu_loongarch_store_stable_timer_config(env, v); ++ break; ++ CASE_CSR_WRQ(TVAL) ++ CASE_CSR_WRQ(CNTC) ++ case LOONGARCH_CSR_TINTCLR: ++ old_v = 0; ++ qemu_irq_lower(env->irq[IRQ_TIMER]); ++ break; ++ CASE_CSR_WRQ(GSTAT) ++ CASE_CSR_WRQ(GCFG) ++ CASE_CSR_WRQ(GINTC) ++ CASE_CSR_WRQ(GCNTC) ++ CASE_CSR_WRQ(LLBCTL) ++ CASE_CSR_WRQ(IMPCTL1) ++ case LOONGARCH_CSR_IMPCTL2: ++ if (v & CSR_IMPCTL2_MTLB) { ++ ls3a5k_flush_vtlb(env); ++ } ++ if (v & CSR_IMPCTL2_STLB) { ++ ls3a5k_flush_ftlb(env); ++ } ++ break; ++ CASE_CSR_WRQ(GNMI) ++ CASE_CSR_WRQ(TLBRENT) ++ CASE_CSR_WRQ(TLBRBADV) ++ CASE_CSR_WRQ(TLBRERA) ++ CASE_CSR_WRQ(TLBRSAVE) ++ CASE_CSR_WRQ(TLBRELO0) ++ CASE_CSR_WRQ(TLBRELO1) ++ CASE_CSR_WRQ(TLBREHI) ++ CASE_CSR_WRQ(TLBRPRMD) ++ CASE_CSR_WRQ(ERRCTL) ++ CASE_CSR_WRQ(ERRINFO) ++ CASE_CSR_WRQ(ERRINFO1) ++ CASE_CSR_WRQ(ERRENT) ++ CASE_CSR_WRQ(ERRERA) ++ CASE_CSR_WRQ(ERRSAVE) ++ CASE_CSR_WRQ(CTAG) ++ CASE_CSR_WRQ(DMWIN0) ++ CASE_CSR_WRQ(DMWIN1) ++ CASE_CSR_WRQ(DMWIN2) ++ CASE_CSR_WRQ(DMWIN3) ++ CASE_CSR_WRQ(PERFCTRL0) ++ CASE_CSR_WRQ(PERFCNTR0) ++ CASE_CSR_WRQ(PERFCTRL1) ++ CASE_CSR_WRQ(PERFCNTR1) ++ CASE_CSR_WRQ(PERFCTRL2) ++ CASE_CSR_WRQ(PERFCNTR2) ++ CASE_CSR_WRQ(PERFCTRL3) ++ CASE_CSR_WRQ(PERFCNTR3) ++ /* debug */ ++ CASE_CSR_WRQ(MWPC) ++ CASE_CSR_WRQ(MWPS) ++ CASE_CSR_WRQ(DB0ADDR) ++ CASE_CSR_WRQ(DB0MASK) ++ CASE_CSR_WRQ(DB0CTL) ++ CASE_CSR_WRQ(DB0ASID) ++ CASE_CSR_WRQ(DB1ADDR) ++ CASE_CSR_WRQ(DB1MASK) ++ CASE_CSR_WRQ(DB1CTL) ++ CASE_CSR_WRQ(DB1ASID) ++ CASE_CSR_WRQ(DB2ADDR) ++ CASE_CSR_WRQ(DB2MASK) ++ CASE_CSR_WRQ(DB2CTL) ++ CASE_CSR_WRQ(DB2ASID) ++ CASE_CSR_WRQ(DB3ADDR) ++ CASE_CSR_WRQ(DB3MASK) ++ CASE_CSR_WRQ(DB3CTL) ++ CASE_CSR_WRQ(DB3ASID) ++ CASE_CSR_WRQ(FWPC) ++ CASE_CSR_WRQ(FWPS) ++ CASE_CSR_WRQ(IB0ADDR) ++ CASE_CSR_WRQ(IB0MASK) ++ CASE_CSR_WRQ(IB0CTL) ++ CASE_CSR_WRQ(IB0ASID) ++ CASE_CSR_WRQ(IB1ADDR) ++ CASE_CSR_WRQ(IB1MASK) ++ CASE_CSR_WRQ(IB1CTL) ++ CASE_CSR_WRQ(IB1ASID) ++ CASE_CSR_WRQ(IB2ADDR) ++ CASE_CSR_WRQ(IB2MASK) ++ CASE_CSR_WRQ(IB2CTL) ++ CASE_CSR_WRQ(IB2ASID) ++ CASE_CSR_WRQ(IB3ADDR) ++ CASE_CSR_WRQ(IB3MASK) ++ CASE_CSR_WRQ(IB3CTL) ++ CASE_CSR_WRQ(IB3ASID) ++ CASE_CSR_WRQ(IB4ADDR) ++ CASE_CSR_WRQ(IB4MASK) ++ CASE_CSR_WRQ(IB4CTL) ++ CASE_CSR_WRQ(IB4ASID) ++ CASE_CSR_WRQ(IB5ADDR) ++ CASE_CSR_WRQ(IB5MASK) ++ CASE_CSR_WRQ(IB5CTL) ++ CASE_CSR_WRQ(IB5ASID) ++ CASE_CSR_WRQ(IB6ADDR) ++ CASE_CSR_WRQ(IB6MASK) ++ CASE_CSR_WRQ(IB6CTL) ++ CASE_CSR_WRQ(IB6ASID) ++ CASE_CSR_WRQ(IB7ADDR) ++ CASE_CSR_WRQ(IB7MASK) ++ CASE_CSR_WRQ(IB7CTL) ++ CASE_CSR_WRQ(IB7ASID) ++ CASE_CSR_WRQ(DEBUG) ++ CASE_CSR_WRQ(DERA) ++ CASE_CSR_WRQ(DESAVE) ++ default : ++ assert(0); ++ } ++ ++ if (csr == LOONGARCH_CSR_ASID) { ++ if (old_v != v) { ++ tlb_flush(CPU(loongarch_env_get_cpu(env))); ++ } ++ } ++ ++#undef CASE_CSR_WRQ ++ compute_hflags(env); ++ return old_v; ++} ++ ++target_ulong helper_csr_xchgq(CPULOONGARCHState *env, target_ulong val, ++ target_ulong mask, uint64_t csr) ++{ ++ target_ulong v, tmp; ++ v = val & mask; ++ ++#define CASE_CSR_XCHGQ(csr) \ ++ case LOONGARCH_CSR_ ## csr: \ ++ { \ ++ val = env->CSR_ ## csr; \ ++ env->CSR_ ## csr = (env->CSR_ ## csr) & (~mask); \ ++ env->CSR_ ## csr = (env->CSR_ ## csr) | v; \ ++ break; \ ++ }; \ ++ ++ switch (csr) { ++ CASE_CSR_XCHGQ(CRMD) ++ CASE_CSR_XCHGQ(PRMD) ++ CASE_CSR_XCHGQ(EUEN) ++ CASE_CSR_XCHGQ(MISC) ++ CASE_CSR_XCHGQ(ECFG) ++ case LOONGARCH_CSR_ESTAT: ++ val = env->CSR_ESTAT; ++ qatomic_and(&env->CSR_ESTAT, ~mask); ++ qatomic_or(&env->CSR_ESTAT, v); ++ break; ++ CASE_CSR_XCHGQ(ERA) ++ CASE_CSR_XCHGQ(BADV) ++ CASE_CSR_XCHGQ(BADI) ++ CASE_CSR_XCHGQ(EEPN) ++ CASE_CSR_XCHGQ(TLBIDX) ++ CASE_CSR_XCHGQ(TLBEHI) ++ CASE_CSR_XCHGQ(TLBELO0) ++ CASE_CSR_XCHGQ(TLBELO1) ++ CASE_CSR_XCHGQ(TLBWIRED) ++ CASE_CSR_XCHGQ(GTLBC) ++ CASE_CSR_XCHGQ(TRGP) ++ CASE_CSR_XCHGQ(ASID) ++ CASE_CSR_XCHGQ(PGDL) ++ CASE_CSR_XCHGQ(PGDH) ++ CASE_CSR_XCHGQ(PGD) ++ CASE_CSR_XCHGQ(PWCTL0) ++ CASE_CSR_XCHGQ(PWCTL1) ++ CASE_CSR_XCHGQ(STLBPGSIZE) ++ CASE_CSR_XCHGQ(RVACFG) ++ CASE_CSR_XCHGQ(CPUID) ++ CASE_CSR_XCHGQ(PRCFG1) ++ CASE_CSR_XCHGQ(PRCFG2) ++ CASE_CSR_XCHGQ(PRCFG3) ++ CASE_CSR_XCHGQ(KS0) ++ CASE_CSR_XCHGQ(KS1) ++ CASE_CSR_XCHGQ(KS2) ++ CASE_CSR_XCHGQ(KS3) ++ CASE_CSR_XCHGQ(KS4) ++ CASE_CSR_XCHGQ(KS5) ++ CASE_CSR_XCHGQ(KS6) ++ CASE_CSR_XCHGQ(KS7) ++ CASE_CSR_XCHGQ(KS8) ++ CASE_CSR_XCHGQ(TMID) ++ case LOONGARCH_CSR_TCFG: ++ val = env->CSR_TCFG; ++ tmp = val & ~mask; ++ tmp |= v; ++ cpu_loongarch_store_stable_timer_config(env, tmp); ++ break; ++ CASE_CSR_XCHGQ(TVAL) ++ CASE_CSR_XCHGQ(CNTC) ++ CASE_CSR_XCHGQ(TINTCLR) ++ CASE_CSR_XCHGQ(GSTAT) ++ CASE_CSR_XCHGQ(GCFG) ++ CASE_CSR_XCHGQ(GINTC) ++ CASE_CSR_XCHGQ(GCNTC) ++ CASE_CSR_XCHGQ(LLBCTL) ++ CASE_CSR_XCHGQ(IMPCTL1) ++ CASE_CSR_XCHGQ(IMPCTL2) ++ CASE_CSR_XCHGQ(GNMI) ++ CASE_CSR_XCHGQ(TLBRENT) ++ CASE_CSR_XCHGQ(TLBRBADV) ++ CASE_CSR_XCHGQ(TLBRERA) ++ CASE_CSR_XCHGQ(TLBRSAVE) ++ CASE_CSR_XCHGQ(TLBRELO0) ++ CASE_CSR_XCHGQ(TLBRELO1) ++ CASE_CSR_XCHGQ(TLBREHI) ++ CASE_CSR_XCHGQ(TLBRPRMD) ++ CASE_CSR_XCHGQ(ERRCTL) ++ CASE_CSR_XCHGQ(ERRINFO) ++ CASE_CSR_XCHGQ(ERRINFO1) ++ CASE_CSR_XCHGQ(ERRENT) ++ CASE_CSR_XCHGQ(ERRERA) ++ CASE_CSR_XCHGQ(ERRSAVE) ++ CASE_CSR_XCHGQ(CTAG) ++ CASE_CSR_XCHGQ(DMWIN0) ++ CASE_CSR_XCHGQ(DMWIN1) ++ CASE_CSR_XCHGQ(DMWIN2) ++ CASE_CSR_XCHGQ(DMWIN3) ++ CASE_CSR_XCHGQ(PERFCTRL0) ++ CASE_CSR_XCHGQ(PERFCNTR0) ++ CASE_CSR_XCHGQ(PERFCTRL1) ++ CASE_CSR_XCHGQ(PERFCNTR1) ++ CASE_CSR_XCHGQ(PERFCTRL2) ++ CASE_CSR_XCHGQ(PERFCNTR2) ++ CASE_CSR_XCHGQ(PERFCTRL3) ++ CASE_CSR_XCHGQ(PERFCNTR3) ++ /* debug */ ++ CASE_CSR_XCHGQ(MWPC) ++ CASE_CSR_XCHGQ(MWPS) ++ CASE_CSR_XCHGQ(DB0ADDR) ++ CASE_CSR_XCHGQ(DB0MASK) ++ CASE_CSR_XCHGQ(DB0CTL) ++ CASE_CSR_XCHGQ(DB0ASID) ++ CASE_CSR_XCHGQ(DB1ADDR) ++ CASE_CSR_XCHGQ(DB1MASK) ++ CASE_CSR_XCHGQ(DB1CTL) ++ CASE_CSR_XCHGQ(DB1ASID) ++ CASE_CSR_XCHGQ(DB2ADDR) ++ CASE_CSR_XCHGQ(DB2MASK) ++ CASE_CSR_XCHGQ(DB2CTL) ++ CASE_CSR_XCHGQ(DB2ASID) ++ CASE_CSR_XCHGQ(DB3ADDR) ++ CASE_CSR_XCHGQ(DB3MASK) ++ CASE_CSR_XCHGQ(DB3CTL) ++ CASE_CSR_XCHGQ(DB3ASID) ++ CASE_CSR_XCHGQ(FWPC) ++ CASE_CSR_XCHGQ(FWPS) ++ CASE_CSR_XCHGQ(IB0ADDR) ++ CASE_CSR_XCHGQ(IB0MASK) ++ CASE_CSR_XCHGQ(IB0CTL) ++ CASE_CSR_XCHGQ(IB0ASID) ++ CASE_CSR_XCHGQ(IB1ADDR) ++ CASE_CSR_XCHGQ(IB1MASK) ++ CASE_CSR_XCHGQ(IB1CTL) ++ CASE_CSR_XCHGQ(IB1ASID) ++ CASE_CSR_XCHGQ(IB2ADDR) ++ CASE_CSR_XCHGQ(IB2MASK) ++ CASE_CSR_XCHGQ(IB2CTL) ++ CASE_CSR_XCHGQ(IB2ASID) ++ CASE_CSR_XCHGQ(IB3ADDR) ++ CASE_CSR_XCHGQ(IB3MASK) ++ CASE_CSR_XCHGQ(IB3CTL) ++ CASE_CSR_XCHGQ(IB3ASID) ++ CASE_CSR_XCHGQ(IB4ADDR) ++ CASE_CSR_XCHGQ(IB4MASK) ++ CASE_CSR_XCHGQ(IB4CTL) ++ CASE_CSR_XCHGQ(IB4ASID) ++ CASE_CSR_XCHGQ(IB5ADDR) ++ CASE_CSR_XCHGQ(IB5MASK) ++ CASE_CSR_XCHGQ(IB5CTL) ++ CASE_CSR_XCHGQ(IB5ASID) ++ CASE_CSR_XCHGQ(IB6ADDR) ++ CASE_CSR_XCHGQ(IB6MASK) ++ CASE_CSR_XCHGQ(IB6CTL) ++ CASE_CSR_XCHGQ(IB6ASID) ++ CASE_CSR_XCHGQ(IB7ADDR) ++ CASE_CSR_XCHGQ(IB7MASK) ++ CASE_CSR_XCHGQ(IB7CTL) ++ CASE_CSR_XCHGQ(IB7ASID) ++ CASE_CSR_XCHGQ(DEBUG) ++ CASE_CSR_XCHGQ(DERA) ++ CASE_CSR_XCHGQ(DESAVE) ++ default : ++ assert(0); ++ } ++ ++#undef CASE_CSR_XCHGQ ++ compute_hflags(env); ++ return val; ++} ++ ++static target_ulong confbus_addr(CPULOONGARCHState *env, int cpuid, ++ target_ulong csr_addr) ++{ ++ target_ulong addr; ++ target_ulong node_addr; ++ int cores_per_node = ((0x60018 >> 3) & 0xff) + 1; ++ ++ switch (cores_per_node) { ++ case 4: ++ assert(cpuid < 64); ++ node_addr = ((target_ulong)(cpuid & 0x3c) << 42); ++ break; ++ case 8: ++ assert(cpuid < 128); ++ node_addr = ((target_ulong)(cpuid & 0x78) << 41) + ++ ((target_ulong)(cpuid & 0x4) << 14); ++ break; ++ case 16: ++ assert(cpuid < 256); ++ node_addr = ((target_ulong)(cpuid & 0xf0) << 40) + ++ ((target_ulong)(cpuid & 0xc) << 14); ++ break; ++ default: ++ assert(0); ++ break; ++ } ++ ++ /* ++ * per core address ++ *0x10xx => ipi ++ * 0x18xx => extioi isr ++ */ ++ if (((csr_addr & 0xff00) == 0x1000)) { ++ addr = (csr_addr & 0xff) + (target_ulong)(cpuid << 8); ++ addr = 0x800000001f000000UL + addr; ++ return addr; ++ } else if ((csr_addr & 0xff00) == 0x1800) { ++ addr = (csr_addr & 0xff) + ((target_ulong)(cpuid << 8)); ++ addr = 0x800000001f020000UL + addr; ++ return addr; ++ } else if ((csr_addr & 0xff00) >= 0x1400 && (csr_addr & 0xff00) < 0x1d00) { ++ addr = 0x800000001f010000UL + ((csr_addr & 0xfff) - 0x400); ++ return addr; ++ } else if (csr_addr == 0x408) { ++ addr = csr_addr; ++ } else { ++ addr = csr_addr + node_addr; ++ } ++ ++ addr = 0x800000001fe00000UL + addr; ++ return addr; ++} ++ ++void helper_iocsr(CPULOONGARCHState *env, target_ulong r_addr, ++ target_ulong r_val, uint32_t op) ++{ ++ target_ulong addr; ++ target_ulong val = env->active_tc.gpr[r_val]; ++ int mask; ++ ++ addr = confbus_addr(env, CPU(loongarch_env_get_cpu(env))->cpu_index, ++ env->active_tc.gpr[r_addr]); ++ ++ switch (env->active_tc.gpr[r_addr]) { ++ /* IPI send */ ++ case 0x1040: ++ if (op != OPC_LARCH_ST_W) { ++ return; ++ } ++ op = OPC_LARCH_ST_W; ++ break; ++ ++ /* Mail send */ ++ case 0x1048: ++ if (op != OPC_LARCH_ST_D) { ++ return; ++ } ++ op = OPC_LARCH_ST_D; ++ break; ++ ++ /* ANY send */ ++ case 0x1158: ++ if (op != OPC_LARCH_ST_D) { ++ return; ++ } ++ addr = confbus_addr(env, (val >> 16) & 0x3ff, val & 0xffff); ++ mask = (val >> 27) & 0xf; ++ val = (val >> 32); ++ switch (mask) { ++ case 0: ++ op = OPC_LARCH_ST_W; ++ break; ++ case 0x7: ++ op = OPC_LARCH_ST_B; ++ addr += 3; ++ val >>= 24; ++ break; ++ case 0xb: ++ op = OPC_LARCH_ST_B; ++ addr += 2; ++ val >>= 16; ++ break; ++ case 0xd: ++ op = OPC_LARCH_ST_B; ++ addr += 1; ++ val >>= 8; ++ break; ++ case 0xe: ++ op = OPC_LARCH_ST_B; ++ break; ++ case 0xc: ++ op = OPC_LARCH_ST_H; ++ break; ++ case 0x3: ++ op = OPC_LARCH_ST_H; ++ addr += 2; ++ val >>= 16; ++ break; ++ default: ++ qemu_log("Unsupported any_send mask0x%x\n", mask); ++ break; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ switch (op) { ++ case OPC_LARCH_LD_D: ++ env->active_tc.gpr[r_val] = cpu_ldq_data_ra(env, addr, ++ GETPC()); ++ break; ++ case OPC_LARCH_LD_W: ++ env->active_tc.gpr[r_val] = cpu_ldl_data_ra(env, addr, ++ GETPC()); ++ break; ++ case OPC_LARCH_LD_H: ++ assert(0); ++ break; ++ case OPC_LARCH_LD_B: ++ assert(0); ++ break; ++ case OPC_LARCH_ST_D: ++ cpu_stq_data_ra(env, addr, val, GETPC()); ++ break; ++ case OPC_LARCH_ST_W: ++ cpu_stl_data_ra(env, addr, val, GETPC()); ++ break; ++ case OPC_LARCH_ST_H: ++ cpu_stb_data_ra(env, addr, val, GETPC()); ++ break; ++ case OPC_LARCH_ST_B: ++ cpu_stb_data_ra(env, addr, val, GETPC()); ++ break; ++ default: ++ qemu_log("Unknown op 0x%x", op); ++ assert(0); ++ } ++} ++#endif ++ ++target_ulong helper_cpucfg(CPULOONGARCHState *env, target_ulong rj) ++{ ++ return 0; ++} ++ ++ +diff --git a/target/loongarch64/fpu.c b/target/loongarch64/fpu.c +new file mode 100644 +index 000000000..795458205 +--- /dev/null ++++ b/target/loongarch64/fpu.c +@@ -0,0 +1,28 @@ ++/* ++ * loongarch float point emulation helpers for qemu. ++ * ++ * Copyright (c) 2020-2021 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#include "qemu/osdep.h" ++#include "fpu/softfloat.h" ++ ++/* convert loongarch rounding mode in fcsr0 to IEEE library */ ++unsigned int ieee_rm[] = { ++ float_round_nearest_even, ++ float_round_to_zero, ++ float_round_up, ++ float_round_down ++}; +diff --git a/target/loongarch64/fpu_helper.c b/target/loongarch64/fpu_helper.c +new file mode 100644 +index 000000000..42d7f05ca +--- /dev/null ++++ b/target/loongarch64/fpu_helper.c +@@ -0,0 +1,952 @@ ++/* ++ * loongarch float point emulation helpers for qemu. ++ * ++ * Copyright (c) 2020-2021 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#include "qemu/osdep.h" ++#include "cpu.h" ++#include "internal.h" ++#include "qemu/host-utils.h" ++#include "exec/helper-proto.h" ++#include "exec/exec-all.h" ++#include "fpu/softfloat.h" ++ ++#define FP_TO_INT32_OVERFLOW 0x7fffffff ++#define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL ++ ++#define FLOAT_CLASS_SIGNALING_NAN 0x001 ++#define FLOAT_CLASS_QUIET_NAN 0x002 ++#define FLOAT_CLASS_NEGATIVE_INFINITY 0x004 ++#define FLOAT_CLASS_NEGATIVE_NORMAL 0x008 ++#define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010 ++#define FLOAT_CLASS_NEGATIVE_ZERO 0x020 ++#define FLOAT_CLASS_POSITIVE_INFINITY 0x040 ++#define FLOAT_CLASS_POSITIVE_NORMAL 0x080 ++#define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100 ++#define FLOAT_CLASS_POSITIVE_ZERO 0x200 ++ ++target_ulong helper_movfcsr2gr(CPULOONGARCHState *env, uint32_t reg) ++{ ++ target_ulong r = 0; ++ ++ switch (reg) { ++ case 0: ++ r = (uint32_t)env->active_fpu.fcsr0; ++ break; ++ case 1: ++ r = (env->active_fpu.fcsr0 & FCSR0_M1); ++ break; ++ case 2: ++ r = (env->active_fpu.fcsr0 & FCSR0_M2); ++ break; ++ case 3: ++ r = (env->active_fpu.fcsr0 & FCSR0_M3); ++ break; ++ case 16: ++ r = (uint32_t)env->active_fpu.vcsr16; ++ break; ++ default: ++ printf("%s: warning, fcsr '%d' not supported\n", __func__, reg); ++ assert(0); ++ break; ++ } ++ ++ return r; ++} ++ ++void helper_movgr2fcsr(CPULOONGARCHState *env, target_ulong arg1, ++ uint32_t fcsr, uint32_t rj) ++{ ++ switch (fcsr) { ++ case 0: ++ env->active_fpu.fcsr0 = arg1; ++ break; ++ case 1: ++ env->active_fpu.fcsr0 = (arg1 & FCSR0_M1) | ++ (env->active_fpu.fcsr0 & ~FCSR0_M1); ++ break; ++ case 2: ++ env->active_fpu.fcsr0 = (arg1 & FCSR0_M2) | ++ (env->active_fpu.fcsr0 & ~FCSR0_M2); ++ break; ++ case 3: ++ env->active_fpu.fcsr0 = (arg1 & FCSR0_M3) | ++ (env->active_fpu.fcsr0 & ~FCSR0_M3); ++ break; ++ case 16: ++ env->active_fpu.vcsr16 = arg1; ++ break; ++ default: ++ printf("%s: warning, fcsr '%d' not supported\n", __func__, fcsr); ++ assert(0); ++ break; ++ } ++ restore_fp_status(env); ++ set_float_exception_flags(0, &env->active_fpu.fp_status); ++} ++ ++void helper_movreg2cf(CPULOONGARCHState *env, uint32_t cd, target_ulong src) ++{ ++ env->active_fpu.cf[cd & 0x7] = src & 0x1; ++} ++ ++void helper_movreg2cf_i32(CPULOONGARCHState *env, uint32_t cd, uint32_t src) ++{ ++ env->active_fpu.cf[cd & 0x7] = src & 0x1; ++} ++ ++void helper_movreg2cf_i64(CPULOONGARCHState *env, uint32_t cd, uint64_t src) ++{ ++ env->active_fpu.cf[cd & 0x7] = src & 0x1; ++} ++ ++target_ulong helper_movcf2reg(CPULOONGARCHState *env, uint32_t cj) ++{ ++ return (target_ulong)env->active_fpu.cf[cj & 0x7]; ++} ++ ++int ieee_ex_to_loongarch(int xcpt) ++{ ++ int ret = 0; ++ if (xcpt) { ++ if (xcpt & float_flag_invalid) { ++ ret |= FP_INVALID; ++ } ++ if (xcpt & float_flag_overflow) { ++ ret |= FP_OVERFLOW; ++ } ++ if (xcpt & float_flag_underflow) { ++ ret |= FP_UNDERFLOW; ++ } ++ if (xcpt & float_flag_divbyzero) { ++ ret |= FP_DIV0; ++ } ++ if (xcpt & float_flag_inexact) { ++ ret |= FP_INEXACT; ++ } ++ } ++ return ret; ++} ++ ++static inline void update_fcsr0(CPULOONGARCHState *env, uintptr_t pc) ++{ ++ int tmp = ieee_ex_to_loongarch(get_float_exception_flags( ++ &env->active_fpu.fp_status)); ++ ++ SET_FP_CAUSE(env->active_fpu.fcsr0, tmp); ++ if (tmp) { ++ set_float_exception_flags(0, &env->active_fpu.fp_status); ++ ++ if (GET_FP_ENABLE(env->active_fpu.fcsr0) & tmp) { ++ do_raise_exception(env, EXCP_FPE, pc); ++ } else { ++ UPDATE_FP_FLAGS(env->active_fpu.fcsr0, tmp); ++ } ++ } ++} ++ ++/* unary operations, modifying fp status */ ++uint64_t helper_float_sqrt_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdt0; ++} ++ ++uint32_t helper_float_sqrt_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fst0; ++} ++ ++uint64_t helper_float_cvtd_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint64_t fdt2; ++ ++ fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdt2; ++} ++ ++uint64_t helper_float_cvtd_w(CPULOONGARCHState *env, uint32_t wt0) ++{ ++ uint64_t fdt2; ++ ++ fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdt2; ++} ++ ++uint64_t helper_float_cvtd_l(CPULOONGARCHState *env, uint64_t dt0) ++{ ++ uint64_t fdt2; ++ ++ fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdt2; ++} ++ ++uint64_t helper_float_cvt_l_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t dt2; ++ ++ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint64_t helper_float_cvt_l_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint64_t dt2; ++ ++ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint32_t helper_float_cvts_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint32_t fst2; ++ ++ fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fst2; ++} ++ ++uint32_t helper_float_cvts_w(CPULOONGARCHState *env, uint32_t wt0) ++{ ++ uint32_t fst2; ++ ++ fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fst2; ++} ++ ++uint32_t helper_float_cvts_l(CPULOONGARCHState *env, uint64_t dt0) ++{ ++ uint32_t fst2; ++ ++ fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fst2; ++} ++ ++uint32_t helper_float_cvt_w_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t wt2; ++ ++ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint32_t helper_float_cvt_w_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint32_t wt2; ++ ++ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint64_t helper_float_round_l_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t dt2; ++ ++ set_float_rounding_mode(float_round_nearest_even, ++ &env->active_fpu.fp_status); ++ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint64_t helper_float_round_l_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint64_t dt2; ++ ++ set_float_rounding_mode(float_round_nearest_even, ++ &env->active_fpu.fp_status); ++ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint32_t helper_float_round_w_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint32_t wt2; ++ ++ set_float_rounding_mode(float_round_nearest_even, ++ &env->active_fpu.fp_status); ++ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint32_t helper_float_round_w_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t wt2; ++ ++ set_float_rounding_mode(float_round_nearest_even, ++ &env->active_fpu.fp_status); ++ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint64_t helper_float_trunc_l_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t dt2; ++ ++ dt2 = float64_to_int64_round_to_zero(fdt0, ++ &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint64_t helper_float_trunc_l_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint64_t dt2; ++ ++ dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint32_t helper_float_trunc_w_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint32_t wt2; ++ ++ wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint32_t helper_float_trunc_w_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t wt2; ++ ++ wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint64_t helper_float_ceil_l_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t dt2; ++ ++ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); ++ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint64_t helper_float_ceil_l_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint64_t dt2; ++ ++ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); ++ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint32_t helper_float_ceil_w_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint32_t wt2; ++ ++ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); ++ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint32_t helper_float_ceil_w_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t wt2; ++ ++ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); ++ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint64_t helper_float_floor_l_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t dt2; ++ ++ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); ++ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint64_t helper_float_floor_l_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint64_t dt2; ++ ++ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); ++ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ dt2 = FP_TO_INT64_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint32_t helper_float_floor_w_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint32_t wt2; ++ ++ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); ++ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint32_t helper_float_floor_w_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t wt2; ++ ++ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); ++ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); ++ restore_rounding_mode(env); ++ if (get_float_exception_flags(&env->active_fpu.fp_status) ++ & (float_flag_invalid | float_flag_overflow)) { ++ wt2 = FP_TO_INT32_OVERFLOW; ++ } ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++/* unary operations, not modifying fp status */ ++#define FLOAT_UNOP(name) \ ++uint64_t helper_float_ ## name ## _d(uint64_t fdt0) \ ++{ \ ++ return float64_ ## name(fdt0); \ ++} \ ++uint32_t helper_float_ ## name ## _s(uint32_t fst0) \ ++{ \ ++ return float32_ ## name(fst0); \ ++} ++ ++FLOAT_UNOP(abs) ++FLOAT_UNOP(chs) ++#undef FLOAT_UNOP ++ ++uint64_t helper_float_recip_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t fdt2; ++ ++ fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdt2; ++} ++ ++uint32_t helper_float_recip_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t fst2; ++ ++ fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fst2; ++} ++ ++uint64_t helper_float_rsqrt_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t fdt2; ++ ++ fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status); ++ fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdt2; ++} ++ ++uint32_t helper_float_rsqrt_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t fst2; ++ ++ fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status); ++ fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fst2; ++} ++ ++uint32_t helper_float_rint_s(CPULOONGARCHState *env, uint32_t fs) ++{ ++ uint32_t fdret; ++ ++ fdret = float32_round_to_int(fs, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdret; ++} ++ ++uint64_t helper_float_rint_d(CPULOONGARCHState *env, uint64_t fs) ++{ ++ uint64_t fdret; ++ ++ fdret = float64_round_to_int(fs, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return fdret; ++} ++ ++#define FLOAT_CLASS(name, bits) \ ++uint ## bits ## _t float_ ## name(uint ## bits ## _t arg, \ ++ float_status *status) \ ++{ \ ++ if (float ## bits ## _is_signaling_nan(arg, status)) { \ ++ return FLOAT_CLASS_SIGNALING_NAN; \ ++ } else if (float ## bits ## _is_quiet_nan(arg, status)) { \ ++ return FLOAT_CLASS_QUIET_NAN; \ ++ } else if (float ## bits ## _is_neg(arg)) { \ ++ if (float ## bits ## _is_infinity(arg)) { \ ++ return FLOAT_CLASS_NEGATIVE_INFINITY; \ ++ } else if (float ## bits ## _is_zero(arg)) { \ ++ return FLOAT_CLASS_NEGATIVE_ZERO; \ ++ } else if (float ## bits ## _is_zero_or_denormal(arg)) { \ ++ return FLOAT_CLASS_NEGATIVE_SUBNORMAL; \ ++ } else { \ ++ return FLOAT_CLASS_NEGATIVE_NORMAL; \ ++ } \ ++ } else { \ ++ if (float ## bits ## _is_infinity(arg)) { \ ++ return FLOAT_CLASS_POSITIVE_INFINITY; \ ++ } else if (float ## bits ## _is_zero(arg)) { \ ++ return FLOAT_CLASS_POSITIVE_ZERO; \ ++ } else if (float ## bits ## _is_zero_or_denormal(arg)) { \ ++ return FLOAT_CLASS_POSITIVE_SUBNORMAL; \ ++ } else { \ ++ return FLOAT_CLASS_POSITIVE_NORMAL; \ ++ } \ ++ } \ ++} \ ++ \ ++uint ## bits ## _t helper_float_ ## name(CPULOONGARCHState *env, \ ++ uint ## bits ## _t arg) \ ++{ \ ++ return float_ ## name(arg, &env->active_fpu.fp_status); \ ++} ++ ++FLOAT_CLASS(class_s, 32) ++FLOAT_CLASS(class_d, 64) ++#undef FLOAT_CLASS ++ ++/* binary operations */ ++#define FLOAT_BINOP(name) \ ++uint64_t helper_float_ ## name ## _d(CPULOONGARCHState *env, \ ++ uint64_t fdt0, uint64_t fdt1) \ ++{ \ ++ uint64_t dt2; \ ++ \ ++ dt2 = float64_ ## name(fdt0, fdt1, &env->active_fpu.fp_status);\ ++ update_fcsr0(env, GETPC()); \ ++ return dt2; \ ++} \ ++ \ ++uint32_t helper_float_ ## name ## _s(CPULOONGARCHState *env, \ ++ uint32_t fst0, uint32_t fst1) \ ++{ \ ++ uint32_t wt2; \ ++ \ ++ wt2 = float32_ ## name(fst0, fst1, &env->active_fpu.fp_status);\ ++ update_fcsr0(env, GETPC()); \ ++ return wt2; \ ++} ++ ++FLOAT_BINOP(add) ++FLOAT_BINOP(sub) ++FLOAT_BINOP(mul) ++FLOAT_BINOP(div) ++#undef FLOAT_BINOP ++ ++uint64_t helper_float_exp2_d(CPULOONGARCHState *env, ++ uint64_t fdt0, uint64_t fdt1) ++{ ++ uint64_t dt2; ++ int64_t n = (int64_t)fdt1; ++ ++ dt2 = float64_scalbn(fdt0, ++ n > 0x1000 ? 0x1000 : ++ n < -0x1000 ? -0x1000 : n, ++ &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++uint32_t helper_float_exp2_s(CPULOONGARCHState *env, ++ uint32_t fst0, uint32_t fst1) ++{ ++ uint32_t wt2; ++ int32_t n = (int32_t)fst1; ++ ++ wt2 = float32_scalbn(fst0, ++ n > 0x200 ? 0x200 : ++ n < -0x200 ? -0x200 : n, ++ &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++#define FLOAT_MINMAX(name, bits, minmaxfunc) \ ++uint ## bits ## _t helper_float_ ## name(CPULOONGARCHState *env, \ ++ uint ## bits ## _t fs, \ ++ uint ## bits ## _t ft) \ ++{ \ ++ uint ## bits ## _t fdret; \ ++ \ ++ fdret = float ## bits ## _ ## minmaxfunc(fs, ft, \ ++ &env->active_fpu.fp_status); \ ++ update_fcsr0(env, GETPC()); \ ++ return fdret; \ ++} ++ ++FLOAT_MINMAX(max_s, 32, maxnum) ++FLOAT_MINMAX(max_d, 64, maxnum) ++FLOAT_MINMAX(maxa_s, 32, maxnummag) ++FLOAT_MINMAX(maxa_d, 64, maxnummag) ++ ++FLOAT_MINMAX(min_s, 32, minnum) ++FLOAT_MINMAX(min_d, 64, minnum) ++FLOAT_MINMAX(mina_s, 32, minnummag) ++FLOAT_MINMAX(mina_d, 64, minnummag) ++#undef FLOAT_MINMAX ++ ++#define FLOAT_FMADDSUB(name, bits, muladd_arg) \ ++uint ## bits ## _t helper_float_ ## name(CPULOONGARCHState *env, \ ++ uint ## bits ## _t fs, \ ++ uint ## bits ## _t ft, \ ++ uint ## bits ## _t fd) \ ++{ \ ++ uint ## bits ## _t fdret; \ ++ \ ++ fdret = float ## bits ## _muladd(fs, ft, fd, muladd_arg, \ ++ &env->active_fpu.fp_status); \ ++ update_fcsr0(env, GETPC()); \ ++ return fdret; \ ++} ++ ++FLOAT_FMADDSUB(maddf_s, 32, 0) ++FLOAT_FMADDSUB(maddf_d, 64, 0) ++FLOAT_FMADDSUB(msubf_s, 32, float_muladd_negate_c) ++FLOAT_FMADDSUB(msubf_d, 64, float_muladd_negate_c) ++FLOAT_FMADDSUB(nmaddf_s, 32, float_muladd_negate_result) ++FLOAT_FMADDSUB(nmaddf_d, 64, float_muladd_negate_result) ++FLOAT_FMADDSUB(nmsubf_s, 32, float_muladd_negate_result | float_muladd_negate_c) ++FLOAT_FMADDSUB(nmsubf_d, 64, float_muladd_negate_result | float_muladd_negate_c) ++#undef FLOAT_FMADDSUB ++ ++/* compare operations */ ++#define FOP_CONDN_D(op, cond) \ ++uint64_t helper_cmp_d_ ## op(CPULOONGARCHState *env, uint64_t fdt0, \ ++ uint64_t fdt1) \ ++{ \ ++ uint64_t c; \ ++ c = cond; \ ++ update_fcsr0(env, GETPC()); \ ++ if (c) { \ ++ return -1; \ ++ } else { \ ++ return 0; \ ++ } \ ++} ++ ++/* ++ * NOTE: the comma operator will make "cond" to eval to false, ++ * but float64_unordered_quiet() is still called. ++ */ ++FOP_CONDN_D(af, (float64_unordered_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status), 0)) ++FOP_CONDN_D(un, (float64_unordered_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(eq, (float64_eq_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_eq_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(lt, (float64_lt_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(le, (float64_le_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_le_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++/* ++ * NOTE: the comma operator will make "cond" to eval to false, ++ * but float64_unordered() is still called. ++ */ ++FOP_CONDN_D(saf, (float64_unordered(fdt1, fdt0, ++ &env->active_fpu.fp_status), 0)) ++FOP_CONDN_D(sun, (float64_unordered(fdt1, fdt0, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(seq, (float64_eq(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_eq(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(slt, (float64_lt(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sle, (float64_le(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_le(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(or, (float64_le_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_le_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(une, (float64_unordered_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(ne, (float64_lt_quiet(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt_quiet(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sor, (float64_le(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_le(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_D(sne, (float64_lt(fdt1, fdt0, ++ &env->active_fpu.fp_status) ++ || float64_lt(fdt0, fdt1, ++ &env->active_fpu.fp_status))) ++ ++#define FOP_CONDN_S(op, cond) \ ++uint32_t helper_cmp_s_ ## op(CPULOONGARCHState *env, uint32_t fst0, \ ++ uint32_t fst1) \ ++{ \ ++ uint64_t c; \ ++ c = cond; \ ++ update_fcsr0(env, GETPC()); \ ++ if (c) { \ ++ return -1; \ ++ } else { \ ++ return 0; \ ++ } \ ++} ++ ++/* ++ * NOTE: the comma operator will make "cond" to eval to false, ++ * but float32_unordered_quiet() is still called. ++ */ ++FOP_CONDN_S(af, (float32_unordered_quiet(fst1, fst0, ++ &env->active_fpu.fp_status), 0)) ++FOP_CONDN_S(un, (float32_unordered_quiet(fst1, fst0, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(eq, (float32_eq_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(ueq, (float32_unordered_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_eq_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(lt, (float32_lt_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(ult, (float32_unordered_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(le, (float32_le_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(ule, (float32_unordered_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_le_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++/* ++ * NOTE: the comma operator will make "cond" to eval to false, ++ * but float32_unordered() is still called. ++ */ ++FOP_CONDN_S(saf, (float32_unordered(fst1, fst0, ++ &env->active_fpu.fp_status), 0)) ++FOP_CONDN_S(sun, (float32_unordered(fst1, fst0, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(seq, (float32_eq(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_eq(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(slt, (float32_lt(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sult, (float32_unordered(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sle, (float32_le(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sule, (float32_unordered(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_le(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(or, (float32_le_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_le_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(une, (float32_unordered_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(ne, (float32_lt_quiet(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt_quiet(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sor, (float32_le(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_le(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sune, (float32_unordered(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt(fst0, fst1, ++ &env->active_fpu.fp_status))) ++FOP_CONDN_S(sne, (float32_lt(fst1, fst0, ++ &env->active_fpu.fp_status) ++ || float32_lt(fst0, fst1, ++ &env->active_fpu.fp_status))) ++ ++uint32_t helper_float_logb_s(CPULOONGARCHState *env, uint32_t fst0) ++{ ++ uint32_t wt2; ++ ++ wt2 = float32_log2(fst0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return wt2; ++} ++ ++uint64_t helper_float_logb_d(CPULOONGARCHState *env, uint64_t fdt0) ++{ ++ uint64_t dt2; ++ ++ dt2 = float64_log2(fdt0, &env->active_fpu.fp_status); ++ update_fcsr0(env, GETPC()); ++ return dt2; ++} ++ ++target_ulong helper_fsel(CPULOONGARCHState *env, target_ulong fj, ++ target_ulong fk, uint32_t ca) ++{ ++ if (env->active_fpu.cf[ca & 0x7]) { ++ return fk; ++ } else { ++ return fj; ++ } ++} +diff --git a/target/loongarch64/fpu_helper.h b/target/loongarch64/fpu_helper.h +new file mode 100644 +index 000000000..b6898c2e9 +--- /dev/null ++++ b/target/loongarch64/fpu_helper.h +@@ -0,0 +1,129 @@ ++/* loongarch internal definitions and helpers ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or later. ++ * See the COPYING file in the top-level directory. ++ */ ++ ++#ifndef LOONGARCH_FPU_H ++#define LOONGARCH_FPU_H ++ ++#include "cpu-csr.h" ++ ++ ++extern const struct loongarch_def_t loongarch_defs[]; ++extern const int loongarch_defs_number; ++ ++enum CPULSXDataFormat { ++ DF_BYTE = 0, ++ DF_HALF, ++ DF_WORD, ++ DF_DOUBLE, ++ DF_QUAD ++}; ++ ++void loongarch_cpu_do_interrupt(CPUState *cpu); ++bool loongarch_cpu_exec_interrupt(CPUState *cpu, int int_req); ++void loongarch_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, ++ MMUAccessType access_type, ++ int mmu_idx, uintptr_t retaddr) QEMU_NORETURN; ++ ++#if !defined(CONFIG_USER_ONLY) ++ ++typedef struct r4k_tlb_t r4k_tlb_t; ++struct r4k_tlb_t { ++ target_ulong VPN; ++ uint32_t PageMask; ++ uint16_t ASID; ++ unsigned int G:1; ++ unsigned int C0:3; ++ unsigned int C1:3; ++ unsigned int V0:1; ++ unsigned int V1:1; ++ unsigned int D0:1; ++ unsigned int D1:1; ++ unsigned int XI0:1; ++ unsigned int XI1:1; ++ unsigned int RI0:1; ++ unsigned int RI1:1; ++ unsigned int EHINV:1; ++ uint64_t PPN[2]; ++}; ++ ++int no_mmu_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, ++ target_ulong address, int rw, int access_type); ++int fixed_mmu_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, ++ target_ulong address, int rw, int access_type); ++int r4k_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, ++ target_ulong address, int rw, int access_type); ++ ++/* loongarch 3a5000 tlb helper function : lisa csr */ ++int ls3a5k_map_address(CPULOONGARCHState *env, hwaddr *physical, ++ int *prot, target_ulong address, ++ int rw, int access_type); ++void ls3a5k_helper_tlbwr(CPULOONGARCHState *env); ++void ls3a5k_helper_tlbfill(CPULOONGARCHState *env); ++void ls3a5k_helper_tlbsrch(CPULOONGARCHState *env); ++void ls3a5k_helper_tlbrd(CPULOONGARCHState *env); ++void ls3a5k_helper_tlbclr(CPULOONGARCHState *env); ++void ls3a5k_helper_tlbflush(CPULOONGARCHState *env); ++void ls3a5k_invalidate_tlb(CPULOONGARCHState *env, int idx); ++void ls3a5k_helper_invtlb(CPULOONGARCHState *env, target_ulong addr, ++ target_ulong info, int op); ++void ls3a5k_flush_vtlb(CPULOONGARCHState *env); ++void ls3a5k_flush_ftlb(CPULOONGARCHState *env); ++/*void loongarch_cpu_unassigned_access(CPUState *cpu, hwaddr addr, ++ bool is_write, bool is_exec, int unused, ++ unsigned size); ++*/ ++hwaddr cpu_loongarch_translate_address(CPULOONGARCHState *env, target_ulong address, ++ int rw); ++#endif ++ ++#define cpu_signal_handler cpu_loongarch_signal_handler ++ ++ ++static inline bool cpu_loongarch_hw_interrupts_enabled(CPULOONGARCHState *env) ++{ ++ bool ret = 0; ++ ++ ret = env->CSR_CRMD & (1 << CSR_CRMD_IE_SHIFT); ++ ++ return ret; ++} ++ ++ ++void loongarch_tcg_init(void); ++ ++ ++/* helper.c */ ++bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, ++ MMUAccessType access_type, int mmu_idx, ++ bool probe, uintptr_t retaddr); ++ ++/* op_helper.c */ ++uint32_t float_class_s(uint32_t arg, float_status *fst); ++uint64_t float_class_d(uint64_t arg, float_status *fst); ++ ++int ieee_ex_to_loongarch(int xcpt); ++void update_pagemask(CPULOONGARCHState *env, target_ulong arg1, int32_t *pagemask); ++ ++void cpu_loongarch_tlb_flush(CPULOONGARCHState *env); ++void sync_c0_status(CPULOONGARCHState *env, CPULOONGARCHState *cpu, int tc); ++ ++void QEMU_NORETURN do_raise_exception_err(CPULOONGARCHState *env, uint32_t exception, ++ int error_code, uintptr_t pc); ++int loongarch_read_qxfer(CPUState *cs, const char *annex, ++ uint8_t *read_buf, ++ unsigned long offset, unsigned long len); ++int loongarch_write_qxfer(CPUState *cs, const char *annex, ++ const uint8_t *write_buf, ++ unsigned long offset, unsigned long len); ++ ++static inline void QEMU_NORETURN do_raise_exception(CPULOONGARCHState *env, ++ uint32_t exception, ++ uintptr_t pc) ++{ ++ do_raise_exception_err(env, exception, 0, pc); ++} ++ ++#endif +diff --git a/target/loongarch64/gdbstub.c b/target/loongarch64/gdbstub.c +new file mode 100644 +index 000000000..4013178f4 +--- /dev/null ++++ b/target/loongarch64/gdbstub.c +@@ -0,0 +1,109 @@ ++/* ++ * LOONGARCH gdb server stub ++ * ++ * Copyright (c) 2003-2005 Fabrice Bellard ++ * Copyright (c) 2013 SUSE LINUX Products GmbH ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#include "qemu/osdep.h" ++#include "qemu-common.h" ++#include "cpu.h" ++#include "internal.h" ++#include "exec/gdbstub.h" ++#ifdef CONFIG_TCG ++#include "exec/helper-proto.h" ++#endif ++int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ ++ if (0 <= n && n < 32) { ++ return gdb_get_regl(mem_buf, env->active_tc.gpr[n]); ++ } else if (n == 32) { ++ return gdb_get_regl(mem_buf, env->active_tc.PC); ++ } ++ return 0; ++} ++ ++int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ target_ulong tmp = ldtul_p(mem_buf); ++ ++ if (0 <= n && n < 32) { ++ return env->active_tc.gpr[n] = tmp, sizeof(target_ulong); ++ } else if (n == 32) { ++ return env->active_tc.PC = tmp, sizeof(target_ulong); ++ } ++ return 0; ++} ++ ++static int loongarch_gdb_get_fpu(CPULOONGARCHState *env, GByteArray *mem_buf, int n) ++{ ++ if (0 <= n && n < 32) { ++ return gdb_get_reg64(mem_buf, env->active_fpu.fpr[n].d); ++ } else if (32 <= n && n < 40) { ++ return gdb_get_reg8(mem_buf, env->active_fpu.cf[n - 32]); ++ } else if (n == 40) { ++ return gdb_get_reg32(mem_buf, env->active_fpu.fcsr0); ++ } ++ return 0; ++} ++ ++static int loongarch_gdb_set_fpu(CPULOONGARCHState *env, uint8_t *mem_buf, int n) ++{ ++ if (0 <= n && n < 32) { ++ return env->active_fpu.fpr[n].d = ldq_p(mem_buf), 8; ++ } else if (32 <= n && n < 40) { ++ return env->active_fpu.cf[n - 32] = ldub_p(mem_buf), 1; ++ } else if (n == 40) { ++ return env->active_fpu.fcsr0 = ldl_p(mem_buf), 4; ++ } ++ return 0; ++} ++ ++void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs) ++{ ++ gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, ++ 41, "loongarch-fpu64.xml", 0); ++} ++ ++#ifdef CONFIG_TCG ++int loongarch_read_qxfer(CPUState *cs, const char *annex, uint8_t *read_buf, ++ unsigned long offset, unsigned long len) ++{ ++ if (strncmp(annex, "cpucfg", sizeof("cpucfg") - 1) == 0) { ++ if (offset % 4 != 0 || len % 4 != 0) { ++ return 0; ++ } ++ ++ size_t i; ++ for (i = offset; i < offset + len; i += 4) ++ ((uint32_t *)read_buf)[(i - offset) / 4] = ++ helper_cpucfg(&(LOONGARCH_CPU(cs)->env), i / 4); ++ return 32 * 4; ++ } ++ return 0; ++} ++ ++int loongarch_write_qxfer(CPUState *cs, const char *annex, ++ const uint8_t *write_buf, unsigned long offset, ++ unsigned long len) ++{ ++ return 0; ++} ++#endif +diff --git a/target/loongarch64/helper.c b/target/loongarch64/helper.c +new file mode 100644 +index 000000000..841240e57 +--- /dev/null ++++ b/target/loongarch64/helper.c +@@ -0,0 +1,727 @@ ++/* ++ * LOONGARCH emulation helpers for qemu. ++ * ++ * Copyright (c) 2004-2005 Jocelyn Mayer ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#include "qemu/osdep.h" ++#include "cpu.h" ++#include "internal.h" ++#include "exec/exec-all.h" ++#include "exec/cpu_ldst.h" ++#include "exec/log.h" ++#include "hw/loongarch/cpudevs.h" ++ ++ ++#if !defined(CONFIG_USER_ONLY) ++ ++static int ls3a5k_map_address_tlb_entry( ++ CPULOONGARCHState *env, ++ hwaddr *physical, ++ int *prot, ++ target_ulong address, ++ int rw, ++ int access_type, ++ ls3a5k_tlb_t *tlb) ++{ ++ uint64_t mask = tlb->PageMask; ++ int n = !!(address & mask & ~(mask >> 1)); ++ uint32_t plv = env->CSR_CRMD & CSR_CRMD_PLV; ++ ++ /* Check access rights */ ++ if (!(n ? tlb->V1 : tlb->V0)) { ++ return TLBRET_INVALID; ++ } ++ ++ if (rw == MMU_INST_FETCH && (n ? tlb->XI1 : tlb->XI0)) { ++ return TLBRET_XI; ++ } ++ ++ if (rw == MMU_DATA_LOAD && (n ? tlb->RI1 : tlb->RI0)) { ++ return TLBRET_RI; ++ } ++ ++ if (plv > (n ? tlb->PLV1 : tlb->PLV0)) { ++ return TLBRET_PE; ++ } ++ ++ if (rw != MMU_DATA_STORE || (n ? tlb->WE1 : tlb->WE0)) { ++ /* PPN address ++ * 4 KB: [47:13] [12;0] ++ * 16 KB: [47:15] [14:0] ++ */ ++ if (n) { ++ *physical = tlb->PPN1 | (address & (mask >> 1)); ++ } else { ++ *physical = tlb->PPN0 | (address & (mask >> 1)); ++ } ++ *prot = PAGE_READ; ++ if (n ? tlb->WE1 : tlb->WE0) { ++ *prot |= PAGE_WRITE; ++ } ++ if (!(n ? tlb->XI1 : tlb->XI0)) { ++ *prot |= PAGE_EXEC; ++ } ++ return TLBRET_MATCH; ++ } ++ ++ return TLBRET_DIRTY; ++} ++ ++/* Loongarch 3A5K -style MMU emulation */ ++int ls3a5k_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, ++ target_ulong address, int rw, int access_type) ++{ ++ uint16_t asid = env->CSR_ASID & 0x3ff; ++ int i; ++ ls3a5k_tlb_t *tlb; ++ ++ int ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; ++ int vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; ++ ++ int ftlb_idx; ++ ++ uint64_t mask; ++ uint64_t vpn; /* address to map */ ++ uint64_t tag; /* address in TLB entry */ ++ ++ /* search VTLB */ ++ for (i = ftlb_size; i < ftlb_size + vtlb_size; ++i) { ++ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ mask = tlb->PageMask; ++ ++ vpn = address & 0xffffffffe000 & ~mask; ++ tag = tlb->VPN & ~mask; ++ ++ if ((tlb->G == 1 || tlb->ASID == asid) ++ && vpn == tag ++ && tlb->EHINV != 1) ++ { ++ return ls3a5k_map_address_tlb_entry(env, physical, prot, ++ address, rw, access_type, tlb); ++ } ++ } ++ ++ if (ftlb_size == 0) { ++ return TLBRET_NOMATCH; ++ } ++ ++ /* search FTLB */ ++ mask = env->tlb->mmu.ls3a5k.ftlb_mask; ++ vpn = address & 0xffffffffe000 & ~mask; ++ ++ ftlb_idx = (address & 0xffffffffc000) >> 15; /* 16 KB */ ++ ftlb_idx = ftlb_idx & 0xff; /* [0,255] */ ++ ++ for (i = 0; i < 8; ++i) { ++ /* ---------- set 0 1 2 ... 7 ++ * ftlb_idx ----------------------------------- ++ * 0 | 0 1 2 ... 7 ++ * 1 | 8 9 10 ... 15 ++ * 2 | 16 17 18 ... 23 ++ * ... | ++ * 255 | 2040 2041 2042 ... 2047 ++ */ ++ tlb = &env->tlb->mmu.ls3a5k.tlb[ftlb_idx * 8 + i]; ++ tag = tlb->VPN & ~mask; ++ ++ if ((tlb->G == 1 || tlb->ASID == asid) ++ && vpn == tag ++ && tlb->EHINV != 1) ++ { ++ return ls3a5k_map_address_tlb_entry(env, physical, prot, ++ address, rw, access_type, tlb); ++ } ++ } ++ ++ return TLBRET_NOMATCH; ++} ++ ++static int get_physical_address(CPULOONGARCHState *env, hwaddr *physical, ++ int *prot, target_ulong real_address, ++ int rw, int access_type, int mmu_idx) ++{ ++ int user_mode = mmu_idx == LARCH_HFLAG_UM; ++ int kernel_mode = !user_mode; ++ unsigned plv, base_c, base_v, tmp; ++ ++ /* effective address (modified for KVM T&E kernel segments) */ ++ target_ulong address = real_address; ++ ++ /* Check PG */ ++ if (!(env->CSR_CRMD & CSR_CRMD_PG)) { ++ /* DA mode */ ++ *physical = address & 0xffffffffffffUL; ++ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ++ return TLBRET_MATCH; ++ } ++ ++ plv = kernel_mode | (user_mode << 3); ++ base_v = address >> CSR_DMW_BASE_SH; ++ /* Check direct map window 0 */ ++ base_c = env->CSR_DMWIN0 >> CSR_DMW_BASE_SH; ++ if ((plv & env->CSR_DMWIN0) && (base_c == base_v)) { ++ *physical = dmwin_va2pa(address); ++ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ++ return TLBRET_MATCH; ++ } ++ /* Check direct map window 1 */ ++ base_c = env->CSR_DMWIN1 >> CSR_DMW_BASE_SH; ++ if ((plv & env->CSR_DMWIN1) && (base_c == base_v)) { ++ *physical = dmwin_va2pa(address); ++ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ++ return TLBRET_MATCH; ++ } ++ /* Check valid extension */ ++ tmp = address >> 47; ++ if (!(tmp == 0 || tmp == 0x1ffff)) { ++ return TLBRET_BADADDR; ++ } ++ /* mapped address */ ++ return env->tlb->map_address(env, physical, prot, real_address, rw, ++ access_type); ++} ++ ++void cpu_loongarch_tlb_flush(CPULOONGARCHState *env) ++{ ++ LOONGARCHCPU *cpu = loongarch_env_get_cpu(env); ++ ++ /* Flush qemu's TLB and discard all shadowed entries. */ ++ tlb_flush(CPU(cpu)); ++ env->tlb->tlb_in_use = env->tlb->nb_tlb; ++} ++#endif ++ ++static void raise_mmu_exception(CPULOONGARCHState *env, target_ulong address, ++ int rw, int tlb_error) ++{ ++ CPUState *cs = CPU(loongarch_env_get_cpu(env)); ++ int exception = 0, error_code = 0; ++ ++ if (rw == MMU_INST_FETCH) { ++ error_code |= EXCP_INST_NOTAVAIL; ++ } ++ ++ switch (tlb_error) { ++ default: ++ case TLBRET_BADADDR: ++ /* Reference to kernel address from user mode or supervisor mode */ ++ /* Reference to supervisor address from user mode */ ++ if (rw == MMU_DATA_STORE) { ++ exception = EXCP_AdES; ++ } else { ++ exception = EXCP_AdEL; ++ } ++ break; ++ case TLBRET_NOMATCH: ++ /* No TLB match for a mapped address */ ++ if (rw == MMU_DATA_STORE) { ++ exception = EXCP_TLBS; ++ } else { ++ exception = EXCP_TLBL; ++ } ++ error_code |= EXCP_TLB_NOMATCH; ++ break; ++ case TLBRET_INVALID: ++ /* TLB match with no valid bit */ ++ if (rw == MMU_DATA_STORE) { ++ exception = EXCP_TLBS; ++ } else { ++ exception = EXCP_TLBL; ++ } ++ break; ++ case TLBRET_DIRTY: ++ /* TLB match but 'D' bit is cleared */ ++ exception = EXCP_LTLBL; ++ break; ++ case TLBRET_XI: ++ /* Execute-Inhibit Exception */ ++ exception = EXCP_TLBXI; ++ break; ++ case TLBRET_RI: ++ /* Read-Inhibit Exception */ ++ exception = EXCP_TLBRI; ++ break; ++ case TLBRET_PE: ++ /* Privileged Exception */ ++ exception = EXCP_TLBPE; ++ break; ++ } ++ ++ if (env->insn_flags & INSN_LOONGARCH) { ++ if (tlb_error == TLBRET_NOMATCH) { ++ env->CSR_TLBRBADV = address; ++ env->CSR_TLBREHI = address & (TARGET_PAGE_MASK << 1); ++ cs->exception_index = exception; ++ env->error_code = error_code; ++ return; ++ } ++ } ++ ++ /* Raise exception */ ++ env->CSR_BADV = address; ++ cs->exception_index = exception; ++ env->error_code = error_code; ++ ++ if (env->insn_flags & INSN_LOONGARCH) { ++ env->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1); ++ } ++} ++ ++bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, ++ MMUAccessType access_type, int mmu_idx, ++ bool probe, uintptr_t retaddr) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++#if !defined(CONFIG_USER_ONLY) ++ hwaddr physical; ++ int prot; ++ int loongarch_access_type; ++#endif ++ int ret = TLBRET_BADADDR; ++ ++ qemu_log_mask(CPU_LOG_MMU, ++ "%s pc " TARGET_FMT_lx " ad %" VADDR_PRIx " mmu_idx %d\n", ++ __func__, env->active_tc.PC, address, mmu_idx); ++ ++ /* data access */ ++#if !defined(CONFIG_USER_ONLY) ++ /* XXX: put correct access by using cpu_restore_state() correctly */ ++ loongarch_access_type = ACCESS_INT; ++ ret = get_physical_address(env, &physical, &prot, address, ++ access_type, loongarch_access_type, mmu_idx); ++ switch (ret) { ++ case TLBRET_MATCH: ++ qemu_log_mask(CPU_LOG_MMU, ++ "%s address=%" VADDR_PRIx " physical " TARGET_FMT_plx ++ " prot %d asid %ld pc 0x%lx\n", ++ __func__, address, physical, prot, ++ env->CSR_ASID, env->active_tc.PC); ++ break; ++ default: ++ qemu_log_mask(CPU_LOG_MMU, ++ "%s address=%" VADDR_PRIx " ret %d asid %ld pc 0x%lx\n", ++ __func__, address, ret, env->CSR_ASID, env->active_tc.PC); ++ break; ++ } ++ if (ret == TLBRET_MATCH) { ++ tlb_set_page(cs, address & TARGET_PAGE_MASK, ++ physical & TARGET_PAGE_MASK, prot | PAGE_EXEC, ++ mmu_idx, TARGET_PAGE_SIZE); ++ ret = true; ++ } ++ if (probe) { ++ return false; ++ } ++#endif ++ ++ raise_mmu_exception(env, address, access_type, ret); ++ do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr); ++} ++ ++#if !defined(CONFIG_USER_ONLY) ++hwaddr cpu_loongarch_translate_address(CPULOONGARCHState *env, ++ target_ulong address, int rw) ++{ ++ hwaddr physical; ++ int prot; ++ int access_type; ++ int ret = 0; ++ ++ /* data access */ ++ access_type = ACCESS_INT; ++ ret = get_physical_address(env, &physical, &prot, address, rw, access_type, ++ cpu_mmu_index(env, false)); ++ if (ret != TLBRET_MATCH) { ++ raise_mmu_exception(env, address, rw, ret); ++ return -1LL; ++ } else { ++ return physical; ++ } ++} ++ ++static const char * const excp_names[EXCP_LAST + 1] = { ++ [EXCP_RESET] = "reset", ++ [EXCP_SRESET] = "soft reset", ++ [EXCP_NMI] = "non-maskable interrupt", ++ [EXCP_EXT_INTERRUPT] = "interrupt", ++ [EXCP_AdEL] = "address error load", ++ [EXCP_AdES] = "address error store", ++ [EXCP_TLBF] = "TLB refill", ++ [EXCP_IBE] = "instruction bus error", ++ [EXCP_SYSCALL] = "syscall", ++ [EXCP_BREAK] = "break", ++ [EXCP_FPDIS] = "float unit unusable", ++ [EXCP_LSXDIS] = "vector128 unusable", ++ [EXCP_LASXDIS] = "vector256 unusable", ++ [EXCP_RI] = "reserved instruction", ++ [EXCP_OVERFLOW] = "arithmetic overflow", ++ [EXCP_TRAP] = "trap", ++ [EXCP_FPE] = "floating point", ++ [EXCP_LTLBL] = "TLB modify", ++ [EXCP_TLBL] = "TLB load", ++ [EXCP_TLBS] = "TLB store", ++ [EXCP_DBE] = "data bus error", ++ [EXCP_TLBXI] = "TLB execute-inhibit", ++ [EXCP_TLBRI] = "TLB read-inhibit", ++ [EXCP_TLBPE] = "TLB priviledged error", ++}; ++#endif ++ ++target_ulong exception_resume_pc(CPULOONGARCHState *env) ++{ ++ target_ulong bad_pc; ++ ++ bad_pc = env->active_tc.PC; ++ if (env->hflags & LARCH_HFLAG_BMASK) { ++ /* If the exception was raised from a delay slot, come back to ++ the jump. */ ++ bad_pc -= 4; ++ } ++ ++ return bad_pc; ++} ++ ++#if !defined(CONFIG_USER_ONLY) ++static void set_hflags_for_handler (CPULOONGARCHState *env) ++{ ++ /* Exception handlers are entered in 32-bit mode. */ ++} ++ ++static inline void set_badinstr_registers(CPULOONGARCHState *env) ++{ ++ if ((env->insn_flags & INSN_LOONGARCH)) { ++ env->CSR_BADI = cpu_ldl_code(env, env->active_tc.PC); ++ return; ++ } ++} ++#endif ++ ++static inline unsigned int get_vint_size(CPULOONGARCHState *env) ++{ ++ unsigned int size = 0; ++ ++ switch ((env->CSR_ECFG >> 16) & 0x7) { ++ case 0: ++ break; ++ case 1: ++ size = 2 * 4; /* #Insts * inst_size */ ++ break; ++ case 2: ++ size = 4 * 4; ++ break; ++ case 3: ++ size = 8 * 4; ++ break; ++ case 4: ++ size = 16 * 4; ++ break; ++ case 5: ++ size = 32 * 4; ++ break; ++ case 6: ++ size = 64 * 4; ++ break; ++ case 7: ++ size = 128 * 4; ++ break; ++ default: ++ printf("%s: unexpected value", __func__); ++ assert(0); ++ } ++ ++ return size; ++} ++ ++#define is_refill(cs, env) (((cs->exception_index == EXCP_TLBL) \ ++ || (cs->exception_index == EXCP_TLBS)) \ ++ && (env->error_code & EXCP_TLB_NOMATCH)) ++ ++void loongarch_cpu_do_interrupt(CPUState *cs) ++{ ++#if !defined(CONFIG_USER_ONLY) ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ bool update_badinstr = 0; ++ int cause = -1; ++ const char *name; ++ ++ if (qemu_loglevel_mask(CPU_LOG_INT) ++ && cs->exception_index != EXCP_EXT_INTERRUPT) { ++ if (cs->exception_index < 0 || cs->exception_index > EXCP_LAST) { ++ name = "unknown"; ++ } else { ++ name = excp_names[cs->exception_index]; ++ } ++ ++ qemu_log("%s enter: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx ++ " TLBRERA 0x%016lx" " %s exception\n", __func__, ++ env->active_tc.PC, env->CSR_ERA, env->CSR_TLBRERA, name); ++ } ++ ++ switch (cs->exception_index) { ++ case EXCP_RESET: ++ cpu_reset(CPU(cpu)); ++ break; ++ case EXCP_NMI: ++ env->CSR_ERRERA = exception_resume_pc(env); ++ env->hflags &= ~LARCH_HFLAG_BMASK; ++ env->hflags |= LARCH_HFLAG_64; ++ env->hflags &= ~LARCH_HFLAG_AWRAP; ++ env->hflags &= ~(LARCH_HFLAG_KSU); ++ env->active_tc.PC = env->exception_base; ++ set_hflags_for_handler(env); ++ break; ++ case EXCP_EXT_INTERRUPT: ++ cause = 0; ++ goto set_ERA; ++ case EXCP_LTLBL: ++ cause = 1; ++ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); ++ goto set_ERA; ++ case EXCP_TLBL: ++ cause = 2; ++ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); ++ goto set_ERA; ++ case EXCP_TLBS: ++ cause = 3; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_AdEL: ++ cause = 4; ++ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); ++ goto set_ERA; ++ case EXCP_AdES: ++ cause = 5; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_IBE: ++ cause = 6; ++ goto set_ERA; ++ case EXCP_DBE: ++ cause = 7; ++ goto set_ERA; ++ case EXCP_SYSCALL: ++ cause = 8; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_BREAK: ++ cause = 9; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_RI: ++ cause = 10; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_FPDIS: ++ case EXCP_LSXDIS: ++ case EXCP_LASXDIS: ++ cause = 11; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_OVERFLOW: ++ cause = 12; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_TRAP: ++ cause = 13; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_FPE: ++ cause = 15; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_TLBRI: ++ cause = 19; ++ update_badinstr = 1; ++ goto set_ERA; ++ case EXCP_TLBXI: ++ case EXCP_TLBPE: ++ cause = 20; ++ goto set_ERA; ++ set_ERA: ++ if (is_refill(cs, env)) { ++ env->CSR_TLBRERA = exception_resume_pc(env); ++ env->CSR_TLBRERA |= 1; ++ } else { ++ env->CSR_ERA = exception_resume_pc(env); ++ } ++ ++ if (update_badinstr) { ++ set_badinstr_registers(env); ++ } ++ env->hflags &= ~(LARCH_HFLAG_KSU); ++ ++ env->hflags &= ~LARCH_HFLAG_BMASK; ++ if (env->insn_flags & INSN_LOONGARCH) { ++ /* save PLV and IE */ ++ if (is_refill(cs, env)) { ++ env->CSR_TLBRPRMD &= (~0x7); ++ env->CSR_TLBRPRMD |= (env->CSR_CRMD & 0x7); ++ } else { ++ env->CSR_PRMD &= (~0x7); ++ env->CSR_PRMD |= (env->CSR_CRMD & 0x7); ++ } ++ ++ env->CSR_CRMD &= ~(0x7); ++ ++ switch (cs->exception_index) { ++ case EXCP_EXT_INTERRUPT: ++ break; ++ case EXCP_TLBL: ++ if (env->error_code & EXCP_INST_NOTAVAIL) { ++ cause = EXCCODE_TLBI; ++ } else { ++ cause = EXCCODE_TLBL; ++ } ++ break; ++ case EXCP_TLBS: ++ cause = EXCCODE_TLBS; ++ break; ++ case EXCP_LTLBL: ++ cause = EXCCODE_MOD; ++ break; ++ case EXCP_TLBRI: ++ cause = EXCCODE_TLBRI; ++ break; ++ case EXCP_TLBXI: ++ cause = EXCCODE_TLBXI; ++ break; ++ case EXCP_TLBPE: ++ cause = EXCCODE_TLBPE; ++ break; ++ case EXCP_AdEL: ++ case EXCP_AdES: ++ case EXCP_IBE: ++ case EXCP_DBE: ++ cause = EXCCODE_ADE; ++ break; ++ case EXCP_SYSCALL: ++ cause = EXCCODE_SYS; ++ break; ++ case EXCP_BREAK: ++ cause = EXCCODE_BP; ++ break; ++ case EXCP_RI: ++ cause = EXCCODE_RI; ++ break; ++ case EXCP_FPDIS: ++ cause = EXCCODE_FPDIS; ++ break; ++ case EXCP_LSXDIS: ++ cause = EXCCODE_LSXDIS; ++ break; ++ case EXCP_LASXDIS: ++ cause = EXCCODE_LASXDIS; ++ break; ++ case EXCP_FPE: ++ cause = EXCCODE_FPE; ++ break; ++ default: ++ printf("Error: exception(%d) '%s' has not been supported\n", ++ cs->exception_index, excp_names[cs->exception_index]); ++ abort(); ++ } ++ ++ uint32_t vec_size = get_vint_size(env); ++ env->active_tc.PC = env->CSR_EEPN; ++ env->active_tc.PC += cause * vec_size; ++ if (is_refill(cs, env)) { ++ /* TLB Refill */ ++ env->active_tc.PC = env->CSR_TLBRENT; ++ break; /* Do not modify excode */ ++ } ++ if (cs->exception_index == EXCP_EXT_INTERRUPT) { ++ /* Interrupt */ ++ uint32_t vector = 0; ++ uint32_t pending = env->CSR_ESTAT & CSR_ESTAT_IPMASK; ++ pending &= env->CSR_ECFG & CSR_ECFG_IPMASK; ++ ++ /* Find the highest-priority interrupt. */ ++ while (pending >>= 1) { ++ vector++; ++ } ++ env->active_tc.PC = env->CSR_EEPN + ++ (EXCODE_IP + vector) * vec_size; ++ if (qemu_loglevel_mask(CPU_LOG_INT)) { ++ qemu_log("%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx ++ " cause %d\n" " A " TARGET_FMT_lx " D " ++ TARGET_FMT_lx " vector = %d ExC %08lx ExS %08lx\n", ++ __func__, env->active_tc.PC, env->CSR_ERA, ++ cause, env->CSR_BADV, env->CSR_DERA, vector, ++ env->CSR_ECFG, env->CSR_ESTAT); ++ } ++ } ++ /* Excode */ ++ env->CSR_ESTAT = (env->CSR_ESTAT & ~(0x1f << CSR_ESTAT_EXC_SH)) | ++ (cause << CSR_ESTAT_EXC_SH); ++ } ++ set_hflags_for_handler(env); ++ break; ++ default: ++ abort(); ++ } ++ if (qemu_loglevel_mask(CPU_LOG_INT) ++ && cs->exception_index != EXCP_EXT_INTERRUPT) { ++ qemu_log("%s: PC " TARGET_FMT_lx " ERA 0x%08lx" " cause %d%s\n" ++ " ESTAT %08lx EXCFG 0x%08lx BADVA 0x%08lx BADI 0x%08lx \ ++ SYS_NUM %lu cpu %d asid 0x%lx" "\n", ++ __func__, env->active_tc.PC, ++ is_refill(cs, env) ? env->CSR_TLBRERA : env->CSR_ERA, ++ cause, ++ is_refill(cs, env) ? "(refill)" : "", ++ env->CSR_ESTAT, env->CSR_ECFG, ++ is_refill(cs, env) ? env->CSR_TLBRBADV : env->CSR_BADV, ++ env->CSR_BADI, env->active_tc.gpr[11], cs->cpu_index, ++ env->CSR_ASID ++ ); ++ } ++#endif ++ cs->exception_index = EXCP_NONE; ++} ++ ++bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request) ++{ ++ if (interrupt_request & CPU_INTERRUPT_HARD) { ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ ++ if (cpu_loongarch_hw_interrupts_enabled(env) && ++ cpu_loongarch_hw_interrupts_pending(env)) { ++ /* Raise it */ ++ cs->exception_index = EXCP_EXT_INTERRUPT; ++ env->error_code = 0; ++ loongarch_cpu_do_interrupt(cs); ++ return true; ++ } ++ } ++ return false; ++} ++ ++void QEMU_NORETURN do_raise_exception_err(CPULOONGARCHState *env, ++ uint32_t exception, ++ int error_code, ++ uintptr_t pc) ++{ ++ CPUState *cs = CPU(loongarch_env_get_cpu(env)); ++ ++ qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n", ++ __func__, exception, error_code); ++ cs->exception_index = exception; ++ env->error_code = error_code; ++ ++ cpu_loop_exit_restore(cs, pc); ++} +diff --git a/target/loongarch64/helper.h b/target/loongarch64/helper.h +new file mode 100644 +index 000000000..ff2026ed8 +--- /dev/null ++++ b/target/loongarch64/helper.h +@@ -0,0 +1,168 @@ ++DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int) ++DEF_HELPER_2(raise_exception, noreturn, env, i32) ++DEF_HELPER_1(raise_exception_debug, noreturn, env) ++ ++#if 0 ++#ifndef CONFIG_USER_ONLY ++DEF_HELPER_3(ll, tl, env, tl, int) ++DEF_HELPER_3(lld, tl, env, tl, int) ++#endif ++#endif ++ ++DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl) ++DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl) ++ ++DEF_HELPER_3(crc32, tl, tl, tl, i32) ++DEF_HELPER_3(crc32c, tl, tl, tl, i32) ++ ++#ifndef CONFIG_USER_ONLY ++/* LoongISA CSR register */ ++DEF_HELPER_2(csr_rdq, tl, env, i64) ++DEF_HELPER_3(csr_wrq, tl, env, tl, i64) ++DEF_HELPER_4(csr_xchgq, tl, env, tl, tl, i64) ++ ++#endif /* !CONFIG_USER_ONLY */ ++ ++/* CP1 functions */ ++DEF_HELPER_2(movfcsr2gr, tl, env, i32) ++DEF_HELPER_4(movgr2fcsr, void, env, tl, i32, i32) ++ ++DEF_HELPER_2(float_cvtd_s, i64, env, i32) ++DEF_HELPER_2(float_cvtd_w, i64, env, i32) ++DEF_HELPER_2(float_cvtd_l, i64, env, i64) ++DEF_HELPER_2(float_cvts_d, i32, env, i64) ++DEF_HELPER_2(float_cvts_w, i32, env, i32) ++DEF_HELPER_2(float_cvts_l, i32, env, i64) ++ ++DEF_HELPER_FLAGS_2(float_class_s, TCG_CALL_NO_RWG_SE, i32, env, i32) ++DEF_HELPER_FLAGS_2(float_class_d, TCG_CALL_NO_RWG_SE, i64, env, i64) ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_4(float_ ## op ## _s, i32, env, i32, i32, i32) \ ++DEF_HELPER_4(float_ ## op ## _d, i64, env, i64, i64, i64) ++FOP_PROTO(maddf) ++FOP_PROTO(msubf) ++FOP_PROTO(nmaddf) ++FOP_PROTO(nmsubf) ++#undef FOP_PROTO ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_3(float_ ## op ## _s, i32, env, i32, i32) \ ++DEF_HELPER_3(float_ ## op ## _d, i64, env, i64, i64) ++FOP_PROTO(max) ++FOP_PROTO(maxa) ++FOP_PROTO(min) ++FOP_PROTO(mina) ++#undef FOP_PROTO ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_2(float_ ## op ## _l_s, i64, env, i32) \ ++DEF_HELPER_2(float_ ## op ## _l_d, i64, env, i64) \ ++DEF_HELPER_2(float_ ## op ## _w_s, i32, env, i32) \ ++DEF_HELPER_2(float_ ## op ## _w_d, i32, env, i64) ++FOP_PROTO(cvt) ++FOP_PROTO(round) ++FOP_PROTO(trunc) ++FOP_PROTO(ceil) ++FOP_PROTO(floor) ++#undef FOP_PROTO ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_2(float_ ## op ## _s, i32, env, i32) \ ++DEF_HELPER_2(float_ ## op ## _d, i64, env, i64) ++FOP_PROTO(sqrt) ++FOP_PROTO(rsqrt) ++FOP_PROTO(recip) ++FOP_PROTO(rint) ++#undef FOP_PROTO ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_1(float_ ## op ## _s, i32, i32) \ ++DEF_HELPER_1(float_ ## op ## _d, i64, i64) ++FOP_PROTO(abs) ++FOP_PROTO(chs) ++#undef FOP_PROTO ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_3(float_ ## op ## _s, i32, env, i32, i32) \ ++DEF_HELPER_3(float_ ## op ## _d, i64, env, i64, i64) ++FOP_PROTO(add) ++FOP_PROTO(sub) ++FOP_PROTO(mul) ++FOP_PROTO(div) ++#undef FOP_PROTO ++ ++#define FOP_PROTO(op) \ ++DEF_HELPER_3(cmp_d_ ## op, i64, env, i64, i64) \ ++DEF_HELPER_3(cmp_s_ ## op, i32, env, i32, i32) ++FOP_PROTO(af) ++FOP_PROTO(un) ++FOP_PROTO(eq) ++FOP_PROTO(ueq) ++FOP_PROTO(lt) ++FOP_PROTO(ult) ++FOP_PROTO(le) ++FOP_PROTO(ule) ++FOP_PROTO(saf) ++FOP_PROTO(sun) ++FOP_PROTO(seq) ++FOP_PROTO(sueq) ++FOP_PROTO(slt) ++FOP_PROTO(sult) ++FOP_PROTO(sle) ++FOP_PROTO(sule) ++FOP_PROTO(or) ++FOP_PROTO(une) ++FOP_PROTO(ne) ++FOP_PROTO(sor) ++FOP_PROTO(sune) ++FOP_PROTO(sne) ++#undef FOP_PROTO ++ ++/* Special functions */ ++#ifndef CONFIG_USER_ONLY ++DEF_HELPER_1(tlbwr, void, env) ++DEF_HELPER_1(tlbfill, void, env) ++DEF_HELPER_1(tlbsrch, void, env) ++DEF_HELPER_1(tlbrd, void, env) ++DEF_HELPER_1(tlbclr, void, env) ++DEF_HELPER_1(tlbflush, void, env) ++DEF_HELPER_4(invtlb, void, env, tl, tl, tl) ++DEF_HELPER_1(ertn, void, env) ++DEF_HELPER_5(lddir, void, env, tl, tl, tl, i32) ++DEF_HELPER_4(ldpte, void, env, tl, tl, i32) ++DEF_HELPER_3(drdtime, void, env, tl, tl) ++DEF_HELPER_1(read_pgd, tl, env) ++#endif /* !CONFIG_USER_ONLY */ ++DEF_HELPER_2(cpucfg, tl, env, tl) ++DEF_HELPER_1(idle, void, env) ++ ++DEF_HELPER_3(float_exp2_s, i32, env, i32, i32) ++DEF_HELPER_3(float_exp2_d, i64, env, i64, i64) ++DEF_HELPER_2(float_logb_s, i32, env, i32) ++DEF_HELPER_2(float_logb_d, i64, env, i64) ++DEF_HELPER_3(movreg2cf, void, env, i32, tl) ++DEF_HELPER_2(movcf2reg, tl, env, i32) ++DEF_HELPER_3(movreg2cf_i32, void, env, i32, i32) ++DEF_HELPER_3(movreg2cf_i64, void, env, i32, i64) ++ ++DEF_HELPER_2(cto_w, tl, env, tl) ++DEF_HELPER_2(ctz_w, tl, env, tl) ++DEF_HELPER_2(cto_d, tl, env, tl) ++DEF_HELPER_2(ctz_d, tl, env, tl) ++DEF_HELPER_2(bitrev_w, tl, env, tl) ++DEF_HELPER_2(bitrev_d, tl, env, tl) ++ ++DEF_HELPER_2(load_scr, i64, env, i32) ++DEF_HELPER_3(store_scr, void, env, i32, i64) ++ ++DEF_HELPER_3(asrtle_d, void, env, tl, tl) ++DEF_HELPER_3(asrtgt_d, void, env, tl, tl) ++ ++DEF_HELPER_4(fsel, i64, env, i64, i64, i32) ++ ++#ifndef CONFIG_USER_ONLY ++DEF_HELPER_4(iocsr, void, env, tl, tl, i32) ++#endif ++DEF_HELPER_3(memtrace_addr, void, env, tl, i32) ++DEF_HELPER_2(memtrace_val, void, env, tl) +diff --git a/target/loongarch64/insn.decode b/target/loongarch64/insn.decode +new file mode 100644 +index 000000000..f194f7011 +--- /dev/null ++++ b/target/loongarch64/insn.decode +@@ -0,0 +1,514 @@ ++# Fields ++%sd 0:2 ++%rj 5:5 ++%rd 0:5 ++%sj 5:2 ++%ptr 5:3 ++%rk 10:5 ++%sa2 15:2 ++%sa3 15:3 ++%si5 10:s5 ++%code 0:15 ++%cond 10:4 ++%cond2 0:4 ++%ui5 10:5 ++%ui6 10:6 ++%ui3 10:3 ++%ui4 10:4 ++%op 5:5 ++%ui8 10:8 ++%msbw 16:5 ++%lsbw 10:5 ++%msbd 16:6 ++%lsbd 10:6 ++%fd 0:5 ++%fj 5:5 ++%fk 10:5 ++%fcsrd 0:5 ++%fcsrs 5:5 ++%cd 0:3 ++%cj 5:3 ++%si12 10:s12 ++%ui12 10:12 ++%csr 10:14 ++%cop 0:5 ++%level 10:8 ++%seq 10:8 ++%whint 0:15 ++%addr 10:5 ++%info 5:5 ++%invop 0:5 ++%fa 15:5 ++%vd 0:5 ++%vj 5:5 ++%vk 10:5 ++%va 15:5 ++%xd 0:5 ++%xj 5:5 ++%xk 10:5 ++%xa 15:5 ++%fcond 15:5 ++%ca 15:3 ++%vui5 15:5 ++%si16 10:s16 ++%si20 5:s20 ++%si14 10:s14 ++%hint 0:5 ++%si9 10:s9 ++%si10 10:s10 ++%si11 10:s11 ++%si8 10:s8 ++%idx1 18:1 ++%idx2 18:2 ++%idx3 18:3 ++%idx4 18:4 ++%idx 18:5 ++%offs21 0:s5 10:16 ++%offs16 10:s16 ++%offs 0:s10 10:16 ++%mode 5:5 ++%ui2 10:2 ++%ui1 10:1 ++%ui7 10:7 ++%i13 5:13 ++ ++# Argument sets ++&fmt_sdrj sd rj ++&fmt_rdsj rd sj ++&fmt_rdrj rd rj ++&fmt_empty ++&fmt_rjrk rj rk ++&fmt_rdrjrksa2 rd rj rk sa2 ++&fmt_rdrjrksa3 rd rj rk sa3 ++&fmt_rdrjrk rd rj rk ++&fmt_code code ++&fmt_rdrjui5 rd rj ui5 ++&fmt_rdrjui6 rd rj ui6 ++&fmt_rdrjmsbwlsbw rd rj msbw lsbw ++&fmt_rdrjmsbdlsbd rd rj msbd lsbd ++&fmt_fdfjfk fd fj fk ++&fmt_fdfj fd fj ++&fmt_fdrj fd rj ++&fmt_rdfj rd fj ++&fmt_fcsrdrj fcsrd rj ++&fmt_rdfcsrs rd fcsrs ++&fmt_cdfj cd fj ++&fmt_fdcj fd cj ++&fmt_cdrj cd rj ++&fmt_rdcj rd cj ++&fmt_rdrjsi12 rd rj si12 ++&fmt_rdrjui12 rd rj ui12 ++&fmt_rdrjcsr rd rj csr ++&fmt_coprjsi12 cop rj si12 ++&fmt_rdrjlevel rd rj level ++&fmt_rjseq rj seq ++&fmt_whint whint ++&fmt_invtlb addr info invop ++&fmt_fdfjfkfa fd fj fk fa ++&fmt_cdfjfkfcond cd fj fk fcond ++&fmt_fdfjfkca fd fj fk ca ++&fmt_rdrjsi16 rd rj si16 ++&fmt_rdsi20 rd si20 ++&fmt_rdrjsi14 rd rj si14 ++&fmt_hintrjsi12 hint rj si12 ++&fmt_fdrjsi12 fd rj si12 ++&fmt_fdrjrk fd rj rk ++&fmt_rjoffs21 rj offs21 ++&fmt_cjoffs21 cj offs21 ++&fmt_rdrjoffs16 rd rj offs16 ++&fmt_offs offs ++&fmt_rjrdoffs16 rj rd offs16 ++ ++# Formats ++@fmt_sdrj .... ........ ..... ..... ..... ... .. &fmt_sdrj %sd %rj ++@fmt_rdsj .... ........ ..... ..... ... .. ..... &fmt_rdsj %rd %sj ++@fmt_rdrj .... ........ ..... ..... ..... ..... &fmt_rdrj %rd %rj ++@fmt_empty .... ........ ..... ..... ..... ..... &fmt_empty ++@fmt_rjrk .... ........ ..... ..... ..... ..... &fmt_rjrk %rj %rk ++@fmt_rdrjrksa2 .... ........ ... .. ..... ..... ..... &fmt_rdrjrksa2 %rd %rj %rk %sa2 ++@fmt_rdrjrksa3 .... ........ .. ... ..... ..... ..... &fmt_rdrjrksa3 %rd %rj %rk %sa3 ++@fmt_rdrjrk .... ........ ..... ..... ..... ..... &fmt_rdrjrk %rd %rj %rk ++@fmt_code .... ........ ..... ............... &fmt_code %code ++@fmt_rdrjui5 .... ........ ..... ..... ..... ..... &fmt_rdrjui5 %rd %rj %ui5 ++@fmt_rdrjui6 .... ........ .... ...... ..... ..... &fmt_rdrjui6 %rd %rj %ui6 ++@fmt_rdrjmsbwlsbw .... ....... ..... . ..... ..... ..... &fmt_rdrjmsbwlsbw %rd %rj %msbw %lsbw ++@fmt_rdrjmsbdlsbd .... ...... ...... ...... ..... ..... &fmt_rdrjmsbdlsbd %rd %rj %msbd %lsbd ++@fmt_fdfjfk .... ........ ..... ..... ..... ..... &fmt_fdfjfk %fd %fj %fk ++@fmt_fdfj .... ........ ..... ..... ..... ..... &fmt_fdfj %fd %fj ++@fmt_fdrj .... ........ ..... ..... ..... ..... &fmt_fdrj %fd %rj ++@fmt_rdfj .... ........ ..... ..... ..... ..... &fmt_rdfj %rd %fj ++@fmt_fcsrdrj .... ........ ..... ..... ..... ..... &fmt_fcsrdrj %fcsrd %rj ++@fmt_rdfcsrs .... ........ ..... ..... ..... ..... &fmt_rdfcsrs %rd %fcsrs ++@fmt_cdfj .... ........ ..... ..... ..... .. ... &fmt_cdfj %cd %fj ++@fmt_fdcj .... ........ ..... ..... .. ... ..... &fmt_fdcj %fd %cj ++@fmt_cdrj .... ........ ..... ..... ..... .. ... &fmt_cdrj %cd %rj ++@fmt_rdcj .... ........ ..... ..... .. ... ..... &fmt_rdcj %rd %cj ++@fmt_rdrjsi12 .... ...... ............ ..... ..... &fmt_rdrjsi12 %rd %rj %si12 ++@fmt_rdrjui12 .... ...... ............ ..... ..... &fmt_rdrjui12 %rd %rj %ui12 ++@fmt_rdrjcsr .... .... .............. ..... ..... &fmt_rdrjcsr %rd %rj %csr ++@fmt_coprjsi12 .... ...... ............ ..... ..... &fmt_coprjsi12 %cop %rj %si12 ++@fmt_rdrjlevel .... ........ .. ........ ..... ..... &fmt_rdrjlevel %rd %rj %level ++@fmt_rjseq .... ........ .. ........ ..... ..... &fmt_rjseq %rj %seq ++@fmt_whint .... ........ ..... ............... &fmt_whint %whint ++@fmt_invtlb ...... ...... ..... ..... ..... ..... &fmt_invtlb %addr %info %invop ++@fmt_fdfjfkfa .... ........ ..... ..... ..... ..... &fmt_fdfjfkfa %fd %fj %fk %fa ++@fmt_cdfjfkfcond .... ........ ..... ..... ..... .. ... &fmt_cdfjfkfcond %cd %fj %fk %fcond ++@fmt_fdfjfkca .... ........ .. ... ..... ..... ..... &fmt_fdfjfkca %fd %fj %fk %ca ++@fmt_rdrjsi16 .... .. ................ ..... ..... &fmt_rdrjsi16 %rd %rj %si16 ++@fmt_rdsi20 .... ... .................... ..... &fmt_rdsi20 %rd %si20 ++@fmt_rdrjsi14 .... .... .............. ..... ..... &fmt_rdrjsi14 %rd %rj %si14 ++@fmt_hintrjsi12 .... ...... ............ ..... ..... &fmt_hintrjsi12 %hint %rj %si12 ++@fmt_fdrjsi12 .... ...... ............ ..... ..... &fmt_fdrjsi12 %fd %rj %si12 ++@fmt_fdrjrk .... ........ ..... ..... ..... ..... &fmt_fdrjrk %fd %rj %rk ++@fmt_rjoffs21 .... .. ................ ..... ..... &fmt_rjoffs21 %rj %offs21 ++@fmt_cjoffs21 .... .. ................ .. ... ..... &fmt_cjoffs21 %cj %offs21 ++@fmt_rdrjoffs16 .... .. ................ ..... ..... &fmt_rdrjoffs16 %rd %rj %offs16 ++@fmt_offs .... .. .......................... &fmt_offs %offs ++@fmt_rjrdoffs16 .... .. ................ ..... ..... &fmt_rjrdoffs16 %rj %rd %offs16 ++ ++# Instructions ++ ++# Fiexd point arithmetic Instructions ++gr2scr 0000 00000000 00000 00010 ..... 000 .. @fmt_sdrj ++scr2gr 0000 00000000 00000 00011 000 .. ..... @fmt_rdsj ++clo_w 0000 00000000 00000 00100 ..... ..... @fmt_rdrj ++clz_w 0000 00000000 00000 00101 ..... ..... @fmt_rdrj ++cto_w 0000 00000000 00000 00110 ..... ..... @fmt_rdrj ++ctz_w 0000 00000000 00000 00111 ..... ..... @fmt_rdrj ++clo_d 0000 00000000 00000 01000 ..... ..... @fmt_rdrj ++clz_d 0000 00000000 00000 01001 ..... ..... @fmt_rdrj ++cto_d 0000 00000000 00000 01010 ..... ..... @fmt_rdrj ++ctz_d 0000 00000000 00000 01011 ..... ..... @fmt_rdrj ++revb_2h 0000 00000000 00000 01100 ..... ..... @fmt_rdrj ++revb_4h 0000 00000000 00000 01101 ..... ..... @fmt_rdrj ++revb_2w 0000 00000000 00000 01110 ..... ..... @fmt_rdrj ++revb_d 0000 00000000 00000 01111 ..... ..... @fmt_rdrj ++revh_2w 0000 00000000 00000 10000 ..... ..... @fmt_rdrj ++revh_d 0000 00000000 00000 10001 ..... ..... @fmt_rdrj ++bitrev_4b 0000 00000000 00000 10010 ..... ..... @fmt_rdrj ++bitrev_8b 0000 00000000 00000 10011 ..... ..... @fmt_rdrj ++bitrev_w 0000 00000000 00000 10100 ..... ..... @fmt_rdrj ++bitrev_d 0000 00000000 00000 10101 ..... ..... @fmt_rdrj ++ext_w_h 0000 00000000 00000 10110 ..... ..... @fmt_rdrj ++ext_w_b 0000 00000000 00000 10111 ..... ..... @fmt_rdrj ++rdtime_d 0000 00000000 00000 11010 ..... ..... @fmt_rdrj ++cpucfg 0000 00000000 00000 11011 ..... ..... @fmt_rdrj ++asrtle_d 0000 00000000 00010 ..... ..... 00000 @fmt_rjrk ++asrtgt_d 0000 00000000 00011 ..... ..... 00000 @fmt_rjrk ++alsl_w 0000 00000000 010 .. ..... ..... ..... @fmt_rdrjrksa2 ++alsl_wu 0000 00000000 011 .. ..... ..... ..... @fmt_rdrjrksa2 ++bytepick_w 0000 00000000 100 .. ..... ..... ..... @fmt_rdrjrksa2 ++bytepick_d 0000 00000000 11 ... ..... ..... ..... @fmt_rdrjrksa3 ++add_w 0000 00000001 00000 ..... ..... ..... @fmt_rdrjrk ++add_d 0000 00000001 00001 ..... ..... ..... @fmt_rdrjrk ++sub_w 0000 00000001 00010 ..... ..... ..... @fmt_rdrjrk ++sub_d 0000 00000001 00011 ..... ..... ..... @fmt_rdrjrk ++slt 0000 00000001 00100 ..... ..... ..... @fmt_rdrjrk ++sltu 0000 00000001 00101 ..... ..... ..... @fmt_rdrjrk ++maskeqz 0000 00000001 00110 ..... ..... ..... @fmt_rdrjrk ++masknez 0000 00000001 00111 ..... ..... ..... @fmt_rdrjrk ++nor 0000 00000001 01000 ..... ..... ..... @fmt_rdrjrk ++and 0000 00000001 01001 ..... ..... ..... @fmt_rdrjrk ++or 0000 00000001 01010 ..... ..... ..... @fmt_rdrjrk ++xor 0000 00000001 01011 ..... ..... ..... @fmt_rdrjrk ++orn 0000 00000001 01100 ..... ..... ..... @fmt_rdrjrk ++andn 0000 00000001 01101 ..... ..... ..... @fmt_rdrjrk ++sll_w 0000 00000001 01110 ..... ..... ..... @fmt_rdrjrk ++srl_w 0000 00000001 01111 ..... ..... ..... @fmt_rdrjrk ++sra_w 0000 00000001 10000 ..... ..... ..... @fmt_rdrjrk ++sll_d 0000 00000001 10001 ..... ..... ..... @fmt_rdrjrk ++srl_d 0000 00000001 10010 ..... ..... ..... @fmt_rdrjrk ++sra_d 0000 00000001 10011 ..... ..... ..... @fmt_rdrjrk ++rotr_w 0000 00000001 10110 ..... ..... ..... @fmt_rdrjrk ++rotr_d 0000 00000001 10111 ..... ..... ..... @fmt_rdrjrk ++mul_w 0000 00000001 11000 ..... ..... ..... @fmt_rdrjrk ++mulh_w 0000 00000001 11001 ..... ..... ..... @fmt_rdrjrk ++mulh_wu 0000 00000001 11010 ..... ..... ..... @fmt_rdrjrk ++mul_d 0000 00000001 11011 ..... ..... ..... @fmt_rdrjrk ++mulh_d 0000 00000001 11100 ..... ..... ..... @fmt_rdrjrk ++mulh_du 0000 00000001 11101 ..... ..... ..... @fmt_rdrjrk ++mulw_d_w 0000 00000001 11110 ..... ..... ..... @fmt_rdrjrk ++mulw_d_wu 0000 00000001 11111 ..... ..... ..... @fmt_rdrjrk ++div_w 0000 00000010 00000 ..... ..... ..... @fmt_rdrjrk ++mod_w 0000 00000010 00001 ..... ..... ..... @fmt_rdrjrk ++div_wu 0000 00000010 00010 ..... ..... ..... @fmt_rdrjrk ++mod_wu 0000 00000010 00011 ..... ..... ..... @fmt_rdrjrk ++div_d 0000 00000010 00100 ..... ..... ..... @fmt_rdrjrk ++mod_d 0000 00000010 00101 ..... ..... ..... @fmt_rdrjrk ++div_du 0000 00000010 00110 ..... ..... ..... @fmt_rdrjrk ++mod_du 0000 00000010 00111 ..... ..... ..... @fmt_rdrjrk ++crc_w_b_w 0000 00000010 01000 ..... ..... ..... @fmt_rdrjrk ++crc_w_h_w 0000 00000010 01001 ..... ..... ..... @fmt_rdrjrk ++crc_w_w_w 0000 00000010 01010 ..... ..... ..... @fmt_rdrjrk ++crc_w_d_w 0000 00000010 01011 ..... ..... ..... @fmt_rdrjrk ++crcc_w_b_w 0000 00000010 01100 ..... ..... ..... @fmt_rdrjrk ++crcc_w_h_w 0000 00000010 01101 ..... ..... ..... @fmt_rdrjrk ++crcc_w_w_w 0000 00000010 01110 ..... ..... ..... @fmt_rdrjrk ++crcc_w_d_w 0000 00000010 01111 ..... ..... ..... @fmt_rdrjrk ++break 0000 00000010 10100 ............... @fmt_code ++dbcl 0000 00000010 10101 ............... @fmt_code ++syscall 0000 00000010 10110 ............... @fmt_code ++alsl_d 0000 00000010 110 .. ..... ..... ..... @fmt_rdrjrksa2 ++slli_w 0000 00000100 00001 ..... ..... ..... @fmt_rdrjui5 ++slli_d 0000 00000100 0001 ...... ..... ..... @fmt_rdrjui6 ++srli_w 0000 00000100 01001 ..... ..... ..... @fmt_rdrjui5 ++srli_d 0000 00000100 0101 ...... ..... ..... @fmt_rdrjui6 ++srai_w 0000 00000100 10001 ..... ..... ..... @fmt_rdrjui5 ++srai_d 0000 00000100 1001 ...... ..... ..... @fmt_rdrjui6 ++rotri_w 0000 00000100 11001 ..... ..... ..... @fmt_rdrjui5 ++rotri_d 0000 00000100 1101 ...... ..... ..... @fmt_rdrjui6 ++bstrins_w 0000 0000011 ..... 0 ..... ..... ..... @fmt_rdrjmsbwlsbw ++bstrpick_w 0000 0000011 ..... 1 ..... ..... ..... @fmt_rdrjmsbwlsbw ++bstrins_d 0000 000010 ...... ...... ..... ..... @fmt_rdrjmsbdlsbd ++bstrpick_d 0000 000011 ...... ...... ..... ..... @fmt_rdrjmsbdlsbd ++ ++# float Instructions ++fadd_s 0000 00010000 00001 ..... ..... ..... @fmt_fdfjfk ++fadd_d 0000 00010000 00010 ..... ..... ..... @fmt_fdfjfk ++fsub_s 0000 00010000 00101 ..... ..... ..... @fmt_fdfjfk ++fsub_d 0000 00010000 00110 ..... ..... ..... @fmt_fdfjfk ++fmul_s 0000 00010000 01001 ..... ..... ..... @fmt_fdfjfk ++fmul_d 0000 00010000 01010 ..... ..... ..... @fmt_fdfjfk ++fdiv_s 0000 00010000 01101 ..... ..... ..... @fmt_fdfjfk ++fdiv_d 0000 00010000 01110 ..... ..... ..... @fmt_fdfjfk ++fmax_s 0000 00010000 10001 ..... ..... ..... @fmt_fdfjfk ++fmax_d 0000 00010000 10010 ..... ..... ..... @fmt_fdfjfk ++fmin_s 0000 00010000 10101 ..... ..... ..... @fmt_fdfjfk ++fmin_d 0000 00010000 10110 ..... ..... ..... @fmt_fdfjfk ++fmaxa_s 0000 00010000 11001 ..... ..... ..... @fmt_fdfjfk ++fmaxa_d 0000 00010000 11010 ..... ..... ..... @fmt_fdfjfk ++fmina_s 0000 00010000 11101 ..... ..... ..... @fmt_fdfjfk ++fmina_d 0000 00010000 11110 ..... ..... ..... @fmt_fdfjfk ++fscaleb_s 0000 00010001 00001 ..... ..... ..... @fmt_fdfjfk ++fscaleb_d 0000 00010001 00010 ..... ..... ..... @fmt_fdfjfk ++fcopysign_s 0000 00010001 00101 ..... ..... ..... @fmt_fdfjfk ++fcopysign_d 0000 00010001 00110 ..... ..... ..... @fmt_fdfjfk ++fabs_s 0000 00010001 01000 00001 ..... ..... @fmt_fdfj ++fabs_d 0000 00010001 01000 00010 ..... ..... @fmt_fdfj ++fneg_s 0000 00010001 01000 00101 ..... ..... @fmt_fdfj ++fneg_d 0000 00010001 01000 00110 ..... ..... @fmt_fdfj ++flogb_s 0000 00010001 01000 01001 ..... ..... @fmt_fdfj ++flogb_d 0000 00010001 01000 01010 ..... ..... @fmt_fdfj ++fclass_s 0000 00010001 01000 01101 ..... ..... @fmt_fdfj ++fclass_d 0000 00010001 01000 01110 ..... ..... @fmt_fdfj ++fsqrt_s 0000 00010001 01000 10001 ..... ..... @fmt_fdfj ++fsqrt_d 0000 00010001 01000 10010 ..... ..... @fmt_fdfj ++frecip_s 0000 00010001 01000 10101 ..... ..... @fmt_fdfj ++frecip_d 0000 00010001 01000 10110 ..... ..... @fmt_fdfj ++frsqrt_s 0000 00010001 01000 11001 ..... ..... @fmt_fdfj ++frsqrt_d 0000 00010001 01000 11010 ..... ..... @fmt_fdfj ++fmov_s 0000 00010001 01001 00101 ..... ..... @fmt_fdfj ++fmov_d 0000 00010001 01001 00110 ..... ..... @fmt_fdfj ++movgr2fr_w 0000 00010001 01001 01001 ..... ..... @fmt_fdrj ++movgr2fr_d 0000 00010001 01001 01010 ..... ..... @fmt_fdrj ++movgr2frh_w 0000 00010001 01001 01011 ..... ..... @fmt_fdrj ++movfr2gr_s 0000 00010001 01001 01101 ..... ..... @fmt_rdfj ++movfr2gr_d 0000 00010001 01001 01110 ..... ..... @fmt_rdfj ++movfrh2gr_s 0000 00010001 01001 01111 ..... ..... @fmt_rdfj ++movgr2fcsr 0000 00010001 01001 10000 ..... ..... @fmt_fcsrdrj ++movfcsr2gr 0000 00010001 01001 10010 ..... ..... @fmt_rdfcsrs ++movfr2cf 0000 00010001 01001 10100 ..... 00 ... @fmt_cdfj ++movcf2fr 0000 00010001 01001 10101 00 ... ..... @fmt_fdcj ++movgr2cf 0000 00010001 01001 10110 ..... 00 ... @fmt_cdrj ++movcf2gr 0000 00010001 01001 10111 00 ... ..... @fmt_rdcj ++fcvt_s_d 0000 00010001 10010 00110 ..... ..... @fmt_fdfj ++fcvt_d_s 0000 00010001 10010 01001 ..... ..... @fmt_fdfj ++ftintrm_w_s 0000 00010001 10100 00001 ..... ..... @fmt_fdfj ++ftintrm_w_d 0000 00010001 10100 00010 ..... ..... @fmt_fdfj ++ftintrm_l_s 0000 00010001 10100 01001 ..... ..... @fmt_fdfj ++ftintrm_l_d 0000 00010001 10100 01010 ..... ..... @fmt_fdfj ++ftintrp_w_s 0000 00010001 10100 10001 ..... ..... @fmt_fdfj ++ftintrp_w_d 0000 00010001 10100 10010 ..... ..... @fmt_fdfj ++ftintrp_l_s 0000 00010001 10100 11001 ..... ..... @fmt_fdfj ++ftintrp_l_d 0000 00010001 10100 11010 ..... ..... @fmt_fdfj ++ftintrz_w_s 0000 00010001 10101 00001 ..... ..... @fmt_fdfj ++ftintrz_w_d 0000 00010001 10101 00010 ..... ..... @fmt_fdfj ++ftintrz_l_s 0000 00010001 10101 01001 ..... ..... @fmt_fdfj ++ftintrz_l_d 0000 00010001 10101 01010 ..... ..... @fmt_fdfj ++ftintrne_w_s 0000 00010001 10101 10001 ..... ..... @fmt_fdfj ++ftintrne_w_d 0000 00010001 10101 10010 ..... ..... @fmt_fdfj ++ftintrne_l_s 0000 00010001 10101 11001 ..... ..... @fmt_fdfj ++ftintrne_l_d 0000 00010001 10101 11010 ..... ..... @fmt_fdfj ++ftint_w_s 0000 00010001 10110 00001 ..... ..... @fmt_fdfj ++ftint_w_d 0000 00010001 10110 00010 ..... ..... @fmt_fdfj ++ftint_l_s 0000 00010001 10110 01001 ..... ..... @fmt_fdfj ++ftint_l_d 0000 00010001 10110 01010 ..... ..... @fmt_fdfj ++ffint_s_w 0000 00010001 11010 00100 ..... ..... @fmt_fdfj ++ffint_s_l 0000 00010001 11010 00110 ..... ..... @fmt_fdfj ++ffint_d_w 0000 00010001 11010 01000 ..... ..... @fmt_fdfj ++ffint_d_l 0000 00010001 11010 01010 ..... ..... @fmt_fdfj ++frint_s 0000 00010001 11100 10001 ..... ..... @fmt_fdfj ++frint_d 0000 00010001 11100 10010 ..... ..... @fmt_fdfj ++ ++# 12 bit immediate Instructions ++slti 0000 001000 ............ ..... ..... @fmt_rdrjsi12 ++sltui 0000 001001 ............ ..... ..... @fmt_rdrjsi12 ++addi_w 0000 001010 ............ ..... ..... @fmt_rdrjsi12 ++addi_d 0000 001011 ............ ..... ..... @fmt_rdrjsi12 ++lu52i_d 0000 001100 ............ ..... ..... @fmt_rdrjsi12 ++andi 0000 001101 ............ ..... ..... @fmt_rdrjui12 ++ori 0000 001110 ............ ..... ..... @fmt_rdrjui12 ++xori 0000 001111 ............ ..... ..... @fmt_rdrjui12 ++ ++# core Instructions ++csrxchg 0000 0100 .............. ..... ..... @fmt_rdrjcsr ++cacop 0000 011000 ............ ..... ..... @fmt_coprjsi12 ++lddir 0000 01100100 00 ........ ..... ..... @fmt_rdrjlevel ++ldpte 0000 01100100 01 ........ ..... 00000 @fmt_rjseq ++iocsrrd_b 0000 01100100 10000 00000 ..... ..... @fmt_rdrj ++iocsrrd_h 0000 01100100 10000 00001 ..... ..... @fmt_rdrj ++iocsrrd_w 0000 01100100 10000 00010 ..... ..... @fmt_rdrj ++iocsrrd_d 0000 01100100 10000 00011 ..... ..... @fmt_rdrj ++iocsrwr_b 0000 01100100 10000 00100 ..... ..... @fmt_rdrj ++iocsrwr_h 0000 01100100 10000 00101 ..... ..... @fmt_rdrj ++iocsrwr_w 0000 01100100 10000 00110 ..... ..... @fmt_rdrj ++iocsrwr_d 0000 01100100 10000 00111 ..... ..... @fmt_rdrj ++tlbclr 0000 01100100 10000 01000 00000 00000 @fmt_empty ++tlbflush 0000 01100100 10000 01001 00000 00000 @fmt_empty ++tlbsrch 0000 01100100 10000 01010 00000 00000 @fmt_empty ++tlbrd 0000 01100100 10000 01011 00000 00000 @fmt_empty ++tlbwr 0000 01100100 10000 01100 00000 00000 @fmt_empty ++tlbfill 0000 01100100 10000 01101 00000 00000 @fmt_empty ++ertn 0000 01100100 10000 01110 00000 00000 @fmt_empty ++idle 0000 01100100 10001 ............... @fmt_whint ++invtlb 0000 01100100 10011 ..... ..... ..... @fmt_invtlb ++ ++# foure Op Instructions ++fmadd_s 0000 10000001 ..... ..... ..... ..... @fmt_fdfjfkfa ++fmadd_d 0000 10000010 ..... ..... ..... ..... @fmt_fdfjfkfa ++fmsub_s 0000 10000101 ..... ..... ..... ..... @fmt_fdfjfkfa ++fmsub_d 0000 10000110 ..... ..... ..... ..... @fmt_fdfjfkfa ++fnmadd_s 0000 10001001 ..... ..... ..... ..... @fmt_fdfjfkfa ++fnmadd_d 0000 10001010 ..... ..... ..... ..... @fmt_fdfjfkfa ++fnmsub_s 0000 10001101 ..... ..... ..... ..... @fmt_fdfjfkfa ++fnmsub_d 0000 10001110 ..... ..... ..... ..... @fmt_fdfjfkfa ++fcmp_cond_s 0000 11000001 ..... ..... ..... 00 ... @fmt_cdfjfkfcond ++fcmp_cond_d 0000 11000010 ..... ..... ..... 00 ... @fmt_cdfjfkfcond ++fsel 0000 11010000 00 ... ..... ..... ..... @fmt_fdfjfkca ++ ++# loog immediate Instructions ++addu16i_d 0001 00 ................ ..... ..... @fmt_rdrjsi16 ++lu12i_w 0001 010 .................... ..... @fmt_rdsi20 ++lu32i_d 0001 011 .................... ..... @fmt_rdsi20 ++pcaddi 0001 100 .................... ..... @fmt_rdsi20 ++pcalau12i 0001 101 .................... ..... @fmt_rdsi20 ++pcaddu12i 0001 110 .................... ..... @fmt_rdsi20 ++pcaddu18i 0001 111 .................... ..... @fmt_rdsi20 ++ ++# load/store Instructions ++ll_w 0010 0000 .............. ..... ..... @fmt_rdrjsi14 ++sc_w 0010 0001 .............. ..... ..... @fmt_rdrjsi14 ++ll_d 0010 0010 .............. ..... ..... @fmt_rdrjsi14 ++sc_d 0010 0011 .............. ..... ..... @fmt_rdrjsi14 ++ldptr_w 0010 0100 .............. ..... ..... @fmt_rdrjsi14 ++stptr_w 0010 0101 .............. ..... ..... @fmt_rdrjsi14 ++ldptr_d 0010 0110 .............. ..... ..... @fmt_rdrjsi14 ++stptr_d 0010 0111 .............. ..... ..... @fmt_rdrjsi14 ++ld_b 0010 100000 ............ ..... ..... @fmt_rdrjsi12 ++ld_h 0010 100001 ............ ..... ..... @fmt_rdrjsi12 ++ld_w 0010 100010 ............ ..... ..... @fmt_rdrjsi12 ++ld_d 0010 100011 ............ ..... ..... @fmt_rdrjsi12 ++st_b 0010 100100 ............ ..... ..... @fmt_rdrjsi12 ++st_h 0010 100101 ............ ..... ..... @fmt_rdrjsi12 ++st_w 0010 100110 ............ ..... ..... @fmt_rdrjsi12 ++st_d 0010 100111 ............ ..... ..... @fmt_rdrjsi12 ++ld_bu 0010 101000 ............ ..... ..... @fmt_rdrjsi12 ++ld_hu 0010 101001 ............ ..... ..... @fmt_rdrjsi12 ++ld_wu 0010 101010 ............ ..... ..... @fmt_rdrjsi12 ++preld 0010 101011 ............ ..... ..... @fmt_hintrjsi12 ++fld_s 0010 101100 ............ ..... ..... @fmt_fdrjsi12 ++fst_s 0010 101101 ............ ..... ..... @fmt_fdrjsi12 ++fld_d 0010 101110 ............ ..... ..... @fmt_fdrjsi12 ++fst_d 0010 101111 ............ ..... ..... @fmt_fdrjsi12 ++ldx_b 0011 10000000 00000 ..... ..... ..... @fmt_rdrjrk ++ldx_h 0011 10000000 01000 ..... ..... ..... @fmt_rdrjrk ++ldx_w 0011 10000000 10000 ..... ..... ..... @fmt_rdrjrk ++ldx_d 0011 10000000 11000 ..... ..... ..... @fmt_rdrjrk ++stx_b 0011 10000001 00000 ..... ..... ..... @fmt_rdrjrk ++stx_h 0011 10000001 01000 ..... ..... ..... @fmt_rdrjrk ++stx_w 0011 10000001 10000 ..... ..... ..... @fmt_rdrjrk ++stx_d 0011 10000001 11000 ..... ..... ..... @fmt_rdrjrk ++ldx_bu 0011 10000010 00000 ..... ..... ..... @fmt_rdrjrk ++ldx_hu 0011 10000010 01000 ..... ..... ..... @fmt_rdrjrk ++ldx_wu 0011 10000010 10000 ..... ..... ..... @fmt_rdrjrk ++fldx_s 0011 10000011 00000 ..... ..... ..... @fmt_fdrjrk ++fldx_d 0011 10000011 01000 ..... ..... ..... @fmt_fdrjrk ++fstx_s 0011 10000011 10000 ..... ..... ..... @fmt_fdrjrk ++fstx_d 0011 10000011 11000 ..... ..... ..... @fmt_fdrjrk ++amswap_w 0011 10000110 00000 ..... ..... ..... @fmt_rdrjrk ++amswap_d 0011 10000110 00001 ..... ..... ..... @fmt_rdrjrk ++amadd_w 0011 10000110 00010 ..... ..... ..... @fmt_rdrjrk ++amadd_d 0011 10000110 00011 ..... ..... ..... @fmt_rdrjrk ++amand_w 0011 10000110 00100 ..... ..... ..... @fmt_rdrjrk ++amand_d 0011 10000110 00101 ..... ..... ..... @fmt_rdrjrk ++amor_w 0011 10000110 00110 ..... ..... ..... @fmt_rdrjrk ++amor_d 0011 10000110 00111 ..... ..... ..... @fmt_rdrjrk ++amxor_w 0011 10000110 01000 ..... ..... ..... @fmt_rdrjrk ++amxor_d 0011 10000110 01001 ..... ..... ..... @fmt_rdrjrk ++ammax_w 0011 10000110 01010 ..... ..... ..... @fmt_rdrjrk ++ammax_d 0011 10000110 01011 ..... ..... ..... @fmt_rdrjrk ++ammin_w 0011 10000110 01100 ..... ..... ..... @fmt_rdrjrk ++ammin_d 0011 10000110 01101 ..... ..... ..... @fmt_rdrjrk ++ammax_wu 0011 10000110 01110 ..... ..... ..... @fmt_rdrjrk ++ammax_du 0011 10000110 01111 ..... ..... ..... @fmt_rdrjrk ++ammin_wu 0011 10000110 10000 ..... ..... ..... @fmt_rdrjrk ++ammin_du 0011 10000110 10001 ..... ..... ..... @fmt_rdrjrk ++amswap_db_w 0011 10000110 10010 ..... ..... ..... @fmt_rdrjrk ++amswap_db_d 0011 10000110 10011 ..... ..... ..... @fmt_rdrjrk ++amadd_db_w 0011 10000110 10100 ..... ..... ..... @fmt_rdrjrk ++amadd_db_d 0011 10000110 10101 ..... ..... ..... @fmt_rdrjrk ++amand_db_w 0011 10000110 10110 ..... ..... ..... @fmt_rdrjrk ++amand_db_d 0011 10000110 10111 ..... ..... ..... @fmt_rdrjrk ++amor_db_w 0011 10000110 11000 ..... ..... ..... @fmt_rdrjrk ++amor_db_d 0011 10000110 11001 ..... ..... ..... @fmt_rdrjrk ++amxor_db_w 0011 10000110 11010 ..... ..... ..... @fmt_rdrjrk ++amxor_db_d 0011 10000110 11011 ..... ..... ..... @fmt_rdrjrk ++ammax_db_w 0011 10000110 11100 ..... ..... ..... @fmt_rdrjrk ++ammax_db_d 0011 10000110 11101 ..... ..... ..... @fmt_rdrjrk ++ammin_db_w 0011 10000110 11110 ..... ..... ..... @fmt_rdrjrk ++ammin_db_d 0011 10000110 11111 ..... ..... ..... @fmt_rdrjrk ++ammax_db_wu 0011 10000111 00000 ..... ..... ..... @fmt_rdrjrk ++ammax_db_du 0011 10000111 00001 ..... ..... ..... @fmt_rdrjrk ++ammin_db_wu 0011 10000111 00010 ..... ..... ..... @fmt_rdrjrk ++ammin_db_du 0011 10000111 00011 ..... ..... ..... @fmt_rdrjrk ++dbar 0011 10000111 00100 ............... @fmt_whint ++ibar 0011 10000111 00101 ............... @fmt_whint ++fldgt_s 0011 10000111 01000 ..... ..... ..... @fmt_fdrjrk ++fldgt_d 0011 10000111 01001 ..... ..... ..... @fmt_fdrjrk ++fldle_s 0011 10000111 01010 ..... ..... ..... @fmt_fdrjrk ++fldle_d 0011 10000111 01011 ..... ..... ..... @fmt_fdrjrk ++fstgt_s 0011 10000111 01100 ..... ..... ..... @fmt_fdrjrk ++fstgt_d 0011 10000111 01101 ..... ..... ..... @fmt_fdrjrk ++fstle_s 0011 10000111 01110 ..... ..... ..... @fmt_fdrjrk ++fstle_d 0011 10000111 01111 ..... ..... ..... @fmt_fdrjrk ++ldgt_b 0011 10000111 10000 ..... ..... ..... @fmt_rdrjrk ++ldgt_h 0011 10000111 10001 ..... ..... ..... @fmt_rdrjrk ++ldgt_w 0011 10000111 10010 ..... ..... ..... @fmt_rdrjrk ++ldgt_d 0011 10000111 10011 ..... ..... ..... @fmt_rdrjrk ++ldle_b 0011 10000111 10100 ..... ..... ..... @fmt_rdrjrk ++ldle_h 0011 10000111 10101 ..... ..... ..... @fmt_rdrjrk ++ldle_w 0011 10000111 10110 ..... ..... ..... @fmt_rdrjrk ++ldle_d 0011 10000111 10111 ..... ..... ..... @fmt_rdrjrk ++stgt_b 0011 10000111 11000 ..... ..... ..... @fmt_rdrjrk ++stgt_h 0011 10000111 11001 ..... ..... ..... @fmt_rdrjrk ++stgt_w 0011 10000111 11010 ..... ..... ..... @fmt_rdrjrk ++stgt_d 0011 10000111 11011 ..... ..... ..... @fmt_rdrjrk ++stle_b 0011 10000111 11100 ..... ..... ..... @fmt_rdrjrk ++stle_h 0011 10000111 11101 ..... ..... ..... @fmt_rdrjrk ++stle_w 0011 10000111 11110 ..... ..... ..... @fmt_rdrjrk ++stle_d 0011 10000111 11111 ..... ..... ..... @fmt_rdrjrk ++ ++# jump Instructions ++beqz 0100 00 ................ ..... ..... @fmt_rjoffs21 ++bnez 0100 01 ................ ..... ..... @fmt_rjoffs21 ++bceqz 0100 10 ................ 00 ... ..... @fmt_cjoffs21 ++bcnez 0100 10 ................ 01 ... ..... @fmt_cjoffs21 ++jirl 0100 11 ................ ..... ..... @fmt_rdrjoffs16 ++b 0101 00 .......................... @fmt_offs ++bl 0101 01 .......................... @fmt_offs ++beq 0101 10 ................ ..... ..... @fmt_rjrdoffs16 ++bne 0101 11 ................ ..... ..... @fmt_rjrdoffs16 ++blt 0110 00 ................ ..... ..... @fmt_rjrdoffs16 ++bge 0110 01 ................ ..... ..... @fmt_rjrdoffs16 ++bltu 0110 10 ................ ..... ..... @fmt_rjrdoffs16 ++bgeu 0110 11 ................ ..... ..... @fmt_rjrdoffs16 +diff --git a/target/loongarch64/instmap.h b/target/loongarch64/instmap.h +new file mode 100644 +index 000000000..6e85847f8 +--- /dev/null ++++ b/target/loongarch64/instmap.h +@@ -0,0 +1,216 @@ ++/* ++ * Loongarch emulation for qemu: instruction opcode ++ * ++ * Copyright (c) 2020-2021 ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2 or later, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program. If not, see . ++ */ ++ ++#ifndef TARGET_LARCH_INSTMAP_H ++#define TARGET_LARCH_INSTMAP_H ++ ++enum { ++ /* fix opcodes */ ++ OPC_LARCH_CLO_W = (0x000004 << 10), ++ OPC_LARCH_CLZ_W = (0x000005 << 10), ++ OPC_LARCH_CLO_D = (0x000008 << 10), ++ OPC_LARCH_CLZ_D = (0x000009 << 10), ++ OPC_LARCH_REVB_2H = (0x00000C << 10), ++ OPC_LARCH_REVB_4H = (0x00000D << 10), ++ OPC_LARCH_REVH_D = (0x000011 << 10), ++ OPC_LARCH_BREV_4B = (0x000012 << 10), ++ OPC_LARCH_BREV_8B = (0x000013 << 10), ++ OPC_LARCH_EXT_WH = (0x000016 << 10), ++ OPC_LARCH_EXT_WB = (0x000017 << 10), ++ ++ OPC_LARCH_ADD_W = (0x00020 << 15), ++ OPC_LARCH_ADD_D = (0x00021 << 15), ++ OPC_LARCH_SUB_W = (0x00022 << 15), ++ OPC_LARCH_SUB_D = (0x00023 << 15), ++ OPC_LARCH_SLT = (0x00024 << 15), ++ OPC_LARCH_SLTU = (0x00025 << 15), ++ OPC_LARCH_MASKEQZ = (0x00026 << 15), ++ OPC_LARCH_MASKNEZ = (0x00027 << 15), ++ OPC_LARCH_NOR = (0x00028 << 15), ++ OPC_LARCH_AND = (0x00029 << 15), ++ OPC_LARCH_OR = (0x0002A << 15), ++ OPC_LARCH_XOR = (0x0002B << 15), ++ OPC_LARCH_SLL_W = (0x0002E << 15), ++ OPC_LARCH_SRL_W = (0x0002F << 15), ++ OPC_LARCH_SRA_W = (0x00030 << 15), ++ OPC_LARCH_SLL_D = (0x00031 << 15), ++ OPC_LARCH_SRL_D = (0x00032 << 15), ++ OPC_LARCH_SRA_D = (0x00033 << 15), ++ OPC_LARCH_ROTR_W = (0x00036 << 15), ++ OPC_LARCH_ROTR_D = (0x00037 << 15), ++ OPC_LARCH_MUL_W = (0x00038 << 15), ++ OPC_LARCH_MULH_W = (0x00039 << 15), ++ OPC_LARCH_MULH_WU = (0x0003A << 15), ++ OPC_LARCH_MUL_D = (0x0003B << 15), ++ OPC_LARCH_MULH_D = (0x0003C << 15), ++ OPC_LARCH_MULH_DU = (0x0003D << 15), ++ OPC_LARCH_DIV_W = (0x00040 << 15), ++ OPC_LARCH_MOD_W = (0x00041 << 15), ++ OPC_LARCH_DIV_WU = (0x00042 << 15), ++ OPC_LARCH_MOD_WU = (0x00043 << 15), ++ OPC_LARCH_DIV_D = (0x00044 << 15), ++ OPC_LARCH_MOD_D = (0x00045 << 15), ++ OPC_LARCH_DIV_DU = (0x00046 << 15), ++ OPC_LARCH_MOD_DU = (0x00047 << 15), ++ OPC_LARCH_SRLI_W = (0x00089 << 15), ++ OPC_LARCH_SRAI_W = (0x00091 << 15), ++ OPC_LARCH_ROTRI_W = (0x00099 << 15), ++ ++ OPC_LARCH_ALSL_W = (0x0002 << 17), ++ OPC_LARCH_ALSL_D = (0x0016 << 17), ++ ++ OPC_LARCH_TRINS_W = (0x003 << 21) | (0x0 << 15), ++ OPC_LARCH_TRPICK_W = (0x003 << 21) | (0x1 << 15), ++}; ++ ++enum { ++ /* float opcodes */ ++ OPC_LARCH_FABS_S = (0x004501 << 10), ++ OPC_LARCH_FABS_D = (0x004502 << 10), ++ OPC_LARCH_FNEG_S = (0x004505 << 10), ++ OPC_LARCH_FNEG_D = (0x004506 << 10), ++ OPC_LARCH_FCLASS_S = (0x00450D << 10), ++ OPC_LARCH_FCLASS_D = (0x00450E << 10), ++ OPC_LARCH_FSQRT_S = (0x004511 << 10), ++ OPC_LARCH_FSQRT_D = (0x004512 << 10), ++ OPC_LARCH_FRECIP_S = (0x004515 << 10), ++ OPC_LARCH_FRECIP_D = (0x004516 << 10), ++ OPC_LARCH_FRSQRT_S = (0x004519 << 10), ++ OPC_LARCH_FRSQRT_D = (0x00451A << 10), ++ OPC_LARCH_FMOV_S = (0x004525 << 10), ++ OPC_LARCH_FMOV_D = (0x004526 << 10), ++ OPC_LARCH_GR2FR_W = (0x004529 << 10), ++ OPC_LARCH_GR2FR_D = (0x00452A << 10), ++ OPC_LARCH_GR2FRH_W = (0x00452B << 10), ++ OPC_LARCH_FR2GR_S = (0x00452D << 10), ++ OPC_LARCH_FR2GR_D = (0x00452E << 10), ++ OPC_LARCH_FRH2GR_S = (0x00452F << 10), ++ ++ OPC_LARCH_FCVT_S_D = (0x004646 << 10), ++ OPC_LARCH_FCVT_D_S = (0x004649 << 10), ++ OPC_LARCH_FTINTRM_W_S = (0x004681 << 10), ++ OPC_LARCH_FTINTRM_W_D = (0x004682 << 10), ++ OPC_LARCH_FTINTRM_L_S = (0x004689 << 10), ++ OPC_LARCH_FTINTRM_L_D = (0x00468A << 10), ++ OPC_LARCH_FTINTRP_W_S = (0x004691 << 10), ++ OPC_LARCH_FTINTRP_W_D = (0x004692 << 10), ++ OPC_LARCH_FTINTRP_L_S = (0x004699 << 10), ++ OPC_LARCH_FTINTRP_L_D = (0x00469A << 10), ++ OPC_LARCH_FTINTRZ_W_S = (0x0046A1 << 10), ++ OPC_LARCH_FTINTRZ_W_D = (0x0046A2 << 10), ++ OPC_LARCH_FTINTRZ_L_S = (0x0046A9 << 10), ++ OPC_LARCH_FTINTRZ_L_D = (0x0046AA << 10), ++ OPC_LARCH_FTINTRNE_W_S = (0x0046B1 << 10), ++ OPC_LARCH_FTINTRNE_W_D = (0x0046B2 << 10), ++ OPC_LARCH_FTINTRNE_L_S = (0x0046B9 << 10), ++ OPC_LARCH_FTINTRNE_L_D = (0x0046BA << 10), ++ OPC_LARCH_FTINT_W_S = (0x0046C1 << 10), ++ OPC_LARCH_FTINT_W_D = (0x0046C2 << 10), ++ OPC_LARCH_FTINT_L_S = (0x0046C9 << 10), ++ OPC_LARCH_FTINT_L_D = (0x0046CA << 10), ++ OPC_LARCH_FFINT_S_W = (0x004744 << 10), ++ OPC_LARCH_FFINT_S_L = (0x004746 << 10), ++ OPC_LARCH_FFINT_D_W = (0x004748 << 10), ++ OPC_LARCH_FFINT_D_L = (0x00474A << 10), ++ OPC_LARCH_FRINT_S = (0x004791 << 10), ++ OPC_LARCH_FRINT_D = (0x004792 << 10), ++ ++ OPC_LARCH_FADD_S = (0x00201 << 15), ++ OPC_LARCH_FADD_D = (0x00202 << 15), ++ OPC_LARCH_FSUB_S = (0x00205 << 15), ++ OPC_LARCH_FSUB_D = (0x00206 << 15), ++ OPC_LARCH_FMUL_S = (0x00209 << 15), ++ OPC_LARCH_FMUL_D = (0x0020A << 15), ++ OPC_LARCH_FDIV_S = (0x0020D << 15), ++ OPC_LARCH_FDIV_D = (0x0020E << 15), ++ OPC_LARCH_FMAX_S = (0x00211 << 15), ++ OPC_LARCH_FMAX_D = (0x00212 << 15), ++ OPC_LARCH_FMIN_S = (0x00215 << 15), ++ OPC_LARCH_FMIN_D = (0x00216 << 15), ++ OPC_LARCH_FMAXA_S = (0x00219 << 15), ++ OPC_LARCH_FMAXA_D = (0x0021A << 15), ++ OPC_LARCH_FMINA_S = (0x0021D << 15), ++ OPC_LARCH_FMINA_D = (0x0021E << 15), ++}; ++ ++enum { ++ /* 12 bit immediate opcodes */ ++ OPC_LARCH_SLTI = (0x008 << 22), ++ OPC_LARCH_SLTIU = (0x009 << 22), ++ OPC_LARCH_ADDI_W = (0x00A << 22), ++ OPC_LARCH_ADDI_D = (0x00B << 22), ++ OPC_LARCH_ANDI = (0x00D << 22), ++ OPC_LARCH_ORI = (0x00E << 22), ++ OPC_LARCH_XORI = (0x00F << 22), ++}; ++ ++enum { ++ /* load/store opcodes */ ++ OPC_LARCH_FLDX_S = (0x07060 << 15), ++ OPC_LARCH_FLDX_D = (0x07068 << 15), ++ OPC_LARCH_FSTX_S = (0x07070 << 15), ++ OPC_LARCH_FSTX_D = (0x07078 << 15), ++ OPC_LARCH_FLDGT_S = (0x070E8 << 15), ++ OPC_LARCH_FLDGT_D = (0x070E9 << 15), ++ OPC_LARCH_FLDLE_S = (0x070EA << 15), ++ OPC_LARCH_FLDLE_D = (0x070EB << 15), ++ OPC_LARCH_FSTGT_S = (0x070EC << 15), ++ OPC_LARCH_FSTGT_D = (0x070ED << 15), ++ OPC_LARCH_FSTLE_S = (0x070EE << 15), ++ OPC_LARCH_FSTLE_D = (0x070EF << 15), ++ ++ OPC_LARCH_LD_B = (0x0A0 << 22), ++ OPC_LARCH_LD_H = (0x0A1 << 22), ++ OPC_LARCH_LD_W = (0x0A2 << 22), ++ OPC_LARCH_LD_D = (0x0A3 << 22), ++ OPC_LARCH_ST_B = (0x0A4 << 22), ++ OPC_LARCH_ST_H = (0x0A5 << 22), ++ OPC_LARCH_ST_W = (0x0A6 << 22), ++ OPC_LARCH_ST_D = (0x0A7 << 22), ++ OPC_LARCH_LD_BU = (0x0A8 << 22), ++ OPC_LARCH_LD_HU = (0x0A9 << 22), ++ OPC_LARCH_LD_WU = (0x0AA << 22), ++ OPC_LARCH_FLD_S = (0x0AC << 22), ++ OPC_LARCH_FST_S = (0x0AD << 22), ++ OPC_LARCH_FLD_D = (0x0AE << 22), ++ OPC_LARCH_FST_D = (0x0AF << 22), ++ ++ OPC_LARCH_LL_W = (0x20 << 24), ++ OPC_LARCH_SC_W = (0x21 << 24), ++ OPC_LARCH_LL_D = (0x22 << 24), ++ OPC_LARCH_SC_D = (0x23 << 24), ++ OPC_LARCH_LDPTR_W = (0x24 << 24), ++ OPC_LARCH_STPTR_W = (0x25 << 24), ++ OPC_LARCH_LDPTR_D = (0x26 << 24), ++ OPC_LARCH_STPTR_D = (0x27 << 24), ++}; ++ ++enum { ++ /* jump opcodes */ ++ OPC_LARCH_BEQZ = (0x10 << 26), ++ OPC_LARCH_BNEZ = (0x11 << 26), ++ OPC_LARCH_B = (0x14 << 26), ++ OPC_LARCH_BEQ = (0x16 << 26), ++ OPC_LARCH_BNE = (0x17 << 26), ++ OPC_LARCH_BLT = (0x18 << 26), ++ OPC_LARCH_BGE = (0x19 << 26), ++ OPC_LARCH_BLTU = (0x1A << 26), ++ OPC_LARCH_BGEU = (0x1B << 26), ++}; ++ ++#endif +diff --git a/target/loongarch64/internal.h b/target/loongarch64/internal.h +new file mode 100644 +index 000000000..79a70e9d2 +--- /dev/null ++++ b/target/loongarch64/internal.h +@@ -0,0 +1,184 @@ ++#ifndef LOONGARCH_INTERNAL_H ++#define LOONGARCH_INTERNAL_H ++ ++#include "cpu-csr.h" ++ ++/* MMU types, the first four entries have the same layout as the ++ CP0C0_MT field. */ ++enum loongarch_mmu_types { ++ MMU_TYPE_NONE, ++ MMU_TYPE_LS3A5K, /* LISA CSR */ ++}; ++ ++ ++ ++struct loongarch_def_t { ++ const char *name; ++ int32_t CSR_PRid; ++ int32_t FCSR0; ++ int32_t FCSR0_rw_bitmask; ++ int32_t PABITS; ++ CPU_LOONGARCH_CSR ++ uint64_t insn_flags; ++ enum loongarch_mmu_types mmu_type; ++ int cpu_cfg[64]; ++}; ++ ++/* loongarch 3a5000 TLB entry */ ++struct ls3a5k_tlb_t { ++ target_ulong VPN; ++ uint64_t PageMask; /* CSR_TLBIDX[29:24] */ ++ uint32_t PageSize; ++ uint16_t ASID; ++ unsigned int G:1; /* CSR_TLBLO[6] */ ++ ++ unsigned int C0:3; /* CSR_TLBLO[5:4] */ ++ unsigned int C1:3; ++ ++ unsigned int V0:1; /* CSR_TLBLO[0] */ ++ unsigned int V1:1; ++ ++ unsigned int WE0:1; /* CSR_TLBLO[1] */ ++ unsigned int WE1:1; ++ ++ unsigned int XI0:1; /* CSR_TLBLO[62] */ ++ unsigned int XI1:1; ++ ++ unsigned int RI0:1; /* CSR_TLBLO[61] */ ++ unsigned int RI1:1; ++ ++ unsigned int EHINV:1;/* CSR_TLBIDX[31] */ ++ ++ unsigned int PLV0:2; /* CSR_TLBLO[3:2] */ ++ unsigned int PLV1:2; ++ ++ unsigned int RPLV0:1; ++ unsigned int RPLV1:1; /* CSR_TLBLO[63] */ ++ ++ uint64_t PPN0; /* CSR_TLBLO[47:12] */ ++ uint64_t PPN1; /* CSR_TLBLO[47:12] */ ++}; ++typedef struct ls3a5k_tlb_t ls3a5k_tlb_t; ++ ++ ++struct CPULOONGARCHTLBContext { ++ uint32_t nb_tlb; ++ uint32_t tlb_in_use; ++ int (*map_address)(struct CPULOONGARCHState *env, hwaddr *physical, int *prot, ++ target_ulong address, int rw, int access_type); ++ void (*helper_tlbwr)(struct CPULOONGARCHState *env); ++ void (*helper_tlbfill)(struct CPULOONGARCHState *env); ++ void (*helper_tlbsrch)(struct CPULOONGARCHState *env); ++ void (*helper_tlbrd)(struct CPULOONGARCHState *env); ++ void (*helper_tlbclr)(struct CPULOONGARCHState *env); ++ void (*helper_tlbflush)(struct CPULOONGARCHState *env); ++ void (*helper_invtlb)(struct CPULOONGARCHState *env, target_ulong addr, ++ target_ulong info, int op); ++ union { ++ struct { ++ uint64_t ftlb_mask; ++ uint32_t ftlb_size; /* at most : 8 * 256 = 2048 */ ++ uint32_t vtlb_size; /* at most : 64 */ ++ ls3a5k_tlb_t tlb[2048 + 64]; /* at most : 2048 FTLB + 64 VTLB */ ++ } ls3a5k; ++ } mmu; ++}; ++ ++enum { ++ TLBRET_PE = -7, ++ TLBRET_XI = -6, ++ TLBRET_RI = -5, ++ TLBRET_DIRTY = -4, ++ TLBRET_INVALID = -3, ++ TLBRET_NOMATCH = -2, ++ TLBRET_BADADDR = -1, ++ TLBRET_MATCH = 0 ++}; ++ ++ ++extern unsigned int ieee_rm[]; ++ ++static inline void restore_rounding_mode(CPULOONGARCHState *env) ++{ ++ set_float_rounding_mode(ieee_rm[(env->active_fpu.fcsr0 >> FCSR0_RM) & 0x3], ++ &env->active_fpu.fp_status); ++} ++ ++static inline void restore_flush_mode(CPULOONGARCHState *env) ++{ ++ set_flush_to_zero(0, &env->active_fpu.fp_status); ++} ++ ++static inline void restore_fp_status(CPULOONGARCHState *env) ++{ ++ restore_rounding_mode(env); ++ restore_flush_mode(env); ++} ++static inline void compute_hflags(CPULOONGARCHState *env) ++{ ++ env->hflags &= ~(LARCH_HFLAG_64 | LARCH_HFLAG_FPU | LARCH_HFLAG_KSU | ++ LARCH_HFLAG_AWRAP | LARCH_HFLAG_LSX | LARCH_HFLAG_LASX); ++ ++ env->hflags |= (env->CSR_CRMD & CSR_CRMD_PLV); ++ env->hflags |= LARCH_HFLAG_64; ++ ++ if (env->CSR_EUEN & CSR_EUEN_FPEN) { ++ env->hflags |= LARCH_HFLAG_FPU; ++ } ++ if (env->CSR_EUEN & CSR_EUEN_LSXEN) { ++ env->hflags |= LARCH_HFLAG_LSX; ++ } ++ if (env->CSR_EUEN & CSR_EUEN_LASXEN) { ++ env->hflags |= LARCH_HFLAG_LASX; ++ } ++ if (env->CSR_EUEN & CSR_EUEN_LBTEN) { ++ env->hflags |= LARCH_HFLAG_LBT; ++ } ++} ++ ++/* Check if there is pending and not masked out interrupt */ ++static inline bool cpu_loongarch_hw_interrupts_pending(CPULOONGARCHState *env) ++{ ++ int32_t pending; ++ int32_t status; ++ bool r; ++ ++ pending = env->CSR_ESTAT & CSR_ESTAT_IPMASK; ++ status = env->CSR_ECFG & CSR_ECFG_IPMASK; ++ ++ /* Configured with compatibility or VInt (Vectored Interrupts) ++ treats the pending lines as individual interrupt lines, the status ++ lines are individual masks. */ ++ r = (pending & status) != 0; ++ ++ return r; ++} ++ ++ ++/* stabletimer.c */ ++uint32_t cpu_loongarch_get_random_ls3a5k_tlb(uint32_t low, uint32_t high); ++uint64_t cpu_loongarch_get_stable_counter(CPULOONGARCHState *env); ++uint64_t cpu_loongarch_get_stable_timer_ticks(CPULOONGARCHState *env); ++void cpu_loongarch_store_stable_timer_config(CPULOONGARCHState *env, uint64_t value); ++int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, ++ int cpuid, void *opaque); ++ ++void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags); ++ ++/* TODO QOM'ify CPU reset and remove */ ++void cpu_state_reset(CPULOONGARCHState *s); ++void cpu_loongarch_realize_env(CPULOONGARCHState *env); ++ ++int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n); ++int loongarch_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); ++ ++#ifdef CONFIG_TCG ++#include "fpu_helper.h" ++#endif ++ ++#ifndef CONFIG_USER_ONLY ++extern const struct VMStateDescription vmstate_loongarch_cpu; ++hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); ++#endif ++ ++#endif +diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c +new file mode 100644 +index 000000000..b6711da91 +--- /dev/null ++++ b/target/loongarch64/kvm.c +@@ -0,0 +1,1384 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * KVM/LOONGARCH: LOONGARCH specific KVM APIs ++ * ++ * Copyright (C) 2012-2014 Imagination Technologies Ltd. ++ * Authors: Sanjay Lal ++*/ ++ ++#include "qemu/osdep.h" ++#include ++ ++#include ++ ++#include "qemu-common.h" ++#include "cpu.h" ++#include "internal.h" ++#include "qemu/error-report.h" ++#include "qemu/timer.h" ++#include "qemu/main-loop.h" ++#include "sysemu/sysemu.h" ++#include "sysemu/kvm.h" ++#include "sysemu/runstate.h" ++#include "sysemu/cpus.h" ++#include "kvm_larch.h" ++#include "exec/memattrs.h" ++#include "exec/gdbstub.h" ++ ++#define DEBUG_KVM 0 ++/* A 16384-byte buffer can hold the 8-byte kvm_msrs header, plus ++ * 2047 kvm_msr_entry structs */ ++#define 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; ++} ++/* ++#if 0 ++int kvmloongarch_load_kernel(CPUState *env, void *ram_base) ++{ ++ int ret; ++ ++ ret = kvm_vcpu_ioctl(env, KVM_LOAD_KERNEL, ram_base); ++ ++ return ret; ++} ++#endif ++*/ ++void kvm_arch_init_irq_routing(KVMState *s) ++{ ++} ++ ++int kvm_loongarch_set_interrupt(LOONGARCHCPU *cpu, int irq, int level) ++{ ++ CPUState *cs = CPU(cpu); ++ struct kvm_loongarch_interrupt intr; ++ ++ if (!kvm_enabled()) { ++ return 0; ++ } ++ ++ intr.cpu = -1; ++ ++ if (level) { ++ intr.irq = irq; ++ } else { ++ intr.irq = -irq; ++ } ++ ++ kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); ++ ++ return 0; ++} ++ ++int kvm_loongarch_set_ipi_interrupt(LOONGARCHCPU *cpu, int irq, int level) ++{ ++ CPUState *cs = current_cpu; ++ CPUState *dest_cs = CPU(cpu); ++ struct kvm_loongarch_interrupt intr; ++ ++ if (!kvm_enabled()) { ++ return 0; ++ } ++ ++ intr.cpu = dest_cs->cpu_index; ++ ++ if (level) { ++ intr.irq = irq; ++ } else { ++ intr.irq = -irq; ++ } ++ ++ DPRINTF("%s: IRQ: %d\n", __func__, intr.irq); ++ if (!current_cpu) { ++ cs = dest_cs; ++ } ++ kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); ++ ++ return 0; ++} ++ ++static inline int kvm_loongarch_put_one_reg(CPUState *cs, uint64_t reg_id, ++ int32_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_put_one_ureg(CPUState *cs, uint64_t reg_id, ++ uint32_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_put_one_ulreg(CPUState *cs, uint64_t reg_id, ++ target_ulong *addr) ++{ ++ uint64_t val64 = *addr; ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)&val64 ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_put_one_reg64(CPUState *cs, int64_t reg_id, ++ int64_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_larch_putq(CPUState *cs, uint64_t reg_id, ++ uint64_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_get_one_reg(CPUState *cs, uint64_t reg_id, ++ int32_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_get_one_ureg(CPUState *cs, uint64_t reg_id, ++ uint32_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_get_one_ulreg(CPUState *cs, uint64_t reg_id, ++ target_ulong *addr) ++{ ++ int ret; ++ uint64_t val64 = 0; ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)&val64 ++ }; ++ ++ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); ++ if (ret >= 0) { ++ *addr = val64; ++ } ++ return ret; ++} ++ ++static inline int kvm_loongarch_get_one_reg64(CPUState *cs, int64_t reg_id, ++ int64_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_larch_getq(CPUState *cs, uint64_t reg_id, ++ uint64_t *addr) ++{ ++ struct kvm_one_reg csrreg = { ++ .id = reg_id, ++ .addr = (uintptr_t)addr ++ }; ++ ++ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); ++} ++ ++static inline int kvm_loongarch_change_one_reg(CPUState *cs, uint64_t reg_id, ++ int32_t *addr, int32_t mask) ++{ ++ int err; ++ int32_t tmp, change; ++ ++ err = kvm_loongarch_get_one_reg(cs, reg_id, &tmp); ++ if (err < 0) { ++ return err; ++ } ++ ++ /* only change bits in mask */ ++ change = (*addr ^ tmp) & mask; ++ if (!change) { ++ return 0; ++ } ++ ++ tmp = tmp ^ change; ++ return kvm_loongarch_put_one_reg(cs, reg_id, &tmp); ++} ++ ++static inline int kvm_loongarch_change_one_reg64(CPUState *cs, uint64_t reg_id, ++ int64_t *addr, int64_t mask) ++{ ++ int err; ++ int64_t tmp, change; ++ ++ err = kvm_loongarch_get_one_reg64(cs, reg_id, &tmp); ++ if (err < 0) { ++ DPRINTF("%s: Failed to get CSR_CONFIG7 (%d)\n", __func__, err); ++ return err; ++ } ++ ++ /* only change bits in mask */ ++ change = (*addr ^ tmp) & mask; ++ if (!change) { ++ return 0; ++ } ++ ++ tmp = tmp ^ change; ++ return kvm_loongarch_put_one_reg64(cs, reg_id, &tmp); ++} ++/* ++ * Handle the VM clock being started or stopped ++ */ ++static void kvm_loongarch_update_state(void *opaque, bool running, RunState state) ++{ ++ CPUState *cs = opaque; ++ int ret; ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ ++ /* ++ * If state is already dirty (synced to QEMU) then the KVM timer state is ++ * already saved and can be restored when it is synced back to KVM. ++ */ ++ if (!running) { ++ ret = kvm_larch_getq(cs, ++ KVM_REG_LOONGARCH_COUNTER, &cpu->counter_value); ++ if (ret < 0) { ++ printf("%s: Failed to get counter_value (%d)\n", __func__, ret); ++ } ++ ++ } else { ++ ret = kvm_larch_putq(cs, KVM_REG_LOONGARCH_COUNTER, ++ &(LOONGARCH_CPU(cs))->counter_value); ++ if (ret < 0) { ++ printf("%s: Failed to put counter_value (%d)\n", __func__, ret); ++ } ++ } ++} ++ ++static int kvm_loongarch_put_fpu_registers(CPUState *cs, int level) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ int err, ret = 0; ++ unsigned int i; ++ struct kvm_fpu fpu; ++ ++ fpu.fcsr = env->active_fpu.fcsr0; ++ for (i = 0; i < 32; i++) { ++ memcpy(&fpu.fpr[i], &env->active_fpu.fpr[i], sizeof(struct kvm_fpureg)); ++ } ++ for (i = 0; i < 8; i++) { ++ ((char *)&fpu.fcc)[i] = env->active_fpu.cf[i]; ++ } ++ fpu.vcsr = env->active_fpu.vcsr16; ++ ++ err = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu); ++ if (err < 0) { ++ DPRINTF("%s: Failed to get FPU (%d)\n", __func__, err); ++ ret = err; ++ } ++ ++ return ret; ++} ++ ++static int kvm_loongarch_get_fpu_registers(CPUState *cs) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ int err, ret = 0; ++ unsigned int i; ++ struct kvm_fpu fpu; ++ ++ err = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu); ++ if (err < 0) { ++ DPRINTF("%s: Failed to get FPU (%d)\n", __func__, err); ++ ret = err; ++ } else { ++ env->active_fpu.fcsr0 = fpu.fcsr; ++ for (i = 0; i < 32; i++) { ++ memcpy(&env->active_fpu.fpr[i], &fpu.fpr[i], sizeof(struct kvm_fpureg)); ++ } ++ for (i = 0; i < 8; i++) { ++ env->active_fpu.cf[i] = ((char *)&fpu.fcc)[i]; ++ } ++ env->active_fpu.vcsr16 = fpu.vcsr; ++ } ++ ++ return ret; ++} ++ ++#define KVM_PUT_ONE_UREG64(cs, regidx, addr) \ ++ ({ \ ++ int err; \ ++ uint64_t csrid = 0; \ ++ csrid = (KVM_IOC_CSRID(regidx)); \ ++ err = kvm_larch_putq(cs, csrid, addr); \ ++ if (err < 0) { \ ++ DPRINTF("%s: Failed to put regidx 0x%x err:%d\n", __func__, regidx, err); \ ++ } \ ++ err; \ ++ }) ++ ++ ++static int kvm_loongarch_put_csr_registers(CPUState *cs, int level) ++{ ++ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); ++ CPULOONGARCHState *env = &cpu->env; ++ int ret = 0; ++ ++ (void)level; ++ ++ kvm_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 000000000..a56026d10 +--- /dev/null ++++ b/target/loongarch64/kvm_larch.h +@@ -0,0 +1,41 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * KVM/LOONGARCH: LOONGARCH specific KVM APIs ++ * ++ * Copyright (C) 2012-2014 Imagination Technologies Ltd. ++ * Authors: Sanjay Lal ++*/ ++ ++#ifndef KVM_LOONGARCH_H ++#define KVM_LOONGARCH_H ++ ++/** ++ * kvm_loongarch_reset_vcpu: ++ * @cpu: LOONGARCHCPU ++ * ++ * Called at reset time to set kernel registers to their initial values. ++ */ ++void kvm_loongarch_reset_vcpu(LOONGARCHCPU *cpu); ++ ++int kvm_loongarch_set_interrupt(LOONGARCHCPU *cpu, int irq, int level); ++int kvm_loongarch_set_ipi_interrupt(LOONGARCHCPU *cpu, int irq, int level); ++ ++int kvm_loongarch_put_pvtime(LOONGARCHCPU *cpu); ++int kvm_loongarch_get_pvtime(LOONGARCHCPU *cpu); ++ ++#ifndef KVM_INTERRUPT_SET ++#define KVM_INTERRUPT_SET -1 ++#endif ++ ++#ifndef KVM_INTERRUPT_UNSET ++#define KVM_INTERRUPT_UNSET -2 ++#endif ++ ++#ifndef KVM_INTERRUPT_SET_LEVEL ++#define KVM_INTERRUPT_SET_LEVEL -3 ++#endif ++ ++#endif /* KVM_LOONGARCH_H */ +diff --git a/target/loongarch64/larch-defs.h b/target/loongarch64/larch-defs.h +new file mode 100644 +index 000000000..d3a61cf25 +--- /dev/null ++++ b/target/loongarch64/larch-defs.h +@@ -0,0 +1,27 @@ ++#ifndef QEMU_LOONGARCH_DEFS_H ++#define QEMU_LOONGARCH_DEFS_H ++ ++/* If we want to use host float regs... */ ++/* #define USE_HOST_FLOAT_REGS */ ++ ++/* Real pages are variable size... */ ++#define TARGET_PAGE_BITS 14 ++ ++#define LOONGARCH_TLB_MAX 2112 ++ ++#define TARGET_LONG_BITS 64 ++#define TARGET_PHYS_ADDR_SPACE_BITS 48 ++#define TARGET_VIRT_ADDR_SPACE_BITS 48 ++ ++/* ++ * bit definitions for insn_flags (ISAs/ASEs flags) ++ * ------------------------------------------------ ++ */ ++#define ISA_LARCH32 0x00000001ULL ++#define ISA_LARCH64 0x00000002ULL ++#define INSN_LOONGARCH 0x00010000ULL ++ ++#define CPU_LARCH32 (ISA_LARCH32) ++#define CPU_LARCH64 (ISA_LARCH32 | ISA_LARCH64) ++ ++#endif /* QEMU_LOONGARCH_DEFS_H */ +diff --git a/target/loongarch64/machine.c b/target/loongarch64/machine.c +new file mode 100644 +index 000000000..dea6a7034 +--- /dev/null ++++ b/target/loongarch64/machine.c +@@ -0,0 +1,423 @@ ++#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 000000000..6badf4484 +--- /dev/null ++++ b/target/loongarch64/meson.build +@@ -0,0 +1,35 @@ ++loongarch_user_ss = ss.source_set() ++loongarch_softmmu_ss = ss.source_set() ++loongarch_ss = ss.source_set() ++loongarch_ss.add(files( ++ 'cpu.c', ++ 'fpu.c', ++ 'gdbstub.c', ++)) ++ ++gen = [ ++ decodetree.process('insn.decode', extra_args: [ '--decode', 'decode_insn', ++ '--insnwidth', '32' ]) ++] ++ ++loongarch_ss.add(gen) ++loongarch_ss.add(when: 'CONFIG_TCG', if_true: files( ++ 'helper.c', ++ 'translate.c', ++ 'op_helper.c', ++ 'fpu_helper.c', ++ 'tlb_helper.c', ++ 'csr_helper.c', ++)) ++ ++loongarch_softmmu_ss.add(when: 'CONFIG_SOFTMMU', if_true: files( ++ 'machine.c', ++ 'stabletimer.c', ++ 'arch_dump.c', ++)) ++ ++loongarch_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) ++ ++target_arch += {'loongarch64': loongarch_ss} ++target_softmmu_arch += {'loongarch64': loongarch_softmmu_ss} ++target_user_arch += {'loongarch64': loongarch_user_ss} +diff --git a/target/loongarch64/op_helper.c b/target/loongarch64/op_helper.c +new file mode 100644 +index 000000000..9a34c0d25 +--- /dev/null ++++ b/target/loongarch64/op_helper.c +@@ -0,0 +1,533 @@ ++/* ++ * LOONGARCH emulation helpers for qemu. ++ * ++ * Copyright (c) 2004-2005 Jocelyn Mayer ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#include "qemu/osdep.h" ++#include "qemu/main-loop.h" ++#include "cpu.h" ++#include "internal.h" ++#include "qemu/host-utils.h" ++#include "exec/helper-proto.h" ++#include "exec/exec-all.h" ++#include "exec/cpu_ldst.h" ++#include "sysemu/kvm.h" ++#include "qemu/crc32c.h" ++#include ++#include "hw/irq.h" ++#include "hw/core/cpu.h" ++#include "instmap.h" ++ ++/*****************************************************************************/ ++/* Exceptions processing helpers */ ++ ++void helper_raise_exception_err(CPULOONGARCHState *env, uint32_t exception, ++ int error_code) ++{ ++ do_raise_exception_err(env, exception, error_code, 0); ++} ++ ++void helper_raise_exception(CPULOONGARCHState *env, uint32_t exception) ++{ ++ do_raise_exception(env, exception, GETPC()); ++} ++ ++void helper_raise_exception_debug(CPULOONGARCHState *env) ++{ ++ do_raise_exception(env, EXCP_DEBUG, 0); ++} ++ ++static void raise_exception(CPULOONGARCHState *env, uint32_t exception) ++{ ++ do_raise_exception(env, exception, 0); ++} ++ ++#if defined(CONFIG_USER_ONLY) ++#define HELPER_LD(name, insn, type) \ ++static inline type do_##name(CPULOONGARCHState *env, target_ulong addr, \ ++ int mem_idx, uintptr_t retaddr) \ ++{ \ ++ return (type) cpu_##insn##_data_ra(env, addr, retaddr); \ ++} ++#else ++ ++#define HF_SMAP_SHIFT 23 /* CR4.SMAP */ ++#define HF_SMAP_MASK (1 << HF_SMAP_SHIFT) ++#define MMU_KNOSMAP_IDX 2 ++#define HF_CPL_SHIFT 0 ++#define HF_CPL_MASK (3 << HF_CPL_SHIFT) ++#define AC_MASK 0x00040000 ++#define MMU_KSMAP_IDX 0 ++static inline int cpu_mmu_index_kernel(CPULOONGARCHState *env) ++{ ++ return !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP_IDX : ++ ((env->hflags & HF_CPL_MASK) < 3 && (env->hflags & AC_MASK)) ++ ? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX; ++} ++ ++#define cpu_ldl_kernel_ra(e, p, r) \ ++ cpu_ldl_mmuidx_ra(e, p, cpu_mmu_index_kernel(e), r) ++ ++#define HELPER_LD(name, insn, type) \ ++static inline type do_##name(CPULOONGARCHState *env, target_ulong addr, \ ++ int mem_idx, uintptr_t retaddr) \ ++{ \ ++/* \ ++ switch (mem_idx) { \ ++ case 0: return (type) cpu_##insn##_kernel_ra(env, addr, retaddr); \ ++ case 1: return (type) cpu_##insn##_super_ra(env, addr, retaddr); \ ++ default: \ ++ case 2: return (type) cpu_##insn##_user_ra(env, addr, retaddr); \ ++ case 3: return (type) cpu_##insn##_error_ra(env, addr, retaddr); \ ++ } \ ++*/ \ ++} ++#endif ++#if 0 ++HELPER_LD(lw, ldl, int32_t) ++HELPER_LD(ld, ldq, int64_t) ++#endif ++#undef HELPER_LD ++ ++#if defined(CONFIG_USER_ONLY) ++#define HELPER_ST(name, insn, type) \ ++static inline void do_##name(CPULOONGARCHState *env, target_ulong addr, \ ++ type val, int mem_idx, uintptr_t retaddr) \ ++{ \ ++/* \ ++ cpu_##insn##_data_ra(env, addr, val, retaddr); \ ++*/ \ ++} ++#else ++#define HELPER_ST(name, insn, type) \ ++static inline void do_##name(CPULOONGARCHState *env, target_ulong addr, \ ++ type val, int mem_idx, uintptr_t retaddr) \ ++{ \ ++/* \ ++ switch (mem_idx) { \ ++ case 0: \ ++ cpu_##insn##_kernel_ra(env, addr, val, retaddr); \ ++ break; \ ++ case 1: \ ++ cpu_##insn##_super_ra(env, addr, val, retaddr); \ ++ break; \ ++ default: \ ++ case 2: \ ++ cpu_##insn##_user_ra(env, addr, val, retaddr); \ ++ break; \ ++ case 3: \ ++ cpu_##insn##_error_ra(env, addr, val, retaddr); \ ++ break; \ ++ } \ ++*/ \ ++} ++#endif ++#if 0 ++HELPER_ST(sb, stb, uint8_t) ++HELPER_ST(sw, stl, uint32_t) ++HELPER_ST(sd, stq, uint64_t) ++#endif ++#undef HELPER_ST ++ ++static inline target_ulong bitswap(target_ulong v) ++{ ++ v = ((v >> 1) & (target_ulong)0x5555555555555555ULL) | ++ ((v & (target_ulong)0x5555555555555555ULL) << 1); ++ v = ((v >> 2) & (target_ulong)0x3333333333333333ULL) | ++ ((v & (target_ulong)0x3333333333333333ULL) << 2); ++ v = ((v >> 4) & (target_ulong)0x0F0F0F0F0F0F0F0FULL) | ++ ((v & (target_ulong)0x0F0F0F0F0F0F0F0FULL) << 4); ++ return v; ++} ++ ++target_ulong helper_dbitswap(target_ulong rt) ++{ ++ return bitswap(rt); ++} ++ ++target_ulong helper_bitswap(target_ulong rt) ++{ ++ return (int32_t)bitswap(rt); ++} ++ ++/* these crc32 functions are based on target/arm/helper-a64.c */ ++target_ulong helper_crc32(target_ulong val, target_ulong m, uint32_t sz) ++{ ++ uint8_t buf[8]; ++ target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1); ++ ++ m &= mask; ++ stq_le_p(buf, m); ++ return (int32_t) (crc32(val ^ 0xffffffff, buf, sz) ^ 0xffffffff); ++} ++ ++target_ulong helper_crc32c(target_ulong val, target_ulong m, uint32_t sz) ++{ ++ uint8_t buf[8]; ++ target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1); ++ m &= mask; ++ stq_le_p(buf, m); ++ return (int32_t) (crc32c(val, buf, sz) ^ 0xffffffff); ++} ++ ++#ifndef CONFIG_USER_ONLY ++ ++#define HELPER_LD_ATOMIC(name, insn, almask) \ ++target_ulong helper_##name(CPULOONGARCHState *env, target_ulong arg, int mem_idx) \ ++{ \ ++/* \ ++ if (arg & almask) { \ ++ env->CSR_BADV = arg; \ ++ do_raise_exception(env, EXCP_AdEL, GETPC()); \ ++ } \ ++ env->lladdr = arg; \ ++ env->llval = do_##insn(env, arg, mem_idx, GETPC()); \ ++ return env->llval; \ ++*/ \ ++} ++#if 0 ++HELPER_LD_ATOMIC(ll, lw, 0x3) ++HELPER_LD_ATOMIC(lld, ld, 0x7) ++#endif ++#undef HELPER_LD_ATOMIC ++#endif ++ ++#ifndef CONFIG_USER_ONLY ++void helper_drdtime(CPULOONGARCHState *env, target_ulong rd, target_ulong rs) ++{ ++ env->active_tc.gpr[rd] = cpu_loongarch_get_stable_counter(env); ++ env->active_tc.gpr[rs] = env->CSR_TMID; ++} ++#endif ++ ++#ifndef CONFIG_USER_ONLY ++static void debug_pre_ertn(CPULOONGARCHState *env) ++{ ++ if (qemu_loglevel_mask(CPU_LOG_EXEC)) { ++ qemu_log("ERTN: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx, ++ env->active_tc.PC, env->CSR_ERA); ++ qemu_log("\n"); ++ } ++} ++ ++static void debug_post_ertn(CPULOONGARCHState *env) ++{ ++ if (qemu_loglevel_mask(CPU_LOG_EXEC)) { ++ qemu_log("ERTN: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx, ++ env->active_tc.PC, env->CSR_ERA); ++ } ++} ++ ++static void set_pc(CPULOONGARCHState *env, target_ulong error_pc) ++{ ++ env->active_tc.PC = error_pc & ~(target_ulong)1; ++} ++ ++static inline void exception_return(CPULOONGARCHState *env) ++{ ++ debug_pre_ertn(env); ++ ++ if (cpu_refill_state(env)) { ++ env->CSR_CRMD &= (~0x7); ++ env->CSR_CRMD |= (env->CSR_TLBRPRMD & 0x7); ++ /* Clear Refill flag and set pc */ ++ env->CSR_TLBRERA &= (~0x1); ++ set_pc(env, env->CSR_TLBRERA); ++ if (qemu_loglevel_mask(CPU_LOG_INT)) { ++ qemu_log("%s: TLBRERA 0x%lx\n", __func__, env->CSR_TLBRERA); ++ } ++ } else { ++ env->CSR_CRMD &= (~0x7); ++ env->CSR_CRMD |= (env->CSR_PRMD & 0x7); ++ /* Clear Refill flag and set pc*/ ++ set_pc(env, env->CSR_ERA); ++ if (qemu_loglevel_mask(CPU_LOG_INT)) { ++ qemu_log("%s: ERA 0x%lx\n", __func__, env->CSR_ERA); ++ } ++ } ++ ++ compute_hflags(env); ++ debug_post_ertn(env); ++} ++ ++void helper_ertn(CPULOONGARCHState *env) ++{ ++ exception_return(env); ++ env->lladdr = 1; ++} ++ ++#endif /* !CONFIG_USER_ONLY */ ++ ++void helper_idle(CPULOONGARCHState *env) ++{ ++ CPUState *cs = CPU(loongarch_env_get_cpu(env)); ++ ++ cs->halted = 1; ++ cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE); ++ /* Last instruction in the block, PC was updated before ++ - no need to recover PC and icount */ ++ raise_exception(env, EXCP_HLT); ++} ++ ++#if !defined(CONFIG_USER_ONLY) ++ ++void loongarch_cpu_do_unaligned_access(CPUState *cs, vaddr addr, ++ MMUAccessType access_type, ++ int mmu_idx, uintptr_t retaddr) ++{ ++ while(1); ++} ++ ++#endif /* !CONFIG_USER_ONLY */ ++ ++void helper_store_scr(CPULOONGARCHState *env, uint32_t n, target_ulong val) ++{ ++ env->scr[n & 0x3] = val; ++} ++ ++target_ulong helper_load_scr(CPULOONGARCHState *env, uint32_t n) ++{ ++ return env->scr[n & 0x3]; ++} ++ ++/* loongarch assert op */ ++void helper_asrtle_d(CPULOONGARCHState *env, target_ulong rs, target_ulong rt) ++{ ++ if (rs > rt) { ++ do_raise_exception(env, EXCP_AdEL, GETPC()); ++ } ++} ++ ++void helper_asrtgt_d(CPULOONGARCHState *env, target_ulong rs, target_ulong rt) ++{ ++ if (rs <= rt) { ++ do_raise_exception(env, EXCP_AdEL, GETPC()); ++ } ++} ++ ++target_ulong helper_cto_w(CPULOONGARCHState *env, target_ulong a0) ++{ ++ uint32_t v = (uint32_t)a0; ++ int temp = 0; ++ ++ while ((v & 0x1) == 1) { ++ temp++; ++ v = v >> 1; ++ } ++ ++ return (target_ulong)temp; ++} ++ ++target_ulong helper_ctz_w(CPULOONGARCHState *env, target_ulong a0) ++{ ++ uint32_t v = (uint32_t)a0; ++ ++ if (v == 0) { ++ return 32; ++ } ++ ++ int temp = 0; ++ while ((v & 0x1) == 0) { ++ temp++; ++ v = v >> 1; ++ } ++ ++ return (target_ulong)temp; ++} ++ ++target_ulong helper_cto_d(CPULOONGARCHState *env, target_ulong a0) ++{ ++ uint64_t v = a0; ++ int temp = 0; ++ ++ while ((v & 0x1) == 1) { ++ temp++; ++ v = v >> 1; ++ } ++ ++ return (target_ulong)temp; ++} ++ ++target_ulong helper_ctz_d(CPULOONGARCHState *env, target_ulong a0) ++{ ++ uint64_t v = a0; ++ ++ if (v == 0) { ++ return 64; ++ } ++ ++ int temp = 0; ++ while ((v & 0x1) == 0) { ++ temp++; ++ v = v >> 1; ++ } ++ ++ return (target_ulong)temp; ++} ++ ++target_ulong helper_bitrev_w(CPULOONGARCHState *env, target_ulong a0) ++{ ++ int32_t v = (int32_t)a0; ++ const int SIZE = 32; ++ uint8_t bytes[SIZE]; ++ ++ int i; ++ for (i = 0; i < SIZE; i++) { ++ bytes[i] = v & 0x1; ++ v = v >> 1; ++ } ++ /* v == 0 */ ++ for (i = 0; i < SIZE; i++) { ++ v = v | ((uint32_t)bytes[i] << (SIZE - 1 - i)); ++ } ++ ++ return (target_ulong)(int32_t)v; ++} ++ ++target_ulong helper_bitrev_d(CPULOONGARCHState *env, target_ulong a0) ++{ ++ uint64_t v = a0; ++ const int SIZE = 64; ++ uint8_t bytes[SIZE]; ++ ++ int i; ++ for (i = 0; i < SIZE; i++) { ++ bytes[i] = v & 0x1; ++ v = v >> 1; ++ } ++ /* v == 0 */ ++ for (i = 0; i < SIZE; i++) { ++ v = v | ((uint64_t)bytes[i] << (SIZE - 1 - i)); ++ } ++ ++ return (target_ulong)v; ++} ++ ++void helper_memtrace_addr(CPULOONGARCHState *env, ++ target_ulong address, uint32_t op) ++{ ++ qemu_log("[cpu %d asid 0x%lx pc 0x%lx] addr 0x%lx op", ++ CPU(loongarch_env_get_cpu(env))->cpu_index, ++ env->CSR_ASID, env->active_tc.PC, address); ++ switch (op) { ++ case OPC_LARCH_LDPTR_D: ++ qemu_log("OPC_LARCH_LDPTR_D"); ++ break; ++ case OPC_LARCH_LD_D: ++ qemu_log("OPC_LARCH_LD_D"); ++ break; ++ case OPC_LARCH_LDPTR_W: ++ qemu_log("OPC_LARCH_LDPTR_W"); ++ break; ++ case OPC_LARCH_LD_W: ++ qemu_log("OPC_LARCH_LD_W"); ++ break; ++ case OPC_LARCH_LD_H: ++ qemu_log("OPC_LARCH_LD_H"); ++ break; ++ case OPC_LARCH_LD_B: ++ qemu_log("OPC_LARCH_LD_B"); ++ break; ++ case OPC_LARCH_LD_WU: ++ qemu_log("OPC_LARCH_LD_WU"); ++ break; ++ case OPC_LARCH_LD_HU: ++ qemu_log("OPC_LARCH_LD_HU"); ++ break; ++ case OPC_LARCH_LD_BU: ++ qemu_log("OPC_LARCH_LD_BU"); ++ break; ++ case OPC_LARCH_STPTR_D: ++ qemu_log("OPC_LARCH_STPTR_D"); ++ break; ++ case OPC_LARCH_ST_D: ++ qemu_log("OPC_LARCH_ST_D"); ++ break; ++ case OPC_LARCH_STPTR_W: ++ qemu_log("OPC_LARCH_STPTR_W"); ++ break; ++ case OPC_LARCH_ST_W: ++ qemu_log("OPC_LARCH_ST_W"); ++ break; ++ case OPC_LARCH_ST_H: ++ qemu_log("OPC_LARCH_ST_H"); ++ break; ++ case OPC_LARCH_ST_B: ++ qemu_log("OPC_LARCH_ST_B"); ++ break; ++ case OPC_LARCH_FLD_S: ++ qemu_log("OPC_LARCH_FLD_S"); ++ break; ++ case OPC_LARCH_FLD_D: ++ qemu_log("OPC_LARCH_FLD_D"); ++ break; ++ case OPC_LARCH_FST_S: ++ qemu_log("OPC_LARCH_FST_S"); ++ break; ++ case OPC_LARCH_FST_D: ++ qemu_log("OPC_LARCH_FST_D"); ++ break; ++ case OPC_LARCH_FLDX_S: ++ qemu_log("OPC_LARCH_FLDX_S"); ++ break; ++ case OPC_LARCH_FLDGT_S: ++ qemu_log("OPC_LARCH_FLDGT_S"); ++ break; ++ case OPC_LARCH_FLDLE_S: ++ qemu_log("OPC_LARCH_FLDLE_S"); ++ break;; ++ case OPC_LARCH_FSTX_S: ++ qemu_log("OPC_LARCH_FSTX_S"); ++ break; ++ case OPC_LARCH_FSTGT_S: ++ qemu_log("OPC_LARCH_FSTGT_S"); ++ break; ++ case OPC_LARCH_FSTLE_S: ++ qemu_log("OPC_LARCH_FSTLE_S"); ++ break; ++ case OPC_LARCH_FLDX_D: ++ qemu_log("OPC_LARCH_FLDX_D"); ++ break; ++ case OPC_LARCH_FLDGT_D: ++ qemu_log("OPC_LARCH_FLDGT_D"); ++ break; ++ case OPC_LARCH_FLDLE_D: ++ qemu_log("OPC_LARCH_FLDLE_D"); ++ break;; ++ case OPC_LARCH_FSTX_D: ++ qemu_log("OPC_LARCH_FSTX_D"); ++ break; ++ case OPC_LARCH_FSTGT_D: ++ qemu_log("OPC_LARCH_FSTGT_D"); ++ break; ++ case OPC_LARCH_FSTLE_D: ++ qemu_log("OPC_LARCH_FSTLE_D"); ++ break; ++ case OPC_LARCH_LL_W: ++ qemu_log("OPC_LARCH_LL_W"); ++ break; ++ case OPC_LARCH_LL_D: ++ qemu_log("OPC_LARCH_LL_D"); ++ break; ++ default: ++ qemu_log("0x%x", op); ++ } ++} ++ ++void helper_memtrace_val(CPULOONGARCHState *env, target_ulong val) ++{ ++ qemu_log("val 0x%lx\n", val); ++} +diff --git a/target/loongarch64/stabletimer.c b/target/loongarch64/stabletimer.c +new file mode 100644 +index 000000000..b86fecf89 +--- /dev/null ++++ b/target/loongarch64/stabletimer.c +@@ -0,0 +1,122 @@ ++/* ++ * QEMU LOONGARCH timer support ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ ++#include "qemu/osdep.h" ++#include "hw/loongarch/cpudevs.h" ++#include "qemu/timer.h" ++#include "sysemu/kvm.h" ++#include "internal.h" ++#include "hw/irq.h" ++ ++ ++#ifdef DEBUG_TIMER ++#define debug_timer(fmt, args...) printf("%s(%d)-%s -> " #fmt "\n", \ ++ __FILE__, __LINE__, __func__, ##args); ++#else ++#define debug_timer(fmt, args...) ++#endif ++ ++#define TIMER_PERIOD 10 /* 10 ns period for 100 Mhz frequency */ ++#define STABLETIMER_TICK_MASK 0xfffffffffffcUL ++#define STABLETIMER_ENABLE 0x1UL ++#define STABLETIMER_PERIOD 0x2UL ++ ++/* return random value in [low, high] */ ++uint32_t cpu_loongarch_get_random_ls3a5k_tlb(uint32_t low, uint32_t high) ++{ ++ static uint32_t seed = 5; ++ static uint32_t prev_idx; ++ uint32_t idx; ++ uint32_t nb_rand_tlb = high - low + 1; ++ ++ do { ++ seed = 1103515245 * seed + 12345; ++ idx = (seed >> 16) % nb_rand_tlb + low; ++ } while (idx == prev_idx); ++ prev_idx = idx; ++ ++ return idx; ++} ++ ++/* LOONGARCH timer */ ++uint64_t cpu_loongarch_get_stable_counter(CPULOONGARCHState *env) ++{ ++ return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / TIMER_PERIOD; ++} ++ ++uint64_t cpu_loongarch_get_stable_timer_ticks(CPULOONGARCHState *env) ++{ ++ uint64_t now, expire; ++ ++ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ++ expire = timer_expire_time_ns(env->timer); ++ ++ return (expire - now) / TIMER_PERIOD; ++} ++ ++void cpu_loongarch_store_stable_timer_config(CPULOONGARCHState *env, ++ uint64_t value) ++{ ++ uint64_t now, next; ++ ++ env->CSR_TCFG = value; ++ if (value & STABLETIMER_ENABLE) { ++ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ++ next = now + (value & STABLETIMER_TICK_MASK) * TIMER_PERIOD; ++ timer_mod(env->timer, next); ++ } ++ debug_timer("0x%lx 0x%lx now 0x%lx, next 0x%lx", ++ value, env->CSR_TCFG, now, next); ++} ++ ++static void loongarch_stable_timer_cb(void *opaque) ++{ ++ CPULOONGARCHState *env; ++ uint64_t now, next; ++ ++ env = opaque; ++ debug_timer(); ++ if (env->CSR_TCFG & STABLETIMER_PERIOD) { ++ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ++ next = now + (env->CSR_TCFG & STABLETIMER_TICK_MASK) * TIMER_PERIOD; ++ timer_mod(env->timer, next); ++ } else { ++ env->CSR_TCFG &= ~STABLETIMER_ENABLE; ++ } ++ ++ qemu_irq_raise(env->irq[IRQ_TIMER]); ++ ++} ++ ++void cpu_loongarch_clock_init(LOONGARCHCPU *cpu) ++{ ++ CPULOONGARCHState *env = &cpu->env; ++ ++ /* ++ * If we're in KVM mode, don't create the periodic timer, that is handled in ++ * kernel. ++ */ ++ if (!kvm_enabled()) { ++ env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ++ &loongarch_stable_timer_cb, env); ++ } ++} +diff --git a/target/loongarch64/tlb_helper.c b/target/loongarch64/tlb_helper.c +new file mode 100644 +index 000000000..f5e68349a +--- /dev/null ++++ b/target/loongarch64/tlb_helper.c +@@ -0,0 +1,729 @@ ++/* ++ * loongarch tlb emulation helpers for qemu. ++ * ++ * Copyright (c) 2020 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++#include "qemu/osdep.h" ++#include "qemu/main-loop.h" ++#include "cpu.h" ++#include "internal.h" ++#include "qemu/host-utils.h" ++#include "exec/helper-proto.h" ++#include "exec/exec-all.h" ++#include "exec/cpu_ldst.h" ++ ++#ifndef CONFIG_USER_ONLY ++ ++#define HELPER_LD(name, insn, type) \ ++static inline type do_##name(CPULOONGARCHState *env, target_ulong addr, \ ++ int mem_idx, uintptr_t retaddr) \ ++{ \ ++/* \ ++ switch (mem_idx) { \ ++ case 0: return (type) cpu_##insn##_kernel_ra(env, addr, retaddr); \ ++ case 1: return (type) cpu_##insn##_super_ra(env, addr, retaddr); \ ++ default: \ ++ case 2: return (type) cpu_##insn##_user_ra(env, addr, retaddr); \ ++ case 3: return (type) cpu_##insn##_error_ra(env, addr, retaddr); \ ++ } \ ++*/ \ ++} ++#if 0 ++HELPER_LD(lw, ldl, int32_t) ++HELPER_LD(ld, ldq, int64_t) ++#endif ++ ++void helper_lddir(CPULOONGARCHState *env, target_ulong base, target_ulong rt, ++ target_ulong level, uint32_t mem_idx) ++{ ++#if 0 ++ target_ulong pointer = env->active_tc.gpr[base]; ++ target_ulong badvaddr; ++ target_ulong index; ++ target_ulong vaddr; ++ int shift; ++ ++ badvaddr = env->CSR_TLBRBADV; ++ ++ /* 0:8B, 1:16B, 2:32B, 3:64B */ ++ shift = (env->CSR_PWCTL0 >> 30) & 0x3; ++ shift = (shift + 1) * 3; ++ ++ switch (level) { ++ case 1: ++ index = (badvaddr >> ((env->CSR_PWCTL0 >> 10) & 0x1f)) & \ ++ ((1 << ((env->CSR_PWCTL0 >> 15) & 0x1f)) - 1); ++ break; ++ case 3: ++ index = (badvaddr >> ((env->CSR_PWCTL1 >> 0) & 0x3f)) & \ ++ ((1 << ((env->CSR_PWCTL1 >> 6) & 0x3f)) - 1); ++ break; ++ default: ++ do_raise_exception(env, EXCP_RI, GETPC()); ++ return; ++ } ++ ++ vaddr = pointer | index << shift; ++ env->active_tc.gpr[rt] = do_ld(env, vaddr, mem_idx, GETPC()); ++ return; ++#endif ++} ++ ++void helper_ldpte(CPULOONGARCHState *env, target_ulong base, target_ulong odd, ++ uint32_t mem_idx) ++{ ++#if 0 ++ target_ulong pointer = env->active_tc.gpr[base]; ++ target_ulong vaddr; ++ target_ulong tmp0 = 1; ++ target_ulong ptindex, ptoffset0, ptoffset1; ++ target_ulong pagesize; ++ target_ulong badv; ++ int shift; ++ bool huge = pointer & LOONGARCH_PAGE_HUGE; ++ ++ if (huge) { ++ /* Huge Page. pointer is paddr */ ++ tmp0 = pointer ^ LOONGARCH_PAGE_HUGE; ++ /* move Global bit */ ++ tmp0 |= ((tmp0 & LOONGARCH_HUGE_GLOBAL) ++ >> (LOONGARCH_HUGE_GLOBAL_SH - CSR_TLBLO0_GLOBAL_SHIFT)); ++ pagesize = (env->CSR_PWCTL0 & 0x1f) + ++ ((env->CSR_PWCTL0 >> 5) & 0x1f) - 1; ++ if (odd) { ++ tmp0 += (1 << pagesize); ++ } ++ } else { ++ /* 0:8B, 1:16B, 2:32B, 3:64B */ ++ shift = (env->CSR_PWCTL0 >> 30) & 0x3; ++ shift = (shift + 1) * 3; ++ badv = env->CSR_TLBRBADV; ++ ++ ptindex = (badv >> (env->CSR_PWCTL0 & 0x1f)) & ++ ((1 << ((env->CSR_PWCTL0 >> 5) & 0x1f)) - 1); ++ ptindex = ptindex & ~0x1; /* clear bit 0 */ ++ ptoffset0 = ptindex << shift; ++ ptoffset1 = (ptindex + 1) << shift; ++ ++ vaddr = pointer | (odd ? ptoffset1 : ptoffset0); ++ tmp0 = do_ld(env, vaddr, mem_idx, GETPC()); ++ pagesize = (env->CSR_PWCTL0 & 0x1f); ++ } ++ if (odd) { ++ env->CSR_TLBRELO1 = tmp0; ++ } else { ++ env->CSR_TLBRELO0 = tmp0; ++ } ++ env->CSR_TLBREHI = env->CSR_TLBREHI & (~0x3f); ++ env->CSR_TLBREHI = env->CSR_TLBREHI | pagesize; ++#endif ++ return; ++} ++ ++target_ulong helper_read_pgd(CPULOONGARCHState *env) ++{ ++ uint64_t badv; ++ ++ assert(env->CSR_TLBRERA & 0x1); ++ ++ if (env->CSR_TLBRERA & 0x1) { ++ badv = env->CSR_TLBRBADV; ++ } else { ++ badv = env->CSR_BADV; ++ } ++ ++ if ((badv >> 63) & 0x1) { ++ return env->CSR_PGDH; ++ } else { ++ return env->CSR_PGDL; ++ } ++} ++ ++/* TLB management */ ++static uint64_t ls3a5k_pagesize_to_mask(int pagesize) ++{ ++ /* 4KB - 1GB */ ++ if (pagesize < 12 && pagesize > 30) { ++ printf("[ERROR] unsupported page size %d\n", pagesize); ++ exit(-1); ++ } ++ ++ return (1 << (pagesize + 1)) - 1; ++} ++ ++static void ls3a5k_fill_tlb_entry(CPULOONGARCHState *env, ++ ls3a5k_tlb_t *tlb, int is_ftlb) ++{ ++ uint64_t page_mask; /* 0000...00001111...1111 */ ++ uint32_t page_size; ++ uint64_t entryhi; ++ uint64_t lo0, lo1; ++ ++ if (env->CSR_TLBRERA & 0x1) { ++ page_size = env->CSR_TLBREHI & 0x3f; ++ entryhi = env->CSR_TLBREHI; ++ lo0 = env->CSR_TLBRELO0; ++ lo1 = env->CSR_TLBRELO1; ++ } else { ++ page_size = (env->CSR_TLBIDX >> CSR_TLBIDX_PS_SHIFT) & 0x3f; ++ entryhi = env->CSR_TLBEHI; ++ lo0 = env->CSR_TLBELO0; ++ lo1 = env->CSR_TLBELO1; ++ } ++ ++ if (page_size == 0) { ++ printf("Warning: page_size is 0\n"); ++ } ++ ++ /* 15-12 11-8 7-4 3-0 ++ * 4KB: 0001 1111 1111 1111 // double 4KB mask [12:0] ++ * 16KB: 0111 1111 1111 1111 // double 16KB mask [14:0] ++ */ ++ if (is_ftlb) { ++ page_mask = env->tlb->mmu.ls3a5k.ftlb_mask; ++ } else { ++ page_mask = ls3a5k_pagesize_to_mask(page_size); ++ } ++ ++ tlb->VPN = entryhi & 0xffffffffe000 & ~page_mask; ++ ++ tlb->ASID = env->CSR_ASID & 0x3ff; /* CSR_ASID[9:0] */ ++ tlb->EHINV = 0; ++ tlb->G = (lo0 >> CSR_TLBLO0_GLOBAL_SHIFT) & /* CSR_TLBLO[6] */ ++ (lo1 >> CSR_TLBLO1_GLOBAL_SHIFT) & 1; ++ ++ tlb->PageMask = page_mask; ++ tlb->PageSize = page_size; ++ ++ tlb->V0 = (lo0 >> CSR_TLBLO0_V_SHIFT) & 0x1; /* [0] */ ++ tlb->WE0 = (lo0 >> CSR_TLBLO0_WE_SHIFT) & 0x1; /* [1] */ ++ tlb->PLV0 = (lo0 >> CSR_TLBLO0_PLV_SHIFT) & 0x3; /* [3:2] */ ++ tlb->C0 = (lo0 >> CSR_TLBLO0_CCA_SHIFT) & 0x3; /* [5:4] */ ++ tlb->PPN0 = (lo0 & 0xfffffffff000 & ~(page_mask >> 1)); ++ tlb->RI0 = (lo0 >> CSR_TLBLO0_RI_SHIFT) & 0x1; /* [61] */ ++ tlb->XI0 = (lo0 >> CSR_TLBLO0_XI_SHIFT) & 0x1; /* [62] */ ++ tlb->RPLV0 = (lo0 >> CSR_TLBLO0_RPLV_SHIFT) & 0x1; /* [63] */ ++ ++ tlb->V1 = (lo1 >> CSR_TLBLO1_V_SHIFT) & 0x1; /* [0] */ ++ tlb->WE1 = (lo1 >> CSR_TLBLO1_WE_SHIFT) & 0x1; /* [1] */ ++ tlb->PLV1 = (lo1 >> CSR_TLBLO1_PLV_SHIFT) & 0x3; /* [3:2] */ ++ tlb->C1 = (lo1 >> CSR_TLBLO1_CCA_SHIFT) & 0x3; /* [5:4] */ ++ tlb->PPN1 = (lo1 & 0xfffffffff000 & ~(page_mask >> 1)); ++ tlb->RI1 = (lo1 >> CSR_TLBLO1_RI_SHIFT) & 0x1; /* [61] */ ++ tlb->XI1 = (lo1 >> CSR_TLBLO1_XI_SHIFT) & 0x1; /* [62] */ ++ tlb->RPLV1 = (lo1 >> CSR_TLBLO1_RPLV_SHIFT) & 0x1; /* [63] */ ++} ++ ++static void ls3a5k_fill_tlb(CPULOONGARCHState *env, int idx, bool tlbwr) ++{ ++ ls3a5k_tlb_t *tlb; ++ ++ tlb = &env->tlb->mmu.ls3a5k.tlb[idx]; ++ if (tlbwr) { ++ if ((env->CSR_TLBIDX >> CSR_TLBIDX_EHINV_SHIFT) & 0x1) { ++ tlb->EHINV = 1; ++ return; ++ } ++ } ++ ++ if (idx < 2048) { ++ ls3a5k_fill_tlb_entry(env, tlb, 1); ++ } else { ++ ls3a5k_fill_tlb_entry(env, tlb, 0); ++ } ++} ++ ++void ls3a5k_flush_vtlb(CPULOONGARCHState *env) ++{ ++ uint32_t ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; ++ uint32_t vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; ++ int i; ++ ++ ls3a5k_tlb_t *tlb; ++ ++ for (i = ftlb_size; i < ftlb_size + vtlb_size; ++i) { ++ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ tlb->EHINV = 1; ++ } ++ ++ cpu_loongarch_tlb_flush(env); ++} ++ ++void ls3a5k_flush_ftlb(CPULOONGARCHState *env) ++{ ++ uint32_t ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; ++ int i; ++ ++ ls3a5k_tlb_t *tlb; ++ ++ for (i = 0; i < ftlb_size; ++i) { ++ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ tlb->EHINV = 1; ++ } ++ ++ cpu_loongarch_tlb_flush(env); ++} ++ ++void ls3a5k_helper_tlbclr(CPULOONGARCHState *env) ++{ ++ int i; ++ uint16_t asid; ++ int vsize, fsize, index; ++ int start = 0, end = -1; ++ ++ asid = env->CSR_ASID & 0x3ff; ++ vsize = env->tlb->mmu.ls3a5k.vtlb_size; ++ fsize = env->tlb->mmu.ls3a5k.ftlb_size; ++ index = env->CSR_TLBIDX & CSR_TLBIDX_IDX; ++ ++ if (index < fsize) { ++ /* FTLB. One line per operation */ ++ int set = index % 256; ++ start = set * 8; ++ end = start + 7; ++ } else if (index < (fsize + vsize)) { ++ /* VTLB. All entries */ ++ start = fsize; ++ end = fsize + vsize - 1; ++ } else { ++ /* Ignore */ ++ } ++ ++ for (i = start; i <= end; i++) { ++ ls3a5k_tlb_t *tlb; ++ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ if (!tlb->G && tlb->ASID == asid) { ++ tlb->EHINV = 1; ++ } ++ } ++ ++ cpu_loongarch_tlb_flush(env); ++} ++ ++void ls3a5k_helper_tlbflush(CPULOONGARCHState *env) ++{ ++ int i; ++ int vsize, fsize, index; ++ int start = 0, end = -1; ++ ++ vsize = env->tlb->mmu.ls3a5k.vtlb_size; ++ fsize = env->tlb->mmu.ls3a5k.ftlb_size; ++ index = env->CSR_TLBIDX & CSR_TLBIDX_IDX; ++ ++ if (index < fsize) { ++ /* FTLB. One line per operation */ ++ int set = index % 256; ++ start = set * 8; ++ end = start + 7; ++ } else if (index < (fsize + vsize)) { ++ /* VTLB. All entries */ ++ start = fsize; ++ end = fsize + vsize - 1; ++ } else { ++ /* Ignore */ ++ } ++ ++ for (i = start; i <= end; i++) { ++ env->tlb->mmu.ls3a5k.tlb[i].EHINV = 1; ++ } ++ ++ cpu_loongarch_tlb_flush(env); ++} ++ ++void ls3a5k_helper_invtlb(CPULOONGARCHState *env, target_ulong addr, ++ target_ulong info, int op) ++{ ++ uint32_t asid = info & 0x3ff; ++ int i; ++ ++ switch (op) { ++ case 0: ++ case 1: ++ for (i = 0; i < env->tlb->nb_tlb; i++) { ++ env->tlb->mmu.ls3a5k.tlb[i].EHINV = 1; ++ } ++ break; ++ case 4: { ++ int i; ++ for (i = 0; i < env->tlb->nb_tlb; i++) { ++ struct ls3a5k_tlb_t *tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ ++ if (!tlb->G && tlb->ASID == asid) { ++ tlb->EHINV = 1; ++ } ++ } ++ break; ++ } ++ ++ case 5: { ++ int i; ++ for (i = 0; i < env->tlb->nb_tlb; i++) { ++ struct ls3a5k_tlb_t *tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ uint64_t vpn = addr & 0xffffffffe000 & ~tlb->PageMask; ++ ++ if (!tlb->G && tlb->ASID == asid && vpn == tlb->VPN) { ++ tlb->EHINV = 1; ++ } ++ } ++ break; ++ } ++ case 6: { ++ int i; ++ for (i = 0; i < env->tlb->nb_tlb; i++) { ++ struct ls3a5k_tlb_t *tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ uint64_t vpn = addr & 0xffffffffe000 & ~tlb->PageMask; ++ ++ if ((tlb->G || tlb->ASID == asid) && vpn == tlb->VPN) { ++ tlb->EHINV = 1; ++ } ++ } ++ break; ++ } ++ default: ++ helper_raise_exception(env, EXCP_RI); ++ } ++ ++ cpu_loongarch_tlb_flush(env); ++} ++ ++static void ls3a5k_invalidate_tlb_entry(CPULOONGARCHState *env, ++ ls3a5k_tlb_t *tlb) ++{ ++ LOONGARCHCPU *cpu = loongarch_env_get_cpu(env); ++ CPUState *cs = CPU(cpu); ++ target_ulong addr; ++ target_ulong end; ++ target_ulong mask; ++ ++ mask = tlb->PageMask; /* 000...000111...111 */ ++ ++ if (tlb->V0) { ++ addr = tlb->VPN & ~mask; /* xxx...xxx[0]000..0000 */ ++ end = addr | (mask >> 1); /* xxx...xxx[0]111..1111 */ ++ while (addr < end) { ++ tlb_flush_page(cs, addr); ++ addr += TARGET_PAGE_SIZE; ++ } ++ } ++ ++ if (tlb->V1) { ++ /* xxx...xxx[1]000..0000 */ ++ addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1); ++ end = addr | mask; /* xxx...xxx[1]111..1111 */ ++ while (addr - 1 < end) { ++ tlb_flush_page(cs, addr); ++ addr += TARGET_PAGE_SIZE; ++ } ++ } ++} ++ ++void ls3a5k_invalidate_tlb(CPULOONGARCHState *env, int idx) ++{ ++ ls3a5k_tlb_t *tlb; ++ int asid = env->CSR_ASID & 0x3ff; ++ tlb = &env->tlb->mmu.ls3a5k.tlb[idx]; ++ if (tlb->G == 0 && tlb->ASID != asid) { ++ return; ++ } ++ ls3a5k_invalidate_tlb_entry(env, tlb); ++} ++ ++void ls3a5k_helper_tlbwr(CPULOONGARCHState *env) ++{ ++ int idx = env->CSR_TLBIDX & CSR_TLBIDX_IDX; /* [11:0] */ ++ ++ /* Convert idx if in FTLB */ ++ if (idx < env->tlb->mmu.ls3a5k.ftlb_size) { ++ /* ++ * 0 3 6 0 1 2 ++ * 1 4 7 => 3 4 5 ++ * 2 5 8 6 7 8 ++ */ ++ int set = idx % 256; ++ int way = idx / 256; ++ idx = set * 8 + way; ++ } ++ ls3a5k_invalidate_tlb(env, idx); ++ ls3a5k_fill_tlb(env, idx, true); ++} ++ ++void ls3a5k_helper_tlbfill(CPULOONGARCHState *env) ++{ ++ uint64_t mask; ++ uint64_t address; ++ int idx; ++ int set, ftlb_idx; ++ ++ uint64_t entryhi; ++ uint32_t pagesize; ++ ++ if (env->CSR_TLBRERA & 0x1) { ++ entryhi = env->CSR_TLBREHI & ~0x3f; ++ pagesize = env->CSR_TLBREHI & 0x3f; ++ } else { ++ entryhi = env->CSR_TLBEHI; ++ pagesize = (env->CSR_TLBIDX >> CSR_TLBIDX_PS_SHIFT) & 0x3f; ++ } ++ ++ uint32_t ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; ++ uint32_t vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; ++ ++ mask = ls3a5k_pagesize_to_mask(pagesize); ++ ++ if (mask == env->tlb->mmu.ls3a5k.ftlb_mask && ++ env->tlb->mmu.ls3a5k.ftlb_size > 0) { ++ /* only write into FTLB */ ++ address = entryhi & 0xffffffffe000; /* [47:13] */ ++ ++ /* choose one set ramdomly */ ++ set = cpu_loongarch_get_random_ls3a5k_tlb(0, 7); ++ ++ /* index in one set */ ++ ftlb_idx = (address >> 15) & 0xff; /* [0,255] */ ++ ++ /* final idx */ ++ idx = ftlb_idx * 8 + set; /* max is 7 + 8 * 255 = 2047 */ ++ } else { ++ /* only write into VTLB */ ++ int wired_nr = env->CSR_TLBWIRED & 0x3f; ++ idx = cpu_loongarch_get_random_ls3a5k_tlb( ++ ftlb_size + wired_nr, ftlb_size + vtlb_size - 1); ++ } ++ ++ ls3a5k_invalidate_tlb(env, idx); ++ ls3a5k_fill_tlb(env, idx, false); ++} ++ ++void ls3a5k_helper_tlbsrch(CPULOONGARCHState *env) ++{ ++ uint64_t mask; ++ uint64_t vpn; ++ uint64_t tag; ++ uint16_t asid; ++ ++ int ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; ++ int vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; ++ int i; ++ int ftlb_idx; /* [0,255] 2^8 0xff */ ++ ++ ls3a5k_tlb_t *tlb; ++ ++ asid = env->CSR_ASID & 0x3ff; ++ ++ /* search VTLB */ ++ for (i = ftlb_size; i < ftlb_size + vtlb_size; ++i) { ++ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; ++ mask = tlb->PageMask; ++ ++ vpn = env->CSR_TLBEHI & 0xffffffffe000 & ~mask; ++ tag = tlb->VPN & ~mask; ++ ++ if ((tlb->G == 1 || tlb->ASID == asid) && vpn == tag && tlb->EHINV != 1) ++ { ++ env->CSR_TLBIDX = (i & 0xfff) | ++ ((tlb->PageSize & 0x3f) << CSR_TLBIDX_PS_SHIFT); ++ goto _MATCH_OUT_; ++ } ++ } ++ ++ if (ftlb_size == 0) { ++ goto _NO_MATCH_OUT_; ++ } ++ ++ /* search FTLB */ ++ mask = env->tlb->mmu.ls3a5k.ftlb_mask; ++ vpn = env->CSR_TLBEHI & 0xffffffffe000 & ~mask; ++ ++ ftlb_idx = (env->CSR_TLBEHI & 0xffffffffe000) >> 15; /* 16 KB */ ++ ftlb_idx = ftlb_idx & 0xff; /* [0,255] */ ++ ++ for (i = 0; i < 8; ++i) { ++ tlb = &env->tlb->mmu.ls3a5k.tlb[ftlb_idx * 8 + i]; ++ tag = tlb->VPN & ~mask; ++ ++ if ((tlb->G == 1 || tlb->ASID == asid) && vpn == tag && tlb->EHINV != 1) ++ { ++ env->CSR_TLBIDX = ((i * 256 + ftlb_idx) & 0xfff) | ++ ((tlb->PageSize & 0x3f) << CSR_TLBIDX_PS_SHIFT); ++ goto _MATCH_OUT_; ++ } ++ } ++ ++_NO_MATCH_OUT_: ++ env->CSR_TLBIDX = 1 << CSR_TLBIDX_EHINV_SHIFT; ++_MATCH_OUT_: ++ return; ++} ++ ++void ls3a5k_helper_tlbrd(CPULOONGARCHState *env) ++{ ++ ls3a5k_tlb_t *tlb; ++ int idx; ++ uint16_t asid; ++ ++ idx = env->CSR_TLBIDX & CSR_TLBIDX_IDX; ++ if (idx < env->tlb->mmu.ls3a5k.ftlb_size) { ++ int set = idx % 256; ++ int way = idx / 256; ++ idx = set * 8 + way; ++ } ++ ++ tlb = &env->tlb->mmu.ls3a5k.tlb[idx]; ++ ++ asid = env->CSR_ASID & 0x3ff; ++ ++ if (asid != tlb->ASID) { ++ cpu_loongarch_tlb_flush(env); ++ } ++ ++ if (tlb->EHINV) { ++ /* invalid TLB entry */ ++ env->CSR_TLBIDX = 1 << CSR_TLBIDX_EHINV_SHIFT; ++ env->CSR_TLBEHI = 0; ++ env->CSR_TLBELO0 = 0; ++ env->CSR_TLBELO1 = 0; ++ } else { ++ /* valid TLB entry */ ++ env->CSR_TLBIDX = (env->CSR_TLBIDX & 0xfff) | ++ ((tlb->PageSize & 0x3f) << CSR_TLBIDX_PS_SHIFT); ++ env->CSR_TLBEHI = tlb->VPN; ++ env->CSR_TLBELO0 = (tlb->V0 << CSR_TLBLO0_V_SHIFT) | ++ (tlb->WE0 << CSR_TLBLO0_WE_SHIFT) | ++ (tlb->PLV0 << CSR_TLBLO0_PLV_SHIFT) | ++ (tlb->C0 << CSR_TLBLO0_CCA_SHIFT) | ++ (tlb->G << CSR_TLBLO0_GLOBAL_SHIFT) | ++ (tlb->PPN0 & 0xfffffffff000) | ++ ((uint64_t)tlb->RI0 << CSR_TLBLO0_RI_SHIFT) | ++ ((uint64_t)tlb->XI0 << CSR_TLBLO0_XI_SHIFT) | ++ ((uint64_t)tlb->RPLV0 << CSR_TLBLO0_RPLV_SHIFT); ++ env->CSR_TLBELO1 = (tlb->V1 << CSR_TLBLO1_V_SHIFT) | ++ (tlb->WE1 << CSR_TLBLO1_WE_SHIFT) | ++ (tlb->PLV1 << CSR_TLBLO1_PLV_SHIFT) | ++ (tlb->C1 << CSR_TLBLO1_CCA_SHIFT) | ++ (tlb->G << CSR_TLBLO0_GLOBAL_SHIFT) | ++ (tlb->PPN1 & 0xfffffffff000) | ++ ((uint64_t)tlb->RI1 << CSR_TLBLO1_RI_SHIFT) | ++ ((uint64_t)tlb->XI1 << CSR_TLBLO1_XI_SHIFT) | ++ ((uint64_t)tlb->RPLV1 << CSR_TLBLO1_RPLV_SHIFT); ++ env->CSR_ASID = (tlb->ASID << CSR_ASID_ASID_SHIFT) | ++ (env->CSR_ASID & 0xff0000); ++ } ++} ++ ++void helper_tlbwr(CPULOONGARCHState *env) ++{ ++ env->tlb->helper_tlbwr(env); ++} ++ ++void helper_tlbfill(CPULOONGARCHState *env) ++{ ++ env->tlb->helper_tlbfill(env); ++} ++ ++void helper_tlbsrch(CPULOONGARCHState *env) ++{ ++ env->tlb->helper_tlbsrch(env); ++} ++ ++void helper_tlbrd(CPULOONGARCHState *env) ++{ ++ env->tlb->helper_tlbrd(env); ++} ++ ++void helper_tlbclr(CPULOONGARCHState *env) ++{ ++ env->tlb->helper_tlbclr(env); ++} ++ ++void helper_tlbflush(CPULOONGARCHState *env) ++{ ++ env->tlb->helper_tlbflush(env); ++} ++ ++void helper_invtlb(CPULOONGARCHState *env, target_ulong addr, target_ulong info, ++ target_ulong op) ++{ ++ env->tlb->helper_invtlb(env, addr, info, op); ++} ++ ++static void ls3a5k_mmu_init(CPULOONGARCHState *env, const loongarch_def_t *def) ++{ ++ /* number of VTLB */ ++ env->tlb->nb_tlb = 64; ++ env->tlb->mmu.ls3a5k.vtlb_size = 64; ++ ++ /* number of FTLB */ ++ env->tlb->nb_tlb += 2048; ++ env->tlb->mmu.ls3a5k.ftlb_size = 2048; ++ env->tlb->mmu.ls3a5k.ftlb_mask = (1 << 15) - 1; /* 16 KB */ ++ /* ++ * page_size | ftlb_mask | party field ++ * ---------------------------------------------------------------- ++ * 4 KB = 12 | ( 1 << 13 ) - 1 = [12:0] | [12] ++ * 16 KB = 14 | ( 1 << 15 ) - 1 = [14:0] | [14] ++ * 64 KB = 16 | ( 1 << 17 ) - 1 = [16:0] | [16] ++ * 256 KB = 18 | ( 1 << 19 ) - 1 = [18:0] | [18] ++ * 1 MB = 20 | ( 1 << 21 ) - 1 = [20:0] | [20] ++ * 4 MB = 22 | ( 1 << 23 ) - 1 = [22:0] | [22] ++ * 16 MB = 24 | ( 1 << 25 ) - 1 = [24:0] | [24] ++ * 64 MB = 26 | ( 1 << 27 ) - 1 = [26:0] | [26] ++ * 256 MB = 28 | ( 1 << 29 ) - 1 = [28:0] | [28] ++ * 1 GB = 30 | ( 1 << 31 ) - 1 = [30:0] | [30] ++ * ---------------------------------------------------------------- ++ * take party field index as @n. eg. For 16 KB, n = 14 ++ * ---------------------------------------------------------------- ++ * tlb->VPN = TLBEHI & 0xffffffffe000[47:13] & ~mask = [47:n+1] ++ * tlb->PPN = TLBLO0 & 0xffffffffe000[47:13] & ~mask = [47:n+1] ++ * tlb->PPN = TLBLO1 & 0xffffffffe000[47:13] & ~mask = [47:n+1] ++ * ---------------------------------------------------------------- ++ * On mapping : ++ * > vpn = address & 0xffffffffe000[47:13] & ~mask = [47:n+1] ++ * > tag = tlb->VPN & ~mask = [47:n+1] ++ * ---------------------------------------------------------------- ++ * physical address = [47:n+1] | [n:0] ++ * physical address = tlb->PPN0 | (address & mask) ++ * physical address = tlb->PPN1 | (address & mask) ++ */ ++ ++ int i; ++ for (i = 0; i < env->tlb->nb_tlb; i++) { ++ env->tlb->mmu.ls3a5k.tlb[i].EHINV = 1; ++ } ++ ++ /* TLB's helper functions */ ++ env->tlb->map_address = &ls3a5k_map_address; ++ env->tlb->helper_tlbwr = ls3a5k_helper_tlbwr; ++ env->tlb->helper_tlbfill = ls3a5k_helper_tlbfill; ++ env->tlb->helper_tlbsrch = ls3a5k_helper_tlbsrch; ++ env->tlb->helper_tlbrd = ls3a5k_helper_tlbrd; ++ env->tlb->helper_tlbclr = ls3a5k_helper_tlbclr; ++ env->tlb->helper_tlbflush = ls3a5k_helper_tlbflush; ++ env->tlb->helper_invtlb = ls3a5k_helper_invtlb; ++} ++ ++void mmu_init(CPULOONGARCHState *env, const loongarch_def_t *def) ++{ ++ env->tlb = g_malloc0(sizeof(CPULOONGARCHTLBContext)); ++ ++ switch (def->mmu_type) { ++ case MMU_TYPE_LS3A5K: ++ ls3a5k_mmu_init(env, def); ++ break; ++ default: ++ cpu_abort(CPU(loongarch_env_get_cpu(env)), "MMU type not supported\n"); ++ } ++} ++#endif /* !CONFIG_USER_ONLY */ +diff --git a/target/loongarch64/trace-events b/target/loongarch64/trace-events +new file mode 100644 +index 000000000..e0bca4f82 +--- /dev/null ++++ b/target/loongarch64/trace-events +@@ -0,0 +1,3 @@ ++# See docs/devel/tracing.txt for syntax documentation. ++ ++# target/loongarch/translate.c +diff --git a/target/loongarch64/trans.inc.c b/target/loongarch64/trans.inc.c +new file mode 100644 +index 000000000..e50670be4 +--- /dev/null ++++ b/target/loongarch64/trans.inc.c +@@ -0,0 +1,3472 @@ ++static bool trans_syscall(DisasContext *ctx, arg_syscall *a) ++{ ++ generate_exception_end(ctx, EXCP_SYSCALL); ++ return true; ++} ++ ++static bool trans_break(DisasContext *ctx, arg_break *a) ++{ ++ generate_exception_end(ctx, EXCP_BREAK); ++ return true; ++} ++ ++static bool trans_dbcl(DisasContext *ctx, arg_dbcl *a) ++{ ++ /* ++ * dbcl instruction is not support in tcg ++ */ ++ generate_exception_end(ctx, EXCP_RI); ++ return true; ++} ++ ++static bool trans_addi_w(DisasContext *ctx, arg_addi_w *a) ++{ ++ gen_arith_imm(ctx, OPC_LARCH_ADDI_W, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_addi_d(DisasContext *ctx, arg_addi_d *a) ++{ ++ gen_arith_imm(ctx, OPC_LARCH_ADDI_D, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_slli_d(DisasContext *ctx, arg_slli_d *a) ++{ ++ if (a->rd == 0) { ++ /* Nop */ ++ return true; ++ } ++ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ tcg_gen_shli_tl(cpu_gpr[a->rd], t0, a->ui6); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_andi(DisasContext *ctx, arg_andi *a) ++{ ++ gen_logic_imm(ctx, OPC_LARCH_ANDI, a->rd, a->rj, a->ui12); ++ return true; ++} ++ ++static bool trans_srli_d(DisasContext *ctx, arg_srli_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ tcg_gen_shri_tl(cpu_gpr[a->rd], t0, a->ui6); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_slli_w(DisasContext *ctx, arg_slli_w *a) ++{ ++ if (a->rd == 0) { ++ /* Nop */ ++ return true; ++ } ++ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ tcg_gen_shli_tl(t0, t0, a->ui5); ++ tcg_gen_ext32s_tl(cpu_gpr[a->rd], t0); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_addu16i_d(DisasContext *ctx, arg_addu16i_d *a) ++{ ++ if (a->rj != 0) { ++ tcg_gen_addi_tl(cpu_gpr[a->rd], cpu_gpr[a->rj], a->si16 << 16); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[a->rd], a->si16 << 16); ++ } ++ return true; ++} ++ ++static bool trans_lu12i_w(DisasContext *ctx, arg_lu12i_w *a) ++{ ++ tcg_gen_movi_tl(cpu_gpr[a->rd], a->si20 << 12); ++ return true; ++} ++ ++static bool trans_lu32i_d(DisasContext *ctx, arg_lu32i_d *a) ++{ ++ TCGv_i64 t0, t1; ++ t0 = tcg_temp_new_i64(); ++ t1 = tcg_temp_new_i64(); ++ ++ tcg_gen_movi_tl(t0, a->si20); ++ tcg_gen_concat_tl_i64(t1, cpu_gpr[a->rd], t0); ++ gen_store_gpr(t1, a->rd); ++ ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_pcaddi(DisasContext *ctx, arg_pcaddi *a) ++{ ++ target_ulong pc = ctx->base.pc_next; ++ target_ulong addr = pc + (a->si20 << 2); ++ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); ++ return true; ++} ++ ++static bool trans_pcalau12i(DisasContext *ctx, arg_pcalau12i *a) ++{ ++ target_ulong pc = ctx->base.pc_next; ++ target_ulong addr = (pc + (a->si20 << 12)) & ~0xfff; ++ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); ++ return true; ++} ++ ++static bool trans_pcaddu12i(DisasContext *ctx, arg_pcaddu12i *a) ++{ ++ target_ulong pc = ctx->base.pc_next; ++ target_ulong addr = pc + (a->si20 << 12); ++ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); ++ return true; ++} ++ ++static bool trans_pcaddu18i(DisasContext *ctx, arg_pcaddu18i *a) ++{ ++ target_ulong pc = ctx->base.pc_next; ++ target_ulong addr = pc + ((target_ulong)(a->si20) << 18); ++ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); ++ return true; ++} ++ ++static bool trans_slti(DisasContext *ctx, arg_slti *a) ++{ ++ gen_slt_imm(ctx, OPC_LARCH_SLTI, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_sltui(DisasContext *ctx, arg_sltui *a) ++{ ++ gen_slt_imm(ctx, OPC_LARCH_SLTIU, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_lu52i_d(DisasContext *ctx, arg_lu52i_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ ++ gen_load_gpr(t1, a->rj); ++ ++ tcg_gen_movi_tl(t0, a->si12); ++ tcg_gen_shli_tl(t0, t0, 52); ++ tcg_gen_andi_tl(t1, t1, 0xfffffffffffffU); ++ tcg_gen_or_tl(cpu_gpr[a->rd], t0, t1); ++ ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_ori(DisasContext *ctx, arg_ori *a) ++{ ++ gen_logic_imm(ctx, OPC_LARCH_ORI, a->rd, a->rj, a->ui12); ++ return true; ++} ++ ++static bool trans_xori(DisasContext *ctx, arg_xori *a) ++{ ++ gen_logic_imm(ctx, OPC_LARCH_XORI, a->rd, a->rj, a->ui12); ++ return true; ++} ++ ++static bool trans_bstrins_d(DisasContext *ctx, arg_bstrins_d *a) ++{ ++ int lsb = a->lsbd; ++ int msb = a->msbd; ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ ++ if (lsb > msb) { ++ return false; ++ } ++ ++ gen_load_gpr(t1, a->rj); ++ gen_load_gpr(t0, a->rd); ++ tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); ++ gen_store_gpr(t0, a->rd); ++ ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_bstrpick_d(DisasContext *ctx, arg_bstrpick_d *a) ++{ ++ int lsb = a->lsbd; ++ int msb = a->msbd; ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ ++ if (lsb > msb) { ++ return false; ++ } ++ ++ gen_load_gpr(t1, a->rj); ++ gen_load_gpr(t0, a->rd); ++ tcg_gen_extract_tl(t0, t1, lsb, msb - lsb + 1); ++ gen_store_gpr(t0, a->rd); ++ ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_bstrins_w(DisasContext *ctx, arg_bstrins_w *a) ++{ ++ gen_bitops(ctx, OPC_LARCH_TRINS_W, a->rd, a->rj, a->lsbw, a->msbw); ++ return true; ++} ++ ++static bool trans_bstrpick_w(DisasContext *ctx, arg_bstrpick_w *a) ++{ ++ if (a->lsbw > a->msbw) { ++ return false; ++ } ++ gen_bitops(ctx, OPC_LARCH_TRPICK_W, ++ a->rd, a->rj, a->lsbw, a->msbw - a->lsbw); ++ return true; ++} ++ ++static bool trans_ldptr_w(DisasContext *ctx, arg_ldptr_w *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LDPTR_W, a->rd, a->rj, a->si14 << 2); ++ return true; ++} ++ ++static bool trans_stptr_w(DisasContext *ctx, arg_stptr_w *a) ++{ ++ gen_st(ctx, OPC_LARCH_STPTR_W, a->rd, a->rj, a->si14 << 2); ++ return true; ++} ++ ++static bool trans_ldptr_d(DisasContext *ctx, arg_ldptr_d *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LDPTR_D, a->rd, a->rj, a->si14 << 2); ++ return true; ++} ++ ++static bool trans_stptr_d(DisasContext *ctx, arg_stptr_d *a) ++{ ++ gen_st(ctx, OPC_LARCH_STPTR_D, a->rd, a->rj, a->si14 << 2); ++ return true; ++} ++ ++static bool trans_ld_b(DisasContext *ctx, arg_ld_b *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_B, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ld_h(DisasContext *ctx, arg_ld_h *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_H, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ld_w(DisasContext *ctx, arg_ld_w *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_W, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ld_d(DisasContext *ctx, arg_ld_d *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_D, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_st_b(DisasContext *ctx, arg_st_b *a) ++{ ++ gen_st(ctx, OPC_LARCH_ST_B, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_st_h(DisasContext *ctx, arg_st_h *a) ++{ ++ gen_st(ctx, OPC_LARCH_ST_H, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_st_w(DisasContext *ctx, arg_st_w *a) ++{ ++ gen_st(ctx, OPC_LARCH_ST_W, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_st_d(DisasContext *ctx, arg_st_d *a) ++{ ++ gen_st(ctx, OPC_LARCH_ST_D, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ld_bu(DisasContext *ctx, arg_ld_bu *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_BU, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ld_hu(DisasContext *ctx, arg_ld_hu *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_HU, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ld_wu(DisasContext *ctx, arg_ld_wu *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LD_WU, a->rd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_preld(DisasContext *ctx, arg_preld *a) ++{ ++ /* Treat as NOP. */ ++ return true; ++} ++ ++static bool trans_ll_w(DisasContext *ctx, arg_ll_w *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LL_W, a->rd, a->rj, a->si14 << 2); ++ return true; ++} ++ ++static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a) ++{ ++ gen_st_cond(ctx, a->rd, a->rj, a->si14 << 2, MO_TESL, false); ++ return true; ++} ++ ++static bool trans_ll_d(DisasContext *ctx, arg_ll_d *a) ++{ ++ gen_ld(ctx, OPC_LARCH_LL_D, a->rd, a->rj, a->si14 << 2); ++ return true; ++} ++ ++static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a) ++{ ++ gen_st_cond(ctx, a->rd, a->rj, a->si14 << 2, MO_TEQ, false); ++ return true; ++} ++ ++static bool trans_fld_s(DisasContext *ctx, arg_fld_s *a) ++{ ++ gen_fp_ldst(ctx, OPC_LARCH_FLD_S, a->fd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_fst_s(DisasContext *ctx, arg_fst_s *a) ++{ ++ gen_fp_ldst(ctx, OPC_LARCH_FST_S, a->fd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_fld_d(DisasContext *ctx, arg_fld_d *a) ++{ ++ gen_fp_ldst(ctx, OPC_LARCH_FLD_D, a->fd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_fst_d(DisasContext *ctx, arg_fst_d *a) ++{ ++ gen_fp_ldst(ctx, OPC_LARCH_FST_D, a->fd, a->rj, a->si12); ++ return true; ++} ++ ++static bool trans_ldx_b(DisasContext *ctx, arg_ldx_b *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_SB); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_ldx_h(DisasContext *ctx, arg_ldx_h *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TESW | ctx->default_tcg_memop_mask); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_ldx_w(DisasContext *ctx, arg_ldx_w *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TESL | ctx->default_tcg_memop_mask); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_ldx_d(DisasContext *ctx, arg_ldx_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TEQ | ctx->default_tcg_memop_mask); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_stx_b(DisasContext *ctx, arg_stx_b *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ gen_load_gpr(t1, a->rd); ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_stx_h(DisasContext *ctx, arg_stx_h *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ gen_load_gpr(t1, a->rd); ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | ++ ctx->default_tcg_memop_mask); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_stx_w(DisasContext *ctx, arg_stx_w *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ gen_load_gpr(t1, a->rd); ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | ++ ctx->default_tcg_memop_mask); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_stx_d(DisasContext *ctx, arg_stx_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ gen_load_gpr(t1, a->rd); ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ | ++ ctx->default_tcg_memop_mask); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_ldx_bu(DisasContext *ctx, arg_ldx_bu *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_ldx_hu(DisasContext *ctx, arg_ldx_hu *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TEUW | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_ldx_wu(DisasContext *ctx, arg_ldx_wu *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); ++ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TEUL | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t1, a->rd); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_fldx_s(DisasContext *ctx, arg_fldx_s *a) ++{ ++ gen_flt3_ldst(ctx, OPC_LARCH_FLDX_S, a->fd, 0, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fldx_d(DisasContext *ctx, arg_fldx_d *a) ++{ ++ gen_flt3_ldst(ctx, OPC_LARCH_FLDX_D, a->fd, 0, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fstx_s(DisasContext *ctx, arg_fstx_s *a) ++{ ++ gen_flt3_ldst(ctx, OPC_LARCH_FSTX_S, 0, a->fd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fstx_d(DisasContext *ctx, arg_fstx_d *a) ++{ ++ gen_flt3_ldst(ctx, OPC_LARCH_FSTX_D, 0, a->fd, a->rj, a->rk); ++ return true; ++} ++ ++#define TRANS_AM_W(name, op) \ ++static bool trans_ ## name(DisasContext *ctx, arg_ ## name * a) \ ++{ \ ++ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ ++ printf("%s: warning, register equal\n", __func__); \ ++ return false; \ ++ } \ ++ int mem_idx = ctx->mem_idx; \ ++ TCGv addr = tcg_temp_new(); \ ++ TCGv val = tcg_temp_new(); \ ++ TCGv ret = tcg_temp_new(); \ ++\ ++ gen_load_gpr(addr, a->rj); \ ++ gen_load_gpr(val, a->rk); \ ++ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, MO_TESL | \ ++ ctx->default_tcg_memop_mask); \ ++ gen_store_gpr(ret, a->rd); \ ++\ ++ tcg_temp_free(addr); \ ++ tcg_temp_free(val); \ ++ tcg_temp_free(ret); \ ++ return true; \ ++} ++#define TRANS_AM_D(name, op) \ ++static bool trans_ ## name(DisasContext *ctx, arg_ ## name * a) \ ++{ \ ++ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ ++ printf("%s: warning, register equal\n", __func__); \ ++ return false; \ ++ } \ ++ int mem_idx = ctx->mem_idx; \ ++ TCGv addr = tcg_temp_new(); \ ++ TCGv val = tcg_temp_new(); \ ++ TCGv ret = tcg_temp_new(); \ ++\ ++ gen_load_gpr(addr, a->rj); \ ++ gen_load_gpr(val, a->rk); \ ++ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, MO_TEQ | \ ++ ctx->default_tcg_memop_mask); \ ++ gen_store_gpr(ret, a->rd); \ ++\ ++ tcg_temp_free(addr); \ ++ tcg_temp_free(val); \ ++ tcg_temp_free(ret); \ ++ return true; \ ++} ++#define TRANS_AM(name, op) \ ++ TRANS_AM_W(name##_w, op) \ ++ TRANS_AM_D(name##_d, op) ++TRANS_AM(amswap, xchg) /* trans_amswap_w, trans_amswap_d */ ++TRANS_AM(amadd, fetch_add) /* trans_amadd_w, trans_amadd_d */ ++TRANS_AM(amand, fetch_and) /* trans_amand_w, trans_amand_d */ ++TRANS_AM(amor, fetch_or) /* trans_amor_w, trans_amor_d */ ++TRANS_AM(amxor, fetch_xor) /* trans_amxor_w, trans_amxor_d */ ++TRANS_AM(ammax, fetch_smax) /* trans_ammax_w, trans_ammax_d */ ++TRANS_AM(ammin, fetch_smin) /* trans_ammin_w, trans_ammin_d */ ++TRANS_AM_W(ammax_wu, fetch_umax) /* trans_ammax_wu */ ++TRANS_AM_D(ammax_du, fetch_umax) /* trans_ammax_du */ ++TRANS_AM_W(ammin_wu, fetch_umin) /* trans_ammin_wu */ ++TRANS_AM_D(ammin_du, fetch_umin) /* trans_ammin_du */ ++#undef TRANS_AM ++#undef TRANS_AM_W ++#undef TRANS_AM_D ++ ++#define TRANS_AM_DB_W(name, op) \ ++static bool trans_ ## name(DisasContext *ctx, arg_ ## name * a) \ ++{ \ ++ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ ++ printf("%s: warning, register equal\n", __func__); \ ++ return false; \ ++ } \ ++ int mem_idx = ctx->mem_idx; \ ++ TCGv addr = tcg_temp_new(); \ ++ TCGv val = tcg_temp_new(); \ ++ TCGv ret = tcg_temp_new(); \ ++\ ++ gen_sync(0x10); /* TCG_MO_ALL */ \ ++ gen_load_gpr(addr, a->rj); \ ++ gen_load_gpr(val, a->rk); \ ++ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, MO_TESL | \ ++ ctx->default_tcg_memop_mask); \ ++ gen_store_gpr(ret, a->rd); \ ++\ ++ tcg_temp_free(addr); \ ++ tcg_temp_free(val); \ ++ tcg_temp_free(ret); \ ++ return true; \ ++} ++#define TRANS_AM_DB_D(name, op) \ ++static bool trans_ ## name(DisasContext *ctx, arg_ ## name * a) \ ++{ \ ++ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ ++ printf("%s: warning, register equal\n", __func__); \ ++ return false; \ ++ } \ ++ int mem_idx = ctx->mem_idx; \ ++ TCGv addr = tcg_temp_new(); \ ++ TCGv val = tcg_temp_new(); \ ++ TCGv ret = tcg_temp_new(); \ ++\ ++ gen_sync(0x10); /* TCG_MO_ALL */ \ ++ gen_load_gpr(addr, a->rj); \ ++ gen_load_gpr(val, a->rk); \ ++ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, MO_TEQ | \ ++ ctx->default_tcg_memop_mask); \ ++ gen_store_gpr(ret, a->rd); \ ++\ ++ tcg_temp_free(addr); \ ++ tcg_temp_free(val); \ ++ tcg_temp_free(ret); \ ++ return true; \ ++} ++#define TRANS_AM_DB(name, op) \ ++ TRANS_AM_DB_W(name##_db_w, op) \ ++ TRANS_AM_DB_D(name##_db_d, op) ++TRANS_AM_DB(amswap, xchg) /* trans_amswap_db_w, trans_amswap_db_d */ ++TRANS_AM_DB(amadd, fetch_add) /* trans_amadd_db_w, trans_amadd_db_d */ ++TRANS_AM_DB(amand, fetch_and) /* trans_amand_db_w, trans_amand_db_d */ ++TRANS_AM_DB(amor, fetch_or) /* trans_amor_db_w, trans_amor_db_d */ ++TRANS_AM_DB(amxor, fetch_xor) /* trans_amxor_db_w, trans_amxor_db_d */ ++TRANS_AM_DB(ammax, fetch_smax) /* trans_ammax_db_w, trans_ammax_db_d */ ++TRANS_AM_DB(ammin, fetch_smin) /* trans_ammin_db_w, trans_ammin_db_d */ ++TRANS_AM_DB_W(ammax_db_wu, fetch_umax) /* trans_ammax_db_wu */ ++TRANS_AM_DB_D(ammax_db_du, fetch_umax) /* trans_ammax_db_du */ ++TRANS_AM_DB_W(ammin_db_wu, fetch_umin) /* trans_ammin_db_wu */ ++TRANS_AM_DB_D(ammin_db_du, fetch_umin) /* trans_ammin_db_du */ ++#undef TRANS_AM_DB ++#undef TRANS_AM_DB_W ++#undef TRANS_AM_DB_D ++ ++static bool trans_dbar(DisasContext *ctx, arg_dbar * a) ++{ ++ gen_sync(a->whint); ++ return true; ++} ++ ++static bool trans_ibar(DisasContext *ctx, arg_ibar *a) ++{ ++ /* ++ * FENCE_I is a no-op in QEMU, ++ * however we need to end the translation block ++ */ ++ ctx->base.is_jmp = DISAS_STOP; ++ return true; ++} ++ ++#define ASRTGT \ ++do { \ ++ TCGv t1 = tcg_temp_new(); \ ++ TCGv t2 = tcg_temp_new(); \ ++ gen_load_gpr(t1, a->rj); \ ++ gen_load_gpr(t2, a->rk); \ ++ gen_helper_asrtgt_d(cpu_env, t1, t2); \ ++ tcg_temp_free(t1); \ ++ tcg_temp_free(t2); \ ++} while (0) ++ ++#define ASRTLE \ ++do {\ ++ TCGv t1 = tcg_temp_new(); \ ++ TCGv t2 = tcg_temp_new(); \ ++ gen_load_gpr(t1, a->rj); \ ++ gen_load_gpr(t2, a->rk); \ ++ gen_helper_asrtle_d(cpu_env, t1, t2); \ ++ tcg_temp_free(t1); \ ++ tcg_temp_free(t2); \ ++} while (0) ++ ++static bool trans_fldgt_s(DisasContext *ctx, arg_fldgt_s *a) ++{ ++ ASRTGT; ++ gen_flt3_ldst(ctx, OPC_LARCH_FLDGT_S, a->fd, 0, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fldgt_d(DisasContext *ctx, arg_fldgt_d *a) ++{ ++ ASRTGT; ++ gen_flt3_ldst(ctx, OPC_LARCH_FLDGT_D, a->fd, 0, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fldle_s(DisasContext *ctx, arg_fldle_s *a) ++{ ++ ASRTLE; ++ gen_flt3_ldst(ctx, OPC_LARCH_FLDLE_S, a->fd, 0, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fldle_d(DisasContext *ctx, arg_fldle_d *a) ++{ ++ ASRTLE; ++ gen_flt3_ldst(ctx, OPC_LARCH_FLDLE_D, a->fd, 0, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fstgt_s(DisasContext *ctx, arg_fstgt_s *a) ++{ ++ ASRTGT; ++ gen_flt3_ldst(ctx, OPC_LARCH_FSTGT_S, 0, a->fd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fstgt_d(DisasContext *ctx, arg_fstgt_d *a) ++{ ++ ASRTGT; ++ gen_flt3_ldst(ctx, OPC_LARCH_FSTGT_D, 0, a->fd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fstle_s(DisasContext *ctx, arg_fstle_s *a) ++{ ++ ASRTLE; ++ gen_flt3_ldst(ctx, OPC_LARCH_FSTLE_S, 0, a->fd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_fstle_d(DisasContext *ctx, arg_fstle_d *a) ++{ ++ ASRTLE; ++ gen_flt3_ldst(ctx, OPC_LARCH_FSTLE_D, 0, a->fd, a->rj, a->rk); ++ return true; ++} ++ ++#define DECL_ARG(name) \ ++ arg_ ## name arg = { \ ++ .rd = a->rd, \ ++ .rj = a->rj, \ ++ .rk = a->rk, \ ++ }; ++ ++static bool trans_ldgt_b(DisasContext *ctx, arg_ldgt_b *a) ++{ ++ ASRTGT; ++ DECL_ARG(ldx_b) ++ trans_ldx_b(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldgt_h(DisasContext *ctx, arg_ldgt_h *a) ++{ ++ ASRTGT; ++ DECL_ARG(ldx_h) ++ trans_ldx_h(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldgt_w(DisasContext *ctx, arg_ldgt_w *a) ++{ ++ ASRTGT; ++ DECL_ARG(ldx_w) ++ trans_ldx_w(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldgt_d(DisasContext *ctx, arg_ldgt_d *a) ++{ ++ ASRTGT; ++ DECL_ARG(ldx_d) ++ trans_ldx_d(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldle_b(DisasContext *ctx, arg_ldle_b *a) ++{ ++ ASRTLE; ++ DECL_ARG(ldx_b) ++ trans_ldx_b(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldle_h(DisasContext *ctx, arg_ldle_h *a) ++{ ++ ASRTLE; ++ DECL_ARG(ldx_h) ++ trans_ldx_h(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldle_w(DisasContext *ctx, arg_ldle_w *a) ++{ ++ ASRTLE; ++ DECL_ARG(ldx_w) ++ trans_ldx_w(ctx, &arg); ++ return true; ++} ++ ++static bool trans_ldle_d(DisasContext *ctx, arg_ldle_d *a) ++{ ++ ASRTLE; ++ DECL_ARG(ldx_d) ++ trans_ldx_d(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stgt_b(DisasContext *ctx, arg_stgt_b *a) ++{ ++ ASRTGT; ++ DECL_ARG(stx_b) ++ trans_stx_b(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stgt_h(DisasContext *ctx, arg_stgt_h *a) ++{ ++ ASRTGT; ++ DECL_ARG(stx_h) ++ trans_stx_h(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stgt_w(DisasContext *ctx, arg_stgt_w *a) ++{ ++ ASRTGT; ++ DECL_ARG(stx_w) ++ trans_stx_w(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stgt_d(DisasContext *ctx, arg_stgt_d *a) ++{ ++ ASRTGT; ++ DECL_ARG(stx_d) ++ trans_stx_d(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stle_b(DisasContext *ctx, arg_stle_b *a) ++{ ++ ASRTLE; ++ DECL_ARG(stx_b) ++ trans_stx_b(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stle_h(DisasContext *ctx, arg_stle_h *a) ++{ ++ ASRTLE; ++ DECL_ARG(stx_h) ++ trans_stx_h(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stle_w(DisasContext *ctx, arg_stle_w *a) ++{ ++ ASRTLE; ++ DECL_ARG(stx_w) ++ trans_stx_w(ctx, &arg); ++ return true; ++} ++ ++static bool trans_stle_d(DisasContext *ctx, arg_stle_d *a) ++{ ++ ASRTLE; ++ DECL_ARG(stx_d) ++ trans_stx_d(ctx, &arg); ++ return true; ++} ++ ++#undef ASRTGT ++#undef ASRTLE ++#undef DECL_ARG ++ ++static bool trans_beqz(DisasContext *ctx, arg_beqz *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BEQZ, 4, a->rj, 0, a->offs21 << 2); ++ return true; ++} ++ ++static bool trans_bnez(DisasContext *ctx, arg_bnez *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BNEZ, 4, a->rj, 0, a->offs21 << 2); ++ return true; ++} ++ ++static bool trans_bceqz(DisasContext *ctx, arg_bceqz *a) ++{ ++ TCGv_i32 cj = tcg_const_i32(a->cj); ++ TCGv v0 = tcg_temp_new(); ++ TCGv v1 = tcg_const_i64(0); ++ ++ gen_helper_movcf2reg(v0, cpu_env, cj); ++ tcg_gen_setcond_tl(TCG_COND_EQ, bcond, v0, v1); ++ ctx->hflags |= LARCH_HFLAG_BC; ++ ctx->btarget = ctx->base.pc_next + (a->offs21 << 2); ++ ++ tcg_temp_free_i32(cj); ++ tcg_temp_free(v0); ++ tcg_temp_free(v1); ++ return true; ++} ++ ++static bool trans_bcnez(DisasContext *ctx, arg_bcnez *a) ++{ ++ TCGv_i32 cj = tcg_const_i32(a->cj); ++ TCGv v0 = tcg_temp_new(); ++ TCGv v1 = tcg_const_i64(0); ++ ++ gen_helper_movcf2reg(v0, cpu_env, cj); ++ tcg_gen_setcond_tl(TCG_COND_NE, bcond, v0, v1); ++ ctx->hflags |= LARCH_HFLAG_BC; ++ ctx->btarget = ctx->base.pc_next + (a->offs21 << 2); ++ ++ tcg_temp_free_i32(cj); ++ tcg_temp_free(v0); ++ tcg_temp_free(v1); ++ return true; ++} ++ ++static bool trans_b(DisasContext *ctx, arg_b *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_B, 4, 0, 0, a->offs << 2); ++ return true; ++} ++ ++static bool trans_bl(DisasContext *ctx, arg_bl *a) ++{ ++ ctx->btarget = ctx->base.pc_next + (a->offs << 2); ++ tcg_gen_movi_tl(cpu_gpr[1], ctx->base.pc_next + 4); ++ ctx->hflags |= LARCH_HFLAG_B; ++ gen_branch(ctx, 4); ++ return true; ++} ++ ++static bool trans_blt(DisasContext *ctx, arg_blt *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BLT, 4, a->rj, a->rd, a->offs16 << 2); ++ return true; ++} ++ ++static bool trans_bge(DisasContext *ctx, arg_bge *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BGE, 4, a->rj, a->rd, a->offs16 << 2); ++ return true; ++} ++ ++static bool trans_bltu(DisasContext *ctx, arg_bltu *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BLTU, 4, a->rj, a->rd, a->offs16 << 2); ++ return true; ++} ++ ++static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BGEU, 4, a->rj, a->rd, a->offs16 << 2); ++ return true; ++} ++ ++static bool trans_beq(DisasContext *ctx, arg_beq *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BEQ, 4, a->rj, a->rd, a->offs16 << 2); ++ return true; ++} ++ ++static bool trans_bne(DisasContext *ctx, arg_bne *a) ++{ ++ gen_compute_branch(ctx, OPC_LARCH_BNE, 4, a->rj, a->rd, a->offs16 << 2); ++ return true; ++} ++ ++static bool trans_jirl(DisasContext *ctx, arg_jirl *a) ++{ ++ gen_base_offset_addr(ctx, btarget, a->rj, a->offs16 << 2); ++ if (a->rd != 0) { ++ tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->base.pc_next + 4); ++ } ++ ctx->hflags |= LARCH_HFLAG_BR; ++ gen_branch(ctx, 4); ++ ++ return true; ++} ++ ++#define TRANS_F4FR(name, fmt, op, bits) \ ++static bool trans_ ## name ## _ ## fmt(DisasContext *ctx, \ ++ arg_##name##_##fmt * a) \ ++{ \ ++ check_cp1_enabled(ctx); \ ++ TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ ++ TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ ++ TCGv_i ## bits fp2 = tcg_temp_new_i ## bits(); \ ++ TCGv_i ## bits fp3 = tcg_temp_new_i ## bits(); \ ++ check_cp1_enabled(ctx); \ ++ gen_load_fpr ## bits(ctx, fp0, a->fj); \ ++ gen_load_fpr ## bits(ctx, fp1, a->fk); \ ++ gen_load_fpr ## bits(ctx, fp2, a->fa); \ ++ gen_helper_float_ ## op ## _ ## fmt(fp3, \ ++ cpu_env, fp0, fp1, fp2); \ ++ gen_store_fpr ## bits(ctx, fp3, a->fd); \ ++ tcg_temp_free_i ## bits(fp3); \ ++ tcg_temp_free_i ## bits(fp2); \ ++ tcg_temp_free_i ## bits(fp1); \ ++ tcg_temp_free_i ## bits(fp0); \ ++ return true; \ ++} ++ ++TRANS_F4FR(fmadd , s, maddf , 32) /* trans_fmadd_s */ ++TRANS_F4FR(fmadd , d, maddf , 64) /* trans_fmadd_d */ ++TRANS_F4FR(fmsub , s, msubf , 32) /* trans_fmsub_s */ ++TRANS_F4FR(fmsub , d, msubf , 64) /* trans_fmsub_d */ ++TRANS_F4FR(fnmadd, s, nmaddf, 32) /* trans_fnmadd_s */ ++TRANS_F4FR(fnmadd, d, nmaddf, 64) /* trans_fnmadd_d */ ++TRANS_F4FR(fnmsub, s, nmsubf, 32) /* trans_fnmsub_s */ ++TRANS_F4FR(fnmsub, d, nmsubf, 64) /* trans_fnmsub_d */ ++#undef TRANS_F4FR ++ ++static bool trans_fadd_s(DisasContext *ctx, arg_fadd_s * a) ++{ ++ gen_farith(ctx, OPC_LARCH_FADD_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fadd_d(DisasContext *ctx, arg_fadd_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FADD_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fsub_s(DisasContext *ctx, arg_fsub_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FSUB_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fsub_d(DisasContext *ctx, arg_fsub_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FSUB_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmul_s(DisasContext *ctx, arg_fmul_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMUL_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmul_d(DisasContext *ctx, arg_fmul_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMUL_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fdiv_s(DisasContext *ctx, arg_fdiv_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FDIV_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fdiv_d(DisasContext *ctx, arg_fdiv_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FDIV_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmax_s(DisasContext *ctx, arg_fmax_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMAX_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmax_d(DisasContext *ctx, arg_fmax_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMAX_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmin_s(DisasContext *ctx, arg_fmin_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMIN_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmin_d(DisasContext *ctx, arg_fmin_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMIN_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmaxa_s(DisasContext *ctx, arg_fmaxa_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMAXA_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmaxa_d(DisasContext *ctx, arg_fmaxa_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMAXA_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmina_s(DisasContext *ctx, arg_fmina_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMINA_S, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmina_d(DisasContext *ctx, arg_fmina_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMINA_D, a->fk, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fscaleb_s(DisasContext *ctx, arg_fscaleb_s *a) ++{ ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr32(ctx, fp0, a->fj); ++ gen_load_fpr32(ctx, fp1, a->fk); ++ gen_helper_float_exp2_s(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i32(fp1); ++ gen_store_fpr32(ctx, fp0, a->fd); ++ tcg_temp_free_i32(fp0); ++ return true; ++} ++ ++static bool trans_fscaleb_d(DisasContext *ctx, arg_fscaleb_d *a) ++{ ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr64(ctx, fp0, a->fj); ++ gen_load_fpr64(ctx, fp1, a->fk); ++ gen_helper_float_exp2_d(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i64(fp1); ++ gen_store_fpr64(ctx, fp0, a->fd); ++ tcg_temp_free_i64(fp0); ++ return true; ++} ++ ++static bool trans_fcopysign_s(DisasContext *ctx, arg_fcopysign_s *a) ++{ ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ TCGv_i32 fp2 = tcg_temp_new_i32(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr32(ctx, fp0, a->fj); ++ gen_load_fpr32(ctx, fp1, a->fk); ++ tcg_gen_deposit_i32(fp2, fp1, fp0, 0, 31); ++ gen_store_fpr32(ctx, fp2, a->fd); ++ ++ tcg_temp_free_i32(fp2); ++ tcg_temp_free_i32(fp1); ++ tcg_temp_free_i32(fp0); ++ return true; ++} ++ ++static bool trans_fcopysign_d(DisasContext *ctx, arg_fcopysign_d *a) ++{ ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ TCGv_i64 fp2 = tcg_temp_new_i64(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr64(ctx, fp0, a->fj); ++ gen_load_fpr64(ctx, fp1, a->fk); ++ tcg_gen_deposit_i64(fp2, fp1, fp0, 0, 63); ++ gen_store_fpr64(ctx, fp2, a->fd); ++ ++ tcg_temp_free_i64(fp2); ++ tcg_temp_free_i64(fp1); ++ tcg_temp_free_i64(fp0); ++ return true; ++} ++ ++static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FABS_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FABS_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FNEG_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FNEG_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_flogb_s(DisasContext *ctx, arg_flogb_s *a) ++{ ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr32(ctx, fp0, a->fj); ++ gen_helper_float_logb_s(fp1, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp1, a->fd); ++ ++ tcg_temp_free_i32(fp0); ++ tcg_temp_free_i32(fp1); ++ return true; ++} ++ ++static bool trans_flogb_d(DisasContext *ctx, arg_flogb_d *a) ++{ ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr64(ctx, fp0, a->fj); ++ gen_helper_float_logb_d(fp1, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp1, a->fd); ++ ++ tcg_temp_free_i64(fp0); ++ tcg_temp_free_i64(fp1); ++ return true; ++} ++ ++static bool trans_fclass_s(DisasContext *ctx, arg_fclass_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FCLASS_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FCLASS_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fsqrt_s(DisasContext *ctx, arg_fsqrt_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FSQRT_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fsqrt_d(DisasContext *ctx, arg_fsqrt_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FSQRT_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_frecip_s(DisasContext *ctx, arg_frecip_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FRECIP_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_frecip_d(DisasContext *ctx, arg_frecip_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FRECIP_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_frsqrt_s(DisasContext *ctx, arg_frsqrt_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FRSQRT_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_frsqrt_d(DisasContext *ctx, arg_frsqrt_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FRSQRT_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmov_s(DisasContext *ctx, arg_fmov_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMOV_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fmov_d(DisasContext *ctx, arg_fmov_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FMOV_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_movgr2fr_w(DisasContext *ctx, arg_movgr2fr_w *a) ++{ ++ gen_cp1(ctx, OPC_LARCH_GR2FR_W, a->rj, a->fd); ++ return true; ++} ++ ++static bool trans_movgr2fr_d(DisasContext *ctx, arg_movgr2fr_d *a) ++{ ++ gen_cp1(ctx, OPC_LARCH_GR2FR_D, a->rj, a->fd); ++ return true; ++} ++ ++static bool trans_movgr2frh_w(DisasContext *ctx, arg_movgr2frh_w *a) ++{ ++ gen_cp1(ctx, OPC_LARCH_GR2FRH_W, a->rj, a->fd); ++ return true; ++} ++ ++static bool trans_movfr2gr_s(DisasContext *ctx, arg_movfr2gr_s *a) ++{ ++ gen_cp1(ctx, OPC_LARCH_FR2GR_S, a->rd, a->fj); ++ return true; ++} ++ ++static bool trans_movfr2gr_d(DisasContext *ctx, arg_movfr2gr_d *a) ++{ ++ gen_cp1(ctx, OPC_LARCH_FR2GR_D, a->rd, a->fj); ++ return true; ++} ++ ++static bool trans_movfrh2gr_s(DisasContext *ctx, arg_movfrh2gr_s *a) ++{ ++ gen_cp1(ctx, OPC_LARCH_FRH2GR_S, a->rd, a->fj); ++ return true; ++} ++ ++static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ check_cp1_enabled(ctx); ++ gen_load_gpr(t0, a->rj); ++ save_cpu_state(ctx, 0); ++ { ++ TCGv_i32 fs_tmp = tcg_const_i32(a->fcsrd); ++ gen_helper_0e2i(movgr2fcsr, t0, fs_tmp, a->rj); ++ tcg_temp_free_i32(fs_tmp); ++ } ++ /* Stop translation as we may have changed hflags */ ++ ctx->base.is_jmp = DISAS_STOP; ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ gen_helper_1e0i(movfcsr2gr, t0, a->fcsrs); ++ gen_store_gpr(t0, a->rd); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a) ++{ ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i32 cd = tcg_const_i32(a->cd); ++ ++ check_cp1_enabled(ctx); ++ gen_load_fpr64(ctx, fp0, a->fj); ++ gen_helper_movreg2cf(cpu_env, cd, fp0); ++ ++ tcg_temp_free_i64(fp0); ++ tcg_temp_free_i32(cd); ++ return true; ++} ++ ++static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv_i32 cj = tcg_const_i32(a->cj); ++ ++ check_cp1_enabled(ctx); ++ gen_helper_movcf2reg(t0, cpu_env, cj); ++ gen_store_fpr64(ctx, t0, a->fd); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv_i32 cd = tcg_const_i32(a->cd); ++ ++ check_cp1_enabled(ctx); ++ gen_load_gpr(t0, a->rj); ++ gen_helper_movreg2cf(cpu_env, cd, t0); ++ ++ tcg_temp_free(t0); ++ tcg_temp_free_i32(cd); ++ return true; ++} ++ ++static bool trans_movcf2gr(DisasContext *ctx, arg_movcf2gr *a) ++{ ++ TCGv_i32 cj = tcg_const_i32(a->cj); ++ ++ check_cp1_enabled(ctx); ++ gen_helper_movcf2reg(cpu_gpr[a->rd], cpu_env, cj); ++ ++ tcg_temp_free_i32(cj); ++ return true; ++} ++ ++static bool trans_fcvt_s_d(DisasContext *ctx, arg_fcvt_s_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FCVT_S_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_fcvt_d_s(DisasContext *ctx, arg_fcvt_d_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FCVT_D_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrm_w_s(DisasContext *ctx, arg_ftintrm_l_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRM_W_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrm_w_d(DisasContext *ctx, arg_ftintrm_l_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRM_W_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrm_l_s(DisasContext *ctx, arg_ftintrm_l_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRM_L_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrm_l_d(DisasContext *ctx, arg_ftintrm_l_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRM_L_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrp_w_s(DisasContext *ctx, arg_ftintrp_w_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRP_W_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrp_w_d(DisasContext *ctx, arg_ftintrp_w_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRP_W_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrp_l_s(DisasContext *ctx, arg_ftintrp_l_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRP_L_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrp_l_d(DisasContext *ctx, arg_ftintrp_l_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRP_L_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrz_w_s(DisasContext *ctx, arg_ftintrz_w_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRZ_W_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrz_w_d(DisasContext *ctx, arg_ftintrz_w_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRZ_W_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrz_l_s(DisasContext *ctx, arg_ftintrz_l_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRZ_L_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrz_l_d(DisasContext *ctx, arg_ftintrz_l_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRZ_L_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrne_w_s(DisasContext *ctx, arg_ftintrne_w_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRNE_W_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrne_w_d(DisasContext *ctx, arg_ftintrne_w_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRNE_W_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrne_l_s(DisasContext *ctx, arg_ftintrne_l_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRNE_L_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftintrne_l_d(DisasContext *ctx, arg_ftintrne_l_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINTRNE_L_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftint_w_s(DisasContext *ctx, arg_ftint_w_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINT_W_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftint_w_d(DisasContext *ctx, arg_ftint_w_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINT_W_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftint_l_s(DisasContext *ctx, arg_ftint_l_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINT_L_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ftint_l_d(DisasContext *ctx, arg_ftint_l_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FTINT_L_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ffint_s_w(DisasContext *ctx, arg_ffint_s_w *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FFINT_S_W, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ffint_s_l(DisasContext *ctx, arg_ffint_s_l *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FFINT_S_L, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ffint_d_w(DisasContext *ctx, arg_ffint_d_w *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FFINT_D_W, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_ffint_d_l(DisasContext *ctx, arg_ffint_d_l *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FFINT_D_L, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_frint_s(DisasContext *ctx, arg_frint_s *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FRINT_S, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_frint_d(DisasContext *ctx, arg_frint_d *a) ++{ ++ gen_farith(ctx, OPC_LARCH_FRINT_D, 0, a->fj, a->fd, 0); ++ return true; ++} ++ ++static bool trans_alsl_w(DisasContext *ctx, arg_alsl_w *a) ++{ ++ gen_lsa(ctx, OPC_LARCH_ALSL_W, a->rd, a->rj, a->rk, a->sa2); ++ return true; ++} ++ ++static bool trans_alsl_wu(DisasContext *ctx, arg_alsl_wu *a) ++{ ++ TCGv t0, t1; ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rj); ++ gen_load_gpr(t1, a->rk); ++ tcg_gen_shli_tl(t0, t0, a->sa2 + 1); ++ tcg_gen_add_tl(t0, t0, t1); ++ tcg_gen_ext32u_tl(cpu_gpr[a->rd], t0); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ ++ return true; ++} ++ ++static bool trans_alsl_d(DisasContext *ctx, arg_alsl_d *a) ++{ ++ check_larch_64(ctx); ++ gen_lsa(ctx, OPC_LARCH_ALSL_D, a->rd, a->rj, a->rk, a->sa2); ++ return true; ++} ++ ++static bool trans_bytepick_w(DisasContext *ctx, arg_bytepick_w *a) ++{ ++ gen_align(ctx, 32, a->rd, a->rj, a->rk, a->sa2); ++ return true; ++} ++ ++static bool trans_bytepick_d(DisasContext *ctx, arg_bytepick_d *a) ++{ ++ check_larch_64(ctx); ++ gen_align(ctx, 64, a->rd, a->rj, a->rk, a->sa3); ++ return true; ++} ++ ++static bool trans_add_w(DisasContext *ctx, arg_add_w *a) ++{ ++ gen_arith(ctx, OPC_LARCH_ADD_W, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_sub_w(DisasContext *ctx, arg_sub_w *a) ++{ ++ gen_arith(ctx, OPC_LARCH_SUB_W, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_add_d(DisasContext *ctx, arg_add_d *a) ++{ ++ gen_arith(ctx, OPC_LARCH_ADD_D, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_sub_d(DisasContext *ctx, arg_sub_d *a) ++{ ++ check_larch_64(ctx); ++ gen_arith(ctx, OPC_LARCH_SUB_D, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_slt(DisasContext *ctx, arg_slt *a) ++{ ++ gen_slt(ctx, OPC_LARCH_SLT, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_sltu(DisasContext *ctx, arg_sltu *a) ++{ ++ gen_slt(ctx, OPC_LARCH_SLTU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_maskeqz(DisasContext *ctx, arg_maskeqz *a) ++{ ++ gen_cond_move(ctx, OPC_LARCH_MASKEQZ, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_masknez(DisasContext *ctx, arg_masknez *a) ++{ ++ gen_cond_move(ctx, OPC_LARCH_MASKNEZ, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_nor(DisasContext *ctx, arg_nor *a) ++{ ++ gen_logic(ctx, OPC_LARCH_NOR, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_and(DisasContext *ctx, arg_and *a) ++{ ++ gen_logic(ctx, OPC_LARCH_AND, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_or(DisasContext *ctx, arg_or *a) ++{ ++ gen_logic(ctx, OPC_LARCH_OR, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_xor(DisasContext *ctx, arg_xor *a) ++{ ++ gen_logic(ctx, OPC_LARCH_XOR, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_orn(DisasContext *ctx, arg_orn *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rk); ++ tcg_gen_not_tl(t0, t0); ++ tcg_gen_or_tl(cpu_gpr[a->rd], cpu_gpr[a->rj], t0); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_andn(DisasContext *ctx, arg_andn *a) ++{ ++ TCGv t0, t1; ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rk); ++ gen_load_gpr(t1, a->rj); ++ tcg_gen_not_tl(t0, t0); ++ tcg_gen_and_tl(cpu_gpr[a->rd], t1, t0); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++static bool trans_sll_w(DisasContext *ctx, arg_sll_w *a) ++{ ++ gen_shift(ctx, OPC_LARCH_SLL_W, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_srl_w(DisasContext *ctx, arg_srl_w *a) ++{ ++ gen_shift(ctx, OPC_LARCH_SRL_W, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_sra_w(DisasContext *ctx, arg_sra_w *a) ++{ ++ gen_shift(ctx, OPC_LARCH_SRA_W, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_sll_d(DisasContext *ctx, arg_sll_d *a) ++{ ++ check_larch_64(ctx); ++ gen_shift(ctx, OPC_LARCH_SLL_D, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_srl_d(DisasContext *ctx, arg_srl_d *a) ++{ ++ check_larch_64(ctx); ++ gen_shift(ctx, OPC_LARCH_SRL_D, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_sra_d(DisasContext *ctx, arg_sra_d *a) ++{ ++ check_larch_64(ctx); ++ gen_shift(ctx, OPC_LARCH_SRA_D, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_rotr_w(DisasContext *ctx, arg_rotr_w *a) ++{ ++ gen_shift(ctx, OPC_LARCH_ROTR_W, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_rotr_d(DisasContext *ctx, arg_rotr_d *a) ++{ ++ check_larch_64(ctx); ++ gen_shift(ctx, OPC_LARCH_ROTR_D, a->rd, a->rk, a->rj); ++ return true; ++} ++ ++static bool trans_crc_w_b_w(DisasContext *ctx, arg_crc_w_b_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 1, 0); ++ return true; ++} ++ ++static bool trans_crc_w_h_w(DisasContext *ctx, arg_crc_w_h_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 2, 0); ++ return true; ++} ++ ++static bool trans_crc_w_w_w(DisasContext *ctx, arg_crc_w_w_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 4, 0); ++ return true; ++} ++ ++static bool trans_crc_w_d_w(DisasContext *ctx, arg_crc_w_d_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 8, 0); ++ return true; ++} ++ ++static bool trans_crcc_w_b_w(DisasContext *ctx, arg_crcc_w_b_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 1, 1); ++ return true; ++} ++ ++static bool trans_crcc_w_h_w(DisasContext *ctx, arg_crcc_w_h_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 2, 1); ++ return true; ++} ++ ++static bool trans_crcc_w_w_w(DisasContext *ctx, arg_crcc_w_w_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 4, 1); ++ return true; ++} ++ ++static bool trans_crcc_w_d_w(DisasContext *ctx, arg_crcc_w_d_w *a) ++{ ++ gen_crc32(ctx, a->rd, a->rj, a->rk, 8, 1); ++ return true; ++} ++ ++static bool trans_mul_w(DisasContext *ctx, arg_mul_w *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_MUL_W, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mulh_w(DisasContext *ctx, arg_mulh_w *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_MULH_W, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mulh_wu(DisasContext *ctx, arg_mulh_wu *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_MULH_WU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mul_d(DisasContext *ctx, arg_mul_d *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_MUL_D, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mulh_d(DisasContext *ctx, arg_mulh_d *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_MULH_D, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mulh_du(DisasContext *ctx, arg_mulh_du *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_MULH_DU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mulw_d_w(DisasContext *ctx, arg_mulw_d_w *a) ++{ ++ TCGv_i64 t0 = tcg_temp_new_i64(); ++ TCGv_i64 t1 = tcg_temp_new_i64(); ++ TCGv_i64 t2 = tcg_temp_new_i64(); ++ gen_load_gpr(t0, a->rj); ++ gen_load_gpr(t1, a->rk); ++ tcg_gen_ext32s_i64(t0, t0); ++ tcg_gen_ext32s_i64(t1, t1); ++ tcg_gen_mul_i64(t2, t0, t1); ++ gen_store_gpr(t2, a->rd); ++ tcg_temp_free_i64(t0); ++ tcg_temp_free_i64(t1); ++ tcg_temp_free_i64(t2); ++ return true; ++} ++ ++static bool trans_mulw_d_wu(DisasContext *ctx, arg_mulw_d_wu *a) ++{ ++ TCGv_i64 t0 = tcg_temp_new_i64(); ++ TCGv_i64 t1 = tcg_temp_new_i64(); ++ TCGv_i64 t2 = tcg_temp_new_i64(); ++ gen_load_gpr(t0, a->rj); ++ gen_load_gpr(t1, a->rk); ++ tcg_gen_ext32u_i64(t0, t0); ++ tcg_gen_ext32u_i64(t1, t1); ++ tcg_gen_mul_i64(t2, t0, t1); ++ gen_store_gpr(t2, a->rd); ++ tcg_temp_free_i64(t0); ++ tcg_temp_free_i64(t1); ++ tcg_temp_free_i64(t2); ++ return true; ++} ++ ++static bool trans_div_w(DisasContext *ctx, arg_div_w *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_DIV_W, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mod_w(DisasContext *ctx, arg_mod_w *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_MOD_W, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_div_wu(DisasContext *ctx, arg_div_wu *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_DIV_WU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mod_wu(DisasContext *ctx, arg_mod_wu *a) ++{ ++ gen_r6_muldiv(ctx, OPC_LARCH_MOD_WU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_div_d(DisasContext *ctx, arg_div_d *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_DIV_D, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mod_d(DisasContext *ctx, arg_mod_d *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_MOD_D, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_div_du(DisasContext *ctx, arg_div_du *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_DIV_DU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++static bool trans_mod_du(DisasContext *ctx, arg_mod_du *a) ++{ ++ check_larch_64(ctx); ++ gen_r6_muldiv(ctx, OPC_LARCH_MOD_DU, a->rd, a->rj, a->rk); ++ return true; ++} ++ ++/* do not update CP0.BadVaddr */ ++static bool trans_asrtle_d(DisasContext *ctx, arg_asrtle_d * a) ++{ ++ TCGv t1 = tcg_temp_new(); ++ TCGv t2 = tcg_temp_new(); ++ gen_load_gpr(t1, a->rj); ++ gen_load_gpr(t2, a->rk); ++ gen_helper_asrtle_d(cpu_env, t1, t2); ++ tcg_temp_free(t1); ++ tcg_temp_free(t2); ++ return true; ++} ++ ++/* do not update CP0.BadVaddr */ ++static bool trans_asrtgt_d(DisasContext *ctx, arg_asrtgt_d * a) ++{ ++ TCGv t1 = tcg_temp_new(); ++ TCGv t2 = tcg_temp_new(); ++ gen_load_gpr(t1, a->rj); ++ gen_load_gpr(t2, a->rk); ++ gen_helper_asrtgt_d(cpu_env, t1, t2); ++ tcg_temp_free(t1); ++ tcg_temp_free(t2); ++ return true; ++} ++ ++#ifdef CONFIG_USER_ONLY ++static bool trans_gr2scr(DisasContext *ctx, arg_gr2scr *a) ++{ ++ return false; ++} ++ ++static bool trans_scr2gr(DisasContext *ctx, arg_scr2gr *a) ++{ ++ return false; ++} ++#else ++static bool trans_gr2scr(DisasContext *ctx, arg_gr2scr *a) ++{ ++ TCGv_i32 sd = tcg_const_i32(a->sd); ++ TCGv val = tcg_temp_new(); ++ check_lbt_enabled(ctx); ++ gen_load_gpr(val, a->rj); ++ gen_helper_store_scr(cpu_env, sd, val); ++ tcg_temp_free_i32(sd); ++ tcg_temp_free(val); ++ return true; ++} ++ ++static bool trans_scr2gr(DisasContext *ctx, arg_scr2gr *a) ++{ ++ if (a->rd == 0) { ++ /* Nop */ ++ return true; ++ } ++ ++ TCGv_i32 tsj = tcg_const_i32(a->sj); ++ check_lbt_enabled(ctx); ++ gen_helper_load_scr(cpu_gpr[a->rd], cpu_env, tsj); ++ tcg_temp_free_i32(tsj); ++ return true; ++} ++#endif ++ ++static bool trans_clo_w(DisasContext *ctx, arg_clo_w *a) ++{ ++ gen_cl(ctx, OPC_LARCH_CLO_W, a->rd, a->rj); ++ return true; ++} ++ ++static bool trans_clz_w(DisasContext *ctx, arg_clz_w *a) ++{ ++ gen_cl(ctx, OPC_LARCH_CLZ_W, a->rd, a->rj); ++ return true; ++} ++ ++static bool trans_cto_w(DisasContext *ctx, arg_cto_w *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ gen_helper_cto_w(cpu_gpr[a->rd], cpu_env, t0); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_ctz_w(DisasContext *ctx, arg_ctz_w *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ gen_helper_ctz_w(cpu_gpr[a->rd], cpu_env, t0); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_clo_d(DisasContext *ctx, arg_clo_d *a) ++{ ++ check_larch_64(ctx); ++ gen_cl(ctx, OPC_LARCH_CLO_D, a->rd, a->rj); ++ return true; ++} ++ ++static bool trans_clz_d(DisasContext *ctx, arg_clz_d *a) ++{ ++ check_larch_64(ctx); ++ gen_cl(ctx, OPC_LARCH_CLZ_D, a->rd, a->rj); ++ return true; ++} ++ ++static bool trans_cto_d(DisasContext *ctx, arg_cto_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ gen_helper_cto_d(cpu_gpr[a->rd], cpu_env, t0); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_ctz_d(DisasContext *ctx, arg_ctz_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, a->rj); ++ gen_helper_ctz_d(cpu_gpr[a->rd], cpu_env, t0); ++ ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_revb_2h(DisasContext *ctx, arg_revb_2h *a) ++{ ++ gen_bshfl(ctx, OPC_LARCH_REVB_2H, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_revb_4h(DisasContext *ctx, arg_revb_4h *a) ++{ ++ check_larch_64(ctx); ++ gen_bshfl(ctx, OPC_LARCH_REVB_4H, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_revb_2w(DisasContext *ctx, arg_revb_2w *a) ++{ ++ handle_rev32(ctx, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_revb_d(DisasContext *ctx, arg_revb_d *a) ++{ ++ handle_rev64(ctx, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_revh_2w(DisasContext *ctx, arg_revh_2w *a) ++{ ++ handle_rev16(ctx, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_revh_d(DisasContext *ctx, arg_revh_d *a) ++{ ++ check_larch_64(ctx); ++ gen_bshfl(ctx, OPC_LARCH_REVH_D, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_bitrev_4b(DisasContext *ctx, arg_bitrev_4b *a) ++{ ++ gen_bitswap(ctx, OPC_LARCH_BREV_4B, a->rd, a->rj); ++ return true; ++} ++ ++static bool trans_bitrev_8b(DisasContext *ctx, arg_bitrev_8b *a) ++{ ++ check_larch_64(ctx); ++ gen_bitswap(ctx, OPC_LARCH_BREV_8B, a->rd, a->rj); ++ return true; ++} ++ ++static bool trans_bitrev_w(DisasContext *ctx, arg_bitrev_w *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rj); ++ gen_helper_bitrev_w(cpu_gpr[a->rd], cpu_env, t0); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_bitrev_d(DisasContext *ctx, arg_bitrev_d *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rj); ++ gen_helper_bitrev_d(cpu_gpr[a->rd], cpu_env, t0); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_ext_w_h(DisasContext *ctx, arg_ext_w_h *a) ++{ ++ gen_bshfl(ctx, OPC_LARCH_EXT_WH, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_ext_w_b(DisasContext *ctx, arg_ext_w_b *a) ++{ ++ gen_bshfl(ctx, OPC_LARCH_EXT_WB, a->rj, a->rd); ++ return true; ++} ++ ++static bool trans_srli_w(DisasContext *ctx, arg_srli_w *a) ++{ ++ gen_shift_imm(ctx, OPC_LARCH_SRLI_W, a->rd, a->rj, a->ui5); ++ return true; ++} ++ ++static bool trans_srai_w(DisasContext *ctx, arg_srai_w *a) ++{ ++ gen_shift_imm(ctx, OPC_LARCH_SRAI_W, a->rd, a->rj, a->ui5); ++ return true; ++} ++ ++static bool trans_srai_d(DisasContext *ctx, arg_srai_d *a) ++{ ++ TCGv t0; ++ check_larch_64(ctx); ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rj); ++ tcg_gen_sari_tl(cpu_gpr[a->rd], t0, a->ui6); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_rotri_w(DisasContext *ctx, arg_rotri_w *a) ++{ ++ gen_shift_imm(ctx, OPC_LARCH_ROTRI_W, a->rd, a->rj, a->ui5); ++ return true; ++} ++ ++static bool trans_rotri_d(DisasContext *ctx, arg_rotri_d *a) ++{ ++ TCGv t0; ++ check_larch_64(ctx); ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rj); ++ tcg_gen_rotri_tl(cpu_gpr[a->rd], t0, a->ui6); ++ tcg_temp_free(t0); ++ return true; ++} ++ ++static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a) ++{ ++ check_cp1_enabled(ctx); ++ gen_fcmp_s(ctx, a->fcond, a->fk, a->fj, a->cd); ++ return true; ++} ++ ++static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a) ++{ ++ check_cp1_enabled(ctx); ++ gen_fcmp_d(ctx, a->fcond, a->fk, a->fj, a->cd); ++ return true; ++} ++ ++static bool trans_fsel(DisasContext *ctx, arg_fsel *a) ++{ ++ TCGv_i64 fj = tcg_temp_new_i64(); ++ TCGv_i64 fk = tcg_temp_new_i64(); ++ TCGv_i64 fd = tcg_temp_new_i64(); ++ TCGv_i32 ca = tcg_const_i32(a->ca); ++ check_cp1_enabled(ctx); ++ gen_load_fpr64(ctx, fj, a->fj); ++ gen_load_fpr64(ctx, fk, a->fk); ++ gen_helper_fsel(fd, cpu_env, fj, fk, ca); ++ gen_store_fpr64(ctx, fd, a->fd); ++ tcg_temp_free_i64(fj); ++ tcg_temp_free_i64(fk); ++ tcg_temp_free_i64(fd); ++ tcg_temp_free_i32(ca); ++ return true; ++} ++ ++#include "cpu-csr.h" ++ ++#ifdef CONFIG_USER_ONLY ++ ++static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) ++{ ++ return false; ++} ++ ++#else ++ ++ ++#define GEN_CSRRQ_CASE(name) \ ++ do { \ ++ case LOONGARCH_CSR_ ## name: \ ++ gen_csr_rdq(ctx, cpu_gpr[rd], LOONGARCH_CSR_ ## name);\ ++ } while (0) ++ ++static bool trans_csrrd(DisasContext *ctx, unsigned rd, unsigned csr) ++{ ++ switch (csr) { ++ GEN_CSRRQ_CASE(CRMD); ++ break; ++ GEN_CSRRQ_CASE(PRMD); ++ break; ++ GEN_CSRRQ_CASE(EUEN); ++ break; ++ GEN_CSRRQ_CASE(MISC); ++ break; ++ GEN_CSRRQ_CASE(ECFG); ++ break; ++ GEN_CSRRQ_CASE(ESTAT); ++ break; ++ GEN_CSRRQ_CASE(ERA); ++ break; ++ GEN_CSRRQ_CASE(BADV); ++ break; ++ GEN_CSRRQ_CASE(BADI); ++ break; ++ GEN_CSRRQ_CASE(EEPN); ++ break; ++ GEN_CSRRQ_CASE(TLBIDX); ++ break; ++ GEN_CSRRQ_CASE(TLBEHI); ++ break; ++ GEN_CSRRQ_CASE(TLBELO0); ++ break; ++ GEN_CSRRQ_CASE(TLBELO1); ++ break; ++ GEN_CSRRQ_CASE(TLBWIRED); ++ break; ++ GEN_CSRRQ_CASE(GTLBC); ++ break; ++ GEN_CSRRQ_CASE(TRGP); ++ break; ++ GEN_CSRRQ_CASE(ASID); ++ break; ++ GEN_CSRRQ_CASE(PGDL); ++ break; ++ GEN_CSRRQ_CASE(PGDH); ++ break; ++ case LOONGARCH_CSR_PGD: ++ gen_helper_read_pgd(cpu_gpr[rd], cpu_env); ++ break; ++ GEN_CSRRQ_CASE(PWCTL0); ++ break; ++ GEN_CSRRQ_CASE(PWCTL1); ++ break; ++ GEN_CSRRQ_CASE(STLBPGSIZE); ++ break; ++ GEN_CSRRQ_CASE(RVACFG); ++ break; ++ GEN_CSRRQ_CASE(CPUID); ++ break; ++ GEN_CSRRQ_CASE(PRCFG1); ++ break; ++ GEN_CSRRQ_CASE(PRCFG2); ++ break; ++ GEN_CSRRQ_CASE(PRCFG3); ++ break; ++ GEN_CSRRQ_CASE(KS0); ++ break; ++ GEN_CSRRQ_CASE(KS1); ++ break; ++ GEN_CSRRQ_CASE(KS2); ++ break; ++ GEN_CSRRQ_CASE(KS3); ++ break; ++ GEN_CSRRQ_CASE(KS4); ++ break; ++ GEN_CSRRQ_CASE(KS5); ++ break; ++ GEN_CSRRQ_CASE(KS6); ++ break; ++ GEN_CSRRQ_CASE(KS7); ++ break; ++ GEN_CSRRQ_CASE(KS8); ++ break; ++ GEN_CSRRQ_CASE(TMID); ++ break; ++ GEN_CSRRQ_CASE(TCFG); ++ break; ++ GEN_CSRRQ_CASE(TVAL); ++ break; ++ GEN_CSRRQ_CASE(CNTC); ++ break; ++ GEN_CSRRQ_CASE(TINTCLR); ++ break; ++ GEN_CSRRQ_CASE(GSTAT); ++ break; ++ GEN_CSRRQ_CASE(GCFG); ++ break; ++ GEN_CSRRQ_CASE(GINTC); ++ break; ++ GEN_CSRRQ_CASE(GCNTC); ++ break; ++ GEN_CSRRQ_CASE(LLBCTL); ++ break; ++ GEN_CSRRQ_CASE(IMPCTL1); ++ break; ++ GEN_CSRRQ_CASE(IMPCTL2); ++ break; ++ GEN_CSRRQ_CASE(GNMI); ++ break; ++ GEN_CSRRQ_CASE(TLBRENT); ++ break; ++ GEN_CSRRQ_CASE(TLBRBADV); ++ break; ++ GEN_CSRRQ_CASE(TLBRERA); ++ break; ++ GEN_CSRRQ_CASE(TLBRSAVE); ++ break; ++ GEN_CSRRQ_CASE(TLBRELO0); ++ break; ++ GEN_CSRRQ_CASE(TLBRELO1); ++ break; ++ GEN_CSRRQ_CASE(TLBREHI); ++ break; ++ GEN_CSRRQ_CASE(TLBRPRMD); ++ break; ++ GEN_CSRRQ_CASE(ERRCTL); ++ break; ++ GEN_CSRRQ_CASE(ERRINFO); ++ break; ++ GEN_CSRRQ_CASE(ERRINFO1); ++ break; ++ GEN_CSRRQ_CASE(ERRENT); ++ break; ++ GEN_CSRRQ_CASE(ERRERA); ++ break; ++ GEN_CSRRQ_CASE(ERRSAVE); ++ break; ++ GEN_CSRRQ_CASE(CTAG); ++ break; ++ GEN_CSRRQ_CASE(DMWIN0); ++ break; ++ GEN_CSRRQ_CASE(DMWIN1); ++ break; ++ GEN_CSRRQ_CASE(DMWIN2); ++ break; ++ GEN_CSRRQ_CASE(DMWIN3); ++ break; ++ GEN_CSRRQ_CASE(PERFCTRL0); ++ break; ++ GEN_CSRRQ_CASE(PERFCNTR0); ++ break; ++ GEN_CSRRQ_CASE(PERFCTRL1); ++ break; ++ GEN_CSRRQ_CASE(PERFCNTR1); ++ break; ++ GEN_CSRRQ_CASE(PERFCTRL2); ++ break; ++ GEN_CSRRQ_CASE(PERFCNTR2); ++ break; ++ GEN_CSRRQ_CASE(PERFCTRL3); ++ break; ++ GEN_CSRRQ_CASE(PERFCNTR3); ++ break; ++ /* debug */ ++ GEN_CSRRQ_CASE(MWPC); ++ break; ++ GEN_CSRRQ_CASE(MWPS); ++ break; ++ GEN_CSRRQ_CASE(DB0ADDR); ++ break; ++ GEN_CSRRQ_CASE(DB0MASK); ++ break; ++ GEN_CSRRQ_CASE(DB0CTL); ++ break; ++ GEN_CSRRQ_CASE(DB0ASID); ++ break; ++ GEN_CSRRQ_CASE(DB1ADDR); ++ break; ++ GEN_CSRRQ_CASE(DB1MASK); ++ break; ++ GEN_CSRRQ_CASE(DB1CTL); ++ break; ++ GEN_CSRRQ_CASE(DB1ASID); ++ break; ++ GEN_CSRRQ_CASE(DB2ADDR); ++ break; ++ GEN_CSRRQ_CASE(DB2MASK); ++ break; ++ GEN_CSRRQ_CASE(DB2CTL); ++ break; ++ GEN_CSRRQ_CASE(DB2ASID); ++ break; ++ GEN_CSRRQ_CASE(DB3ADDR); ++ break; ++ GEN_CSRRQ_CASE(DB3MASK); ++ break; ++ GEN_CSRRQ_CASE(DB3CTL); ++ break; ++ GEN_CSRRQ_CASE(DB3ASID); ++ break; ++ GEN_CSRRQ_CASE(FWPC); ++ break; ++ GEN_CSRRQ_CASE(FWPS); ++ break; ++ GEN_CSRRQ_CASE(IB0ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB0MASK); ++ break; ++ GEN_CSRRQ_CASE(IB0CTL); ++ break; ++ GEN_CSRRQ_CASE(IB0ASID); ++ break; ++ GEN_CSRRQ_CASE(IB1ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB1MASK); ++ break; ++ GEN_CSRRQ_CASE(IB1CTL); ++ break; ++ GEN_CSRRQ_CASE(IB1ASID); ++ break; ++ GEN_CSRRQ_CASE(IB2ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB2MASK); ++ break; ++ GEN_CSRRQ_CASE(IB2CTL); ++ break; ++ GEN_CSRRQ_CASE(IB2ASID); ++ break; ++ GEN_CSRRQ_CASE(IB3ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB3MASK); ++ break; ++ GEN_CSRRQ_CASE(IB3CTL); ++ break; ++ GEN_CSRRQ_CASE(IB3ASID); ++ break; ++ GEN_CSRRQ_CASE(IB4ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB4MASK); ++ break; ++ GEN_CSRRQ_CASE(IB4CTL); ++ break; ++ GEN_CSRRQ_CASE(IB4ASID); ++ break; ++ GEN_CSRRQ_CASE(IB5ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB5MASK); ++ break; ++ GEN_CSRRQ_CASE(IB5CTL); ++ break; ++ GEN_CSRRQ_CASE(IB5ASID); ++ break; ++ GEN_CSRRQ_CASE(IB6ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB6MASK); ++ break; ++ GEN_CSRRQ_CASE(IB6CTL); ++ break; ++ GEN_CSRRQ_CASE(IB6ASID); ++ break; ++ GEN_CSRRQ_CASE(IB7ADDR); ++ break; ++ GEN_CSRRQ_CASE(IB7MASK); ++ break; ++ GEN_CSRRQ_CASE(IB7CTL); ++ break; ++ GEN_CSRRQ_CASE(IB7ASID); ++ break; ++ GEN_CSRRQ_CASE(DEBUG); ++ break; ++ GEN_CSRRQ_CASE(DERA); ++ break; ++ GEN_CSRRQ_CASE(DESAVE); ++ break; ++ default: ++ return false; ++ } ++ ++ #undef GEN_CSRRQ_CASE ++ ++ return true; ++} ++ ++#define GEN_CSRWQ_CASE(name) \ ++do { \ ++ case LOONGARCH_CSR_ ## name: \ ++ gen_csr_wrq(ctx, cpu_gpr[rd], LOONGARCH_CSR_ ## name); \ ++} while (0) ++ ++static bool trans_csrwr(DisasContext *ctx, unsigned rd, unsigned csr) ++{ ++ ++ switch (csr) { ++ case LOONGARCH_CSR_CRMD: ++ save_cpu_state(ctx, 1); ++ gen_csr_wrq(ctx, cpu_gpr[rd], LOONGARCH_CSR_CRMD); ++ gen_save_pc(ctx->base.pc_next + 4); ++ ctx->base.is_jmp = DISAS_EXIT; ++ break; ++ GEN_CSRWQ_CASE(PRMD); ++ break; ++ case LOONGARCH_CSR_EUEN: ++ gen_csr_wrq(ctx, cpu_gpr[rd], LOONGARCH_CSR_EUEN); ++ /* Stop translation */ ++ gen_save_pc(ctx->base.pc_next + 4); ++ ctx->base.is_jmp = DISAS_EXIT; ++ break; ++ GEN_CSRWQ_CASE(MISC); ++ break; ++ GEN_CSRWQ_CASE(ECFG); ++ break; ++ GEN_CSRWQ_CASE(ESTAT); ++ break; ++ GEN_CSRWQ_CASE(ERA); ++ break; ++ GEN_CSRWQ_CASE(BADV); ++ break; ++ GEN_CSRWQ_CASE(BADI); ++ break; ++ GEN_CSRWQ_CASE(EEPN); ++ break; ++ GEN_CSRWQ_CASE(TLBIDX); ++ break; ++ GEN_CSRWQ_CASE(TLBEHI); ++ break; ++ GEN_CSRWQ_CASE(TLBELO0); ++ break; ++ GEN_CSRWQ_CASE(TLBELO1); ++ break; ++ GEN_CSRWQ_CASE(TLBWIRED); ++ break; ++ GEN_CSRWQ_CASE(GTLBC); ++ break; ++ GEN_CSRWQ_CASE(TRGP); ++ break; ++ GEN_CSRWQ_CASE(ASID); ++ break; ++ GEN_CSRWQ_CASE(PGDL); ++ break; ++ GEN_CSRWQ_CASE(PGDH); ++ break; ++ GEN_CSRWQ_CASE(PGD); ++ break; ++ GEN_CSRWQ_CASE(PWCTL0); ++ break; ++ GEN_CSRWQ_CASE(PWCTL1); ++ break; ++ GEN_CSRWQ_CASE(STLBPGSIZE); ++ break; ++ GEN_CSRWQ_CASE(RVACFG); ++ break; ++ GEN_CSRWQ_CASE(CPUID); ++ break; ++ GEN_CSRWQ_CASE(PRCFG1); ++ break; ++ GEN_CSRWQ_CASE(PRCFG2); ++ break; ++ GEN_CSRWQ_CASE(PRCFG3); ++ break; ++ GEN_CSRWQ_CASE(KS0); ++ break; ++ GEN_CSRWQ_CASE(KS1); ++ break; ++ GEN_CSRWQ_CASE(KS2); ++ break; ++ GEN_CSRWQ_CASE(KS3); ++ break; ++ GEN_CSRWQ_CASE(KS4); ++ break; ++ GEN_CSRWQ_CASE(KS5); ++ break; ++ GEN_CSRWQ_CASE(KS6); ++ break; ++ GEN_CSRWQ_CASE(KS7); ++ break; ++ GEN_CSRWQ_CASE(KS8); ++ break; ++ GEN_CSRWQ_CASE(TMID); ++ break; ++ GEN_CSRWQ_CASE(TCFG); ++ break; ++ GEN_CSRWQ_CASE(TVAL); ++ break; ++ GEN_CSRWQ_CASE(CNTC); ++ break; ++ GEN_CSRWQ_CASE(TINTCLR); ++ break; ++ GEN_CSRWQ_CASE(GSTAT); ++ break; ++ GEN_CSRWQ_CASE(GCFG); ++ break; ++ GEN_CSRWQ_CASE(GINTC); ++ break; ++ GEN_CSRWQ_CASE(GCNTC); ++ break; ++ GEN_CSRWQ_CASE(LLBCTL); ++ break; ++ GEN_CSRWQ_CASE(IMPCTL1); ++ break; ++ GEN_CSRWQ_CASE(IMPCTL2); ++ break; ++ GEN_CSRWQ_CASE(GNMI); ++ break; ++ GEN_CSRWQ_CASE(TLBRENT); ++ break; ++ GEN_CSRWQ_CASE(TLBRBADV); ++ break; ++ GEN_CSRWQ_CASE(TLBRERA); ++ break; ++ GEN_CSRWQ_CASE(TLBRSAVE); ++ break; ++ GEN_CSRWQ_CASE(TLBRELO0); ++ break; ++ GEN_CSRWQ_CASE(TLBRELO1); ++ break; ++ GEN_CSRWQ_CASE(TLBREHI); ++ break; ++ GEN_CSRWQ_CASE(TLBRPRMD); ++ break; ++ GEN_CSRWQ_CASE(ERRCTL); ++ break; ++ GEN_CSRWQ_CASE(ERRINFO); ++ break; ++ GEN_CSRWQ_CASE(ERRINFO1); ++ break; ++ GEN_CSRWQ_CASE(ERRENT); ++ break; ++ GEN_CSRWQ_CASE(ERRERA); ++ break; ++ GEN_CSRWQ_CASE(ERRSAVE); ++ break; ++ GEN_CSRWQ_CASE(CTAG); ++ break; ++ GEN_CSRWQ_CASE(DMWIN0); ++ break; ++ GEN_CSRWQ_CASE(DMWIN1); ++ break; ++ GEN_CSRWQ_CASE(DMWIN2); ++ break; ++ GEN_CSRWQ_CASE(DMWIN3); ++ break; ++ GEN_CSRWQ_CASE(PERFCTRL0); ++ break; ++ GEN_CSRWQ_CASE(PERFCNTR0); ++ break; ++ GEN_CSRWQ_CASE(PERFCTRL1); ++ break; ++ GEN_CSRWQ_CASE(PERFCNTR1); ++ break; ++ GEN_CSRWQ_CASE(PERFCTRL2); ++ break; ++ GEN_CSRWQ_CASE(PERFCNTR2); ++ break; ++ GEN_CSRWQ_CASE(PERFCTRL3); ++ break; ++ GEN_CSRWQ_CASE(PERFCNTR3); ++ break; ++ /* debug */ ++ GEN_CSRWQ_CASE(MWPC); ++ break; ++ GEN_CSRWQ_CASE(MWPS); ++ break; ++ GEN_CSRWQ_CASE(DB0ADDR); ++ break; ++ GEN_CSRWQ_CASE(DB0MASK); ++ break; ++ GEN_CSRWQ_CASE(DB0CTL); ++ break; ++ GEN_CSRWQ_CASE(DB0ASID); ++ break; ++ GEN_CSRWQ_CASE(DB1ADDR); ++ break; ++ GEN_CSRWQ_CASE(DB1MASK); ++ break; ++ GEN_CSRWQ_CASE(DB1CTL); ++ break; ++ GEN_CSRWQ_CASE(DB1ASID); ++ break; ++ GEN_CSRWQ_CASE(DB2ADDR); ++ break; ++ GEN_CSRWQ_CASE(DB2MASK); ++ break; ++ GEN_CSRWQ_CASE(DB2CTL); ++ break; ++ GEN_CSRWQ_CASE(DB2ASID); ++ break; ++ GEN_CSRWQ_CASE(DB3ADDR); ++ break; ++ GEN_CSRWQ_CASE(DB3MASK); ++ break; ++ GEN_CSRWQ_CASE(DB3CTL); ++ break; ++ GEN_CSRWQ_CASE(DB3ASID); ++ break; ++ GEN_CSRWQ_CASE(FWPC); ++ break; ++ GEN_CSRWQ_CASE(FWPS); ++ break; ++ GEN_CSRWQ_CASE(IB0ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB0MASK); ++ break; ++ GEN_CSRWQ_CASE(IB0CTL); ++ break; ++ GEN_CSRWQ_CASE(IB0ASID); ++ break; ++ GEN_CSRWQ_CASE(IB1ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB1MASK); ++ break; ++ GEN_CSRWQ_CASE(IB1CTL); ++ break; ++ GEN_CSRWQ_CASE(IB1ASID); ++ break; ++ GEN_CSRWQ_CASE(IB2ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB2MASK); ++ break; ++ GEN_CSRWQ_CASE(IB2CTL); ++ break; ++ GEN_CSRWQ_CASE(IB2ASID); ++ break; ++ GEN_CSRWQ_CASE(IB3ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB3MASK); ++ break; ++ GEN_CSRWQ_CASE(IB3CTL); ++ break; ++ GEN_CSRWQ_CASE(IB3ASID); ++ break; ++ GEN_CSRWQ_CASE(IB4ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB4MASK); ++ break; ++ GEN_CSRWQ_CASE(IB4CTL); ++ break; ++ GEN_CSRWQ_CASE(IB4ASID); ++ break; ++ GEN_CSRWQ_CASE(IB5ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB5MASK); ++ break; ++ GEN_CSRWQ_CASE(IB5CTL); ++ break; ++ GEN_CSRWQ_CASE(IB5ASID); ++ break; ++ GEN_CSRWQ_CASE(IB6ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB6MASK); ++ break; ++ GEN_CSRWQ_CASE(IB6CTL); ++ break; ++ GEN_CSRWQ_CASE(IB6ASID); ++ break; ++ GEN_CSRWQ_CASE(IB7ADDR); ++ break; ++ GEN_CSRWQ_CASE(IB7MASK); ++ break; ++ GEN_CSRWQ_CASE(IB7CTL); ++ break; ++ GEN_CSRWQ_CASE(IB7ASID); ++ break; ++ GEN_CSRWQ_CASE(DEBUG); ++ break; ++ GEN_CSRWQ_CASE(DERA); ++ break; ++ GEN_CSRWQ_CASE(DESAVE); ++ break; ++ default: ++ return false; ++ } ++ ++ #undef GEN_CSRWQ_CASE ++ ++ return true; ++} ++ ++#define GEN_CSRXQ_CASE(name) \ ++do { \ ++ case LOONGARCH_CSR_ ## name: \ ++ if (rd == 0) { \ ++ gen_csr_xchgq(ctx, zero, cpu_gpr[rj], \ ++ LOONGARCH_CSR_ ## name); \ ++ } else { \ ++ gen_csr_xchgq(ctx, cpu_gpr[rd], cpu_gpr[rj], \ ++ LOONGARCH_CSR_ ## name); \ ++ } \ ++} while (0) ++ ++static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) ++{ ++ unsigned rd, rj, csr; ++ TCGv zero = tcg_const_tl(0); ++ rd = a->rd; ++ rj = a->rj; ++ csr = a->csr; ++ ++ if (rj == 0) { ++ return trans_csrrd(ctx, rd, csr); ++ } else if (rj == 1) { ++ return trans_csrwr(ctx, rd, csr); ++ } ++ ++ switch (csr) { ++ case LOONGARCH_CSR_CRMD: ++ save_cpu_state(ctx, 1); ++ if (rd == 0) { ++ gen_csr_xchgq(ctx, zero, cpu_gpr[rj], LOONGARCH_CSR_CRMD); ++ } else { ++ gen_csr_xchgq(ctx, cpu_gpr[rd], cpu_gpr[rj], LOONGARCH_CSR_CRMD); ++ } ++ gen_save_pc(ctx->base.pc_next + 4); ++ ctx->base.is_jmp = DISAS_EXIT; ++ break; ++ ++ GEN_CSRXQ_CASE(PRMD); ++ break; ++ case LOONGARCH_CSR_EUEN: ++ if (rd == 0) { ++ gen_csr_xchgq(ctx, zero, cpu_gpr[rj], LOONGARCH_CSR_EUEN); ++ } else { ++ gen_csr_xchgq(ctx, cpu_gpr[rd], cpu_gpr[rj], LOONGARCH_CSR_EUEN); ++ } ++ /* Stop translation */ ++ gen_save_pc(ctx->base.pc_next + 4); ++ ctx->base.is_jmp = DISAS_EXIT; ++ break; ++ GEN_CSRXQ_CASE(MISC); ++ break; ++ GEN_CSRXQ_CASE(ECFG); ++ break; ++ GEN_CSRXQ_CASE(ESTAT); ++ break; ++ GEN_CSRXQ_CASE(ERA); ++ break; ++ GEN_CSRXQ_CASE(BADV); ++ break; ++ GEN_CSRXQ_CASE(BADI); ++ break; ++ GEN_CSRXQ_CASE(EEPN); ++ break; ++ GEN_CSRXQ_CASE(TLBIDX); ++ break; ++ GEN_CSRXQ_CASE(TLBEHI); ++ break; ++ GEN_CSRXQ_CASE(TLBELO0); ++ break; ++ GEN_CSRXQ_CASE(TLBELO1); ++ break; ++ GEN_CSRXQ_CASE(TLBWIRED); ++ break; ++ GEN_CSRXQ_CASE(GTLBC); ++ break; ++ GEN_CSRXQ_CASE(TRGP); ++ break; ++ GEN_CSRXQ_CASE(ASID); ++ break; ++ GEN_CSRXQ_CASE(PGDL); ++ break; ++ GEN_CSRXQ_CASE(PGDH); ++ break; ++ GEN_CSRXQ_CASE(PGD); ++ break; ++ GEN_CSRXQ_CASE(PWCTL0); ++ break; ++ GEN_CSRXQ_CASE(PWCTL1); ++ break; ++ GEN_CSRXQ_CASE(STLBPGSIZE); ++ break; ++ GEN_CSRXQ_CASE(RVACFG); ++ break; ++ GEN_CSRXQ_CASE(CPUID); ++ break; ++ GEN_CSRXQ_CASE(PRCFG1); ++ break; ++ GEN_CSRXQ_CASE(PRCFG2); ++ break; ++ GEN_CSRXQ_CASE(PRCFG3); ++ break; ++ GEN_CSRXQ_CASE(KS0); ++ break; ++ GEN_CSRXQ_CASE(KS1); ++ break; ++ GEN_CSRXQ_CASE(KS2); ++ break; ++ GEN_CSRXQ_CASE(KS3); ++ break; ++ GEN_CSRXQ_CASE(KS4); ++ break; ++ GEN_CSRXQ_CASE(KS5); ++ break; ++ GEN_CSRXQ_CASE(KS6); ++ break; ++ GEN_CSRXQ_CASE(KS7); ++ break; ++ GEN_CSRXQ_CASE(KS8); ++ break; ++ GEN_CSRXQ_CASE(TMID); ++ break; ++ GEN_CSRXQ_CASE(TCFG); ++ break; ++ GEN_CSRXQ_CASE(TVAL); ++ break; ++ GEN_CSRXQ_CASE(CNTC); ++ break; ++ GEN_CSRXQ_CASE(TINTCLR); ++ break; ++ GEN_CSRXQ_CASE(GSTAT); ++ break; ++ GEN_CSRXQ_CASE(GCFG); ++ break; ++ GEN_CSRXQ_CASE(GINTC); ++ break; ++ GEN_CSRXQ_CASE(GCNTC); ++ break; ++ GEN_CSRXQ_CASE(LLBCTL); ++ break; ++ GEN_CSRXQ_CASE(IMPCTL1); ++ break; ++ GEN_CSRXQ_CASE(IMPCTL2); ++ break; ++ GEN_CSRXQ_CASE(GNMI); ++ break; ++ GEN_CSRXQ_CASE(TLBRENT); ++ break; ++ GEN_CSRXQ_CASE(TLBRBADV); ++ break; ++ GEN_CSRXQ_CASE(TLBRERA); ++ break; ++ GEN_CSRXQ_CASE(TLBRSAVE); ++ break; ++ GEN_CSRXQ_CASE(TLBRELO0); ++ break; ++ GEN_CSRXQ_CASE(TLBRELO1); ++ break; ++ GEN_CSRXQ_CASE(TLBREHI); ++ break; ++ GEN_CSRXQ_CASE(TLBRPRMD); ++ break; ++ GEN_CSRXQ_CASE(ERRCTL); ++ break; ++ GEN_CSRXQ_CASE(ERRINFO); ++ break; ++ GEN_CSRXQ_CASE(ERRINFO1); ++ break; ++ GEN_CSRXQ_CASE(ERRENT); ++ break; ++ GEN_CSRXQ_CASE(ERRERA); ++ break; ++ GEN_CSRXQ_CASE(ERRSAVE); ++ break; ++ GEN_CSRXQ_CASE(CTAG); ++ break; ++ GEN_CSRXQ_CASE(DMWIN0); ++ break; ++ GEN_CSRXQ_CASE(DMWIN1); ++ break; ++ GEN_CSRXQ_CASE(DMWIN2); ++ break; ++ GEN_CSRXQ_CASE(DMWIN3); ++ break; ++ GEN_CSRXQ_CASE(PERFCTRL0); ++ break; ++ GEN_CSRXQ_CASE(PERFCNTR0); ++ break; ++ GEN_CSRXQ_CASE(PERFCTRL1); ++ break; ++ GEN_CSRXQ_CASE(PERFCNTR1); ++ break; ++ GEN_CSRXQ_CASE(PERFCTRL2); ++ break; ++ GEN_CSRXQ_CASE(PERFCNTR2); ++ break; ++ GEN_CSRXQ_CASE(PERFCTRL3); ++ break; ++ GEN_CSRXQ_CASE(PERFCNTR3); ++ break; ++ /* debug */ ++ GEN_CSRXQ_CASE(MWPC); ++ break; ++ GEN_CSRXQ_CASE(MWPS); ++ break; ++ GEN_CSRXQ_CASE(DB0ADDR); ++ break; ++ GEN_CSRXQ_CASE(DB0MASK); ++ break; ++ GEN_CSRXQ_CASE(DB0CTL); ++ break; ++ GEN_CSRXQ_CASE(DB0ASID); ++ break; ++ GEN_CSRXQ_CASE(DB1ADDR); ++ break; ++ GEN_CSRXQ_CASE(DB1MASK); ++ break; ++ GEN_CSRXQ_CASE(DB1CTL); ++ break; ++ GEN_CSRXQ_CASE(DB1ASID); ++ break; ++ GEN_CSRXQ_CASE(DB2ADDR); ++ break; ++ GEN_CSRXQ_CASE(DB2MASK); ++ break; ++ GEN_CSRXQ_CASE(DB2CTL); ++ break; ++ GEN_CSRXQ_CASE(DB2ASID); ++ break; ++ GEN_CSRXQ_CASE(DB3ADDR); ++ break; ++ GEN_CSRXQ_CASE(DB3MASK); ++ break; ++ GEN_CSRXQ_CASE(DB3CTL); ++ break; ++ GEN_CSRXQ_CASE(DB3ASID); ++ break; ++ GEN_CSRXQ_CASE(FWPC); ++ break; ++ GEN_CSRXQ_CASE(FWPS); ++ break; ++ GEN_CSRXQ_CASE(IB0ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB0MASK); ++ break; ++ GEN_CSRXQ_CASE(IB0CTL); ++ break; ++ GEN_CSRXQ_CASE(IB0ASID); ++ break; ++ GEN_CSRXQ_CASE(IB1ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB1MASK); ++ break; ++ GEN_CSRXQ_CASE(IB1CTL); ++ break; ++ GEN_CSRXQ_CASE(IB1ASID); ++ break; ++ GEN_CSRXQ_CASE(IB2ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB2MASK); ++ break; ++ GEN_CSRXQ_CASE(IB2CTL); ++ break; ++ GEN_CSRXQ_CASE(IB2ASID); ++ break; ++ GEN_CSRXQ_CASE(IB3ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB3MASK); ++ break; ++ GEN_CSRXQ_CASE(IB3CTL); ++ break; ++ GEN_CSRXQ_CASE(IB3ASID); ++ break; ++ GEN_CSRXQ_CASE(IB4ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB4MASK); ++ break; ++ GEN_CSRXQ_CASE(IB4CTL); ++ break; ++ GEN_CSRXQ_CASE(IB4ASID); ++ break; ++ GEN_CSRXQ_CASE(IB5ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB5MASK); ++ break; ++ GEN_CSRXQ_CASE(IB5CTL); ++ break; ++ GEN_CSRXQ_CASE(IB5ASID); ++ break; ++ GEN_CSRXQ_CASE(IB6ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB6MASK); ++ break; ++ GEN_CSRXQ_CASE(IB6CTL); ++ break; ++ GEN_CSRXQ_CASE(IB6ASID); ++ break; ++ GEN_CSRXQ_CASE(IB7ADDR); ++ break; ++ GEN_CSRXQ_CASE(IB7MASK); ++ break; ++ GEN_CSRXQ_CASE(IB7CTL); ++ break; ++ GEN_CSRXQ_CASE(IB7ASID); ++ break; ++ GEN_CSRXQ_CASE(DEBUG); ++ break; ++ GEN_CSRXQ_CASE(DERA); ++ break; ++ GEN_CSRXQ_CASE(DESAVE); ++ break; ++ default: ++ return false; ++ } ++ ++ #undef GEN_CSRXQ_CASE ++ tcg_temp_free(zero); ++ return true; ++} ++ ++#endif ++ ++static bool trans_cacop(DisasContext *ctx, arg_cacop *a) ++{ ++ /* Treat as NOP. */ ++ return true; ++} ++ ++#ifdef CONFIG_USER_ONLY ++ ++static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a) ++{ ++ return false; ++} ++ ++static bool trans_lddir(DisasContext *ctx, arg_lddir *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrrd_b(DisasContext *ctx, arg_iocsrrd_b *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrrd_h(DisasContext *ctx, arg_iocsrrd_h *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrrd_w(DisasContext *ctx, arg_iocsrrd_w *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrrd_d(DisasContext *ctx, arg_iocsrrd_d *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrwr_b(DisasContext *ctx, arg_iocsrwr_b *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrwr_h(DisasContext *ctx, arg_iocsrwr_h *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrwr_w(DisasContext *ctx, arg_iocsrwr_w *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrwr_d(DisasContext *ctx, arg_iocsrwr_d *a) ++{ ++ return false; ++} ++#else ++ ++static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a) ++{ ++ TCGv t0, t1; ++ TCGv_i32 t2; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->seq); ++ t2 = tcg_const_i32(ctx->mem_idx); ++ gen_helper_ldpte(cpu_env, t0, t1, t2); ++ ++ return true; ++} ++ ++static bool trans_lddir(DisasContext *ctx, arg_lddir *a) ++{ ++ TCGv t0, t1, t2; ++ TCGv_i32 t3; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->rd); ++ t2 = tcg_const_tl(a->level); ++ t3 = tcg_const_i32(ctx->mem_idx); ++ gen_helper_lddir(cpu_env, t0, t1, t2, t3); ++ ++ return true; ++} ++ ++static bool trans_iocsrrd_b(DisasContext *ctx, arg_iocsrrd_b *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrrd_h(DisasContext *ctx, arg_iocsrrd_h *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrrd_w(DisasContext *ctx, arg_iocsrrd_w *a) ++{ ++ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_LD_W); ++ TCGv t0, t1; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->rd); ++ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); ++ return true; ++} ++ ++static bool trans_iocsrrd_d(DisasContext *ctx, arg_iocsrrd_d *a) ++{ ++ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_LD_D); ++ TCGv t0, t1; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->rd); ++ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); ++ return true; ++} ++ ++static bool trans_iocsrwr_b(DisasContext *ctx, arg_iocsrwr_b *a) ++{ ++ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_ST_B); ++ TCGv t0, t1; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->rd); ++ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); ++ return true; ++} ++ ++static bool trans_iocsrwr_h(DisasContext *ctx, arg_iocsrwr_h *a) ++{ ++ return false; ++} ++ ++static bool trans_iocsrwr_w(DisasContext *ctx, arg_iocsrwr_w *a) ++{ ++ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_ST_W); ++ TCGv t0, t1; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->rd); ++ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); ++ return true; ++} ++ ++static bool trans_iocsrwr_d(DisasContext *ctx, arg_iocsrwr_d *a) ++{ ++ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_ST_D); ++ TCGv t0, t1; ++ t0 = tcg_const_tl(a->rj); ++ t1 = tcg_const_tl(a->rd); ++ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); ++ return true; ++} ++#endif /* !CONFIG_USER_ONLY */ ++ ++ ++#ifdef CONFIG_USER_ONLY ++ ++#define GEN_FALSE_TRANS(name) \ ++static bool trans_##name(DisasContext *ctx, arg_##name * a) \ ++{ \ ++ return false; \ ++} ++ ++GEN_FALSE_TRANS(tlbclr) ++GEN_FALSE_TRANS(invtlb) ++GEN_FALSE_TRANS(tlbflush) ++GEN_FALSE_TRANS(tlbsrch) ++GEN_FALSE_TRANS(tlbrd) ++GEN_FALSE_TRANS(tlbwr) ++GEN_FALSE_TRANS(tlbfill) ++GEN_FALSE_TRANS(ertn) ++ ++#else ++ ++static bool trans_tlbclr(DisasContext *ctx, arg_tlbclr *a) ++{ ++ gen_helper_tlbclr(cpu_env); ++ return true; ++} ++ ++static bool trans_tlbflush(DisasContext *ctx, arg_tlbflush *a) ++{ ++ gen_helper_tlbflush(cpu_env); ++ return true; ++} ++ ++static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a) ++{ ++ TCGv addr = tcg_temp_new(); ++ TCGv info = tcg_temp_new(); ++ TCGv op = tcg_const_tl(a->invop); ++ ++ gen_load_gpr(addr, a->addr); ++ gen_load_gpr(info, a->info); ++ gen_helper_invtlb(cpu_env, addr, info, op); ++ ++ tcg_temp_free(addr); ++ tcg_temp_free(info); ++ tcg_temp_free(op); ++ return true; ++} ++ ++static bool trans_tlbsrch(DisasContext *ctx, arg_tlbsrch *a) ++{ ++ gen_helper_tlbsrch(cpu_env); ++ return true; ++} ++ ++static bool trans_tlbrd(DisasContext *ctx, arg_tlbrd *a) ++{ ++ gen_helper_tlbrd(cpu_env); ++ return true; ++} ++ ++static bool trans_tlbwr(DisasContext *ctx, arg_tlbwr *a) ++{ ++ gen_helper_tlbwr(cpu_env); ++ return true; ++} ++ ++static bool trans_tlbfill(DisasContext *ctx, arg_tlbfill *a) ++{ ++ gen_helper_tlbfill(cpu_env); ++ return true; ++} ++ ++static bool trans_ertn(DisasContext *ctx, arg_ertn *a) ++{ ++ gen_helper_ertn(cpu_env); ++ ctx->base.is_jmp = DISAS_EXIT; ++ return true; ++} ++ ++#endif /* CONFIG_USER_ONLY */ ++ ++static bool trans_idle(DisasContext *ctx, arg_idle *a) ++{ ++ ctx->base.pc_next += 4; ++ save_cpu_state(ctx, 1); ++ ctx->base.pc_next -= 4; ++ gen_helper_idle(cpu_env); ++ ctx->base.is_jmp = DISAS_NORETURN; ++ return true; ++} ++ ++#ifdef CONFIG_USER_ONLY ++ ++static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a) ++{ ++ /* Nop */ ++ return true; ++} ++ ++#else ++ ++static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a) ++{ ++ TCGv t0, t1; ++ t0 = tcg_const_tl(a->rd); ++ t1 = tcg_const_tl(a->rj); ++ gen_helper_drdtime(cpu_env, t0, t1); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return true; ++} ++ ++#endif ++ ++static bool trans_cpucfg(DisasContext *ctx, arg_cpucfg *a) ++{ ++ TCGv t0 = tcg_temp_new(); ++ gen_load_gpr(t0, a->rj); ++ gen_helper_cpucfg(cpu_gpr[a->rd], cpu_env, t0); ++ tcg_temp_free(t0); ++ return true; ++} +diff --git a/target/loongarch64/translate.c b/target/loongarch64/translate.c +new file mode 100644 +index 000000000..fe122e4c3 +--- /dev/null ++++ b/target/loongarch64/translate.c +@@ -0,0 +1,2892 @@ ++/* ++ * LOONGARCH emulation for QEMU - main translation routines ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++ ++#include "qemu/osdep.h" ++#include "cpu.h" ++#include "internal.h" ++#include "disas/disas.h" ++#include "exec/exec-all.h" ++#include "tcg/tcg-op.h" ++#include "exec/cpu_ldst.h" ++#include "hw/loongarch/cpudevs.h" ++ ++#include "exec/helper-proto.h" ++#include "exec/helper-gen.h" ++#include "semihosting/semihost.h" ++ ++#include "trace-tcg.h" ++#include "exec/translator.h" ++#include "exec/log.h" ++ ++#include "instmap.h" ++ ++#define LARCH_DEBUG_DISAS 0 ++ ++/* Values for the fmt field in FP instructions */ ++enum { ++ /* 0 - 15 are reserved */ ++ FMT_S = 16, /* single fp */ ++ FMT_D = 17, /* double fp */ ++}; ++ ++/* global register indices */ ++static TCGv cpu_gpr[32], cpu_PC; ++static TCGv btarget, bcond; ++static TCGv cpu_lladdr, cpu_llval; ++static TCGv_i32 hflags; ++static TCGv_i32 fpu_fcsr0; ++static TCGv_i64 fpu_f64[32]; ++ ++#include "exec/gen-icount.h" ++ ++#define gen_helper_0e0i(name, arg) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg); \ ++ gen_helper_##name(cpu_env, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++#define gen_helper_0e1i(name, arg1, arg2) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ ++ gen_helper_##name(cpu_env, arg1, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++#define gen_helper_1e0i(name, ret, arg1) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg1); \ ++ gen_helper_##name(ret, cpu_env, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++#define gen_helper_1e1i(name, ret, arg1, arg2) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ ++ gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ ++ gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ ++ gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \ ++ TCGv_i32 helper_tmp = tcg_const_i32(arg4); \ ++ gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \ ++ tcg_temp_free_i32(helper_tmp); \ ++ } while (0) ++ ++typedef struct DisasContext { ++ DisasContextBase base; ++ target_ulong saved_pc; ++ target_ulong page_start; ++ uint32_t opcode; ++ uint64_t insn_flags; ++ /* Routine used to access memory */ ++ int mem_idx; ++ MemOp default_tcg_memop_mask; ++ uint32_t hflags, saved_hflags; ++ target_ulong btarget; ++} DisasContext; ++ ++#define DISAS_STOP DISAS_TARGET_0 ++#define DISAS_EXIT DISAS_TARGET_1 ++ ++#define LOG_DISAS(...) \ ++ do { \ ++ if (LARCH_DEBUG_DISAS) { \ ++ qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \ ++ } \ ++ } while (0) ++ ++#define LARCH_INVAL(op) \ ++ do { \ ++ if (LARCH_DEBUG_DISAS) { \ ++ qemu_log_mask(CPU_LOG_TB_IN_ASM, \ ++ TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \ ++ ctx->base.pc_next, ctx->opcode, op, \ ++ ctx->opcode >> 26, ctx->opcode & 0x3F, \ ++ ((ctx->opcode >> 16) & 0x1F)); \ ++ } \ ++ } while (0) ++ ++/* General purpose registers moves. */ ++static inline void gen_load_gpr(TCGv t, int reg) ++{ ++ if (reg == 0) { ++ tcg_gen_movi_tl(t, 0); ++ } else { ++ tcg_gen_mov_tl(t, cpu_gpr[reg]); ++ } ++} ++ ++static inline void gen_store_gpr(TCGv t, int reg) ++{ ++ if (reg != 0) { ++ tcg_gen_mov_tl(cpu_gpr[reg], t); ++ } ++} ++ ++/* Moves to/from shadow registers. */ ++/* Tests */ ++static inline void gen_save_pc(target_ulong pc) ++{ ++ tcg_gen_movi_tl(cpu_PC, pc); ++} ++ ++static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) ++{ ++ LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); ++ if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { ++ gen_save_pc(ctx->base.pc_next); ++ ctx->saved_pc = ctx->base.pc_next; ++ } ++ if (ctx->hflags != ctx->saved_hflags) { ++ tcg_gen_movi_i32(hflags, ctx->hflags); ++ ctx->saved_hflags = ctx->hflags; ++ switch (ctx->hflags & LARCH_HFLAG_BMASK) { ++ case LARCH_HFLAG_BR: ++ break; ++ case LARCH_HFLAG_BC: ++ case LARCH_HFLAG_B: ++ tcg_gen_movi_tl(btarget, ctx->btarget); ++ break; ++ } ++ } ++} ++ ++static inline void restore_cpu_state(CPULOONGARCHState *env, DisasContext *ctx) ++{ ++ ctx->saved_hflags = ctx->hflags; ++ switch (ctx->hflags & LARCH_HFLAG_BMASK) { ++ case LARCH_HFLAG_BR: ++ break; ++ case LARCH_HFLAG_BC: ++ case LARCH_HFLAG_B: ++ ctx->btarget = env->btarget; ++ break; ++ } ++} ++ ++static inline void generate_exception_err(DisasContext *ctx, int excp, int err) ++{ ++ TCGv_i32 texcp = tcg_const_i32(excp); ++ TCGv_i32 terr = tcg_const_i32(err); ++ save_cpu_state(ctx, 1); ++ gen_helper_raise_exception_err(cpu_env, texcp, terr); ++ tcg_temp_free_i32(terr); ++ tcg_temp_free_i32(texcp); ++ ctx->base.is_jmp = DISAS_NORETURN; ++} ++ ++static inline void generate_exception_end(DisasContext *ctx, int excp) ++{ ++ generate_exception_err(ctx, excp, 0); ++} ++ ++/* Floating point register moves. */ ++static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) ++{ ++ tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); ++} ++ ++static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) ++{ ++ TCGv_i64 t64; ++ t64 = tcg_temp_new_i64(); ++ tcg_gen_extu_i32_i64(t64, t); ++ tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); ++ tcg_temp_free_i64(t64); ++} ++ ++static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) ++{ ++ tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); ++} ++ ++static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) ++{ ++ TCGv_i64 t64 = tcg_temp_new_i64(); ++ tcg_gen_extu_i32_i64(t64, t); ++ tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); ++ tcg_temp_free_i64(t64); ++} ++ ++static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) ++{ ++ tcg_gen_mov_i64(t, fpu_f64[reg]); ++} ++ ++static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) ++{ ++ tcg_gen_mov_i64(fpu_f64[reg], t); ++} ++ ++static inline int get_fp_bit(int cc) ++{ ++ if (cc) { ++ return 24 + cc; ++ } else { ++ return 23; ++ } ++} ++ ++/* Addresses computation */ ++static inline void gen_op_addr_add(DisasContext *ctx, ++ TCGv ret, TCGv arg0, TCGv arg1) ++{ ++ tcg_gen_add_tl(ret, arg0, arg1); ++ ++ if (ctx->hflags & LARCH_HFLAG_AWRAP) { ++ tcg_gen_ext32s_i64(ret, ret); ++ } ++} ++ ++static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, ++ target_long ofs) ++{ ++ tcg_gen_addi_tl(ret, base, ofs); ++ ++ if (ctx->hflags & LARCH_HFLAG_AWRAP) { ++ tcg_gen_ext32s_i64(ret, ret); ++ } ++} ++ ++/* Sign-extract the low 32-bits to a target_long. */ ++static inline void gen_move_low32(TCGv ret, TCGv_i64 arg) ++{ ++ tcg_gen_ext32s_i64(ret, arg); ++} ++ ++/* Sign-extract the high 32-bits to a target_long. */ ++static inline void gen_move_high32(TCGv ret, TCGv_i64 arg) ++{ ++ tcg_gen_sari_i64(ret, arg, 32); ++} ++ ++static inline void check_cp1_enabled(DisasContext *ctx) ++{ ++#ifndef CONFIG_USER_ONLY ++ if (unlikely(!(ctx->hflags & LARCH_HFLAG_FPU))) { ++ generate_exception_err(ctx, EXCP_FPDIS, 1); ++ } ++#endif ++} ++ ++static inline void check_lsx_enabled(DisasContext *ctx) ++{ ++#ifndef CONFIG_USER_ONLY ++ if (unlikely(!(ctx->hflags & LARCH_HFLAG_LSX))) { ++ generate_exception_err(ctx, EXCP_LSXDIS, 1); ++ } ++#endif ++} ++ ++static inline void check_lasx_enabled(DisasContext *ctx) ++{ ++#ifndef CONFIG_USER_ONLY ++ if (unlikely(!(ctx->hflags & LARCH_HFLAG_LASX))) { ++ generate_exception_err(ctx, EXCP_LASXDIS, 1); ++ } ++#endif ++} ++ ++static inline void check_lbt_enabled(DisasContext *ctx) ++{ ++#ifndef CONFIG_USER_ONLY ++ if (unlikely(!(ctx->hflags & LARCH_HFLAG_LBT))) { ++ generate_exception_err(ctx, EXCP_BTDIS, 1); ++ } ++#endif ++} ++ ++/* This code generates a "reserved instruction" exception if the ++ CPU does not support the instruction set corresponding to flags. */ ++static inline void check_insn(DisasContext *ctx, uint64_t flags) ++{ ++ if (unlikely(!(ctx->insn_flags & flags))) { ++ generate_exception_end(ctx, EXCP_RI); ++ } ++} ++ ++/* This code generates a "reserved instruction" exception if the ++ CPU has corresponding flag set which indicates that the instruction ++ has been removed. */ ++static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) ++{ ++ if (unlikely(ctx->insn_flags & flags)) { ++ generate_exception_end(ctx, EXCP_RI); ++ } ++} ++ ++/* ++ * The Linux kernel traps certain reserved instruction exceptions to ++ * emulate the corresponding instructions. QEMU is the kernel in user ++ * mode, so those traps are emulated by accepting the instructions. ++ * ++ * A reserved instruction exception is generated for flagged CPUs if ++ * QEMU runs in system mode. ++ */ ++static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) ++{ ++#ifndef CONFIG_USER_ONLY ++ check_insn_opc_removed(ctx, flags); ++#endif ++} ++ ++/* This code generates a "reserved instruction" exception if 64-bit ++ instructions are not enabled. */ ++static inline void check_larch_64(DisasContext *ctx) ++{ ++ if (unlikely(!(ctx->hflags & LARCH_HFLAG_64))) { ++ generate_exception_end(ctx, EXCP_RI); ++ } ++} ++ ++/* Define small wrappers for gen_load_fpr* so that we have a uniform ++ calling interface for 32 and 64-bit FPRs. No sense in changing ++ all callers for gen_load_fpr32 when we need the CTX parameter for ++ this one use. */ ++#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) ++#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) ++#define FCOP_CONDNS(fmt, ifmt, bits, STORE) \ ++static inline void gen_fcmp_ ## fmt(DisasContext *ctx, int n, \ ++ int ft, int fs, int cd) \ ++{ \ ++ TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ ++ TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ ++ TCGv_i32 fcc = tcg_const_i32(cd); \ ++ check_cp1_enabled(ctx); \ ++ gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ ++ gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ ++ switch (n) { \ ++ case 0: \ ++ gen_helper_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 1: \ ++ gen_helper_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 2: \ ++ gen_helper_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 3: \ ++ gen_helper_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 4: \ ++ gen_helper_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 5: \ ++ gen_helper_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 6: \ ++ gen_helper_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 7: \ ++ gen_helper_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 8: \ ++ gen_helper_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 9: \ ++ gen_helper_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 10: \ ++ gen_helper_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 11: \ ++ gen_helper_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 12: \ ++ gen_helper_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 13: \ ++ gen_helper_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 14: \ ++ gen_helper_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 15: \ ++ gen_helper_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 16: \ ++ gen_helper_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 17: \ ++ gen_helper_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 20: \ ++ gen_helper_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 21: \ ++ gen_helper_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 24: \ ++ gen_helper_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ case 25: \ ++ gen_helper_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \ ++ break; \ ++ default: \ ++ abort(); \ ++ } \ ++ STORE; \ ++ tcg_temp_free_i ## bits(fp0); \ ++ tcg_temp_free_i ## bits(fp1); \ ++ tcg_temp_free_i32(fcc); \ ++} ++ ++FCOP_CONDNS(d, FMT_D, 64, gen_helper_movreg2cf_i64(cpu_env, fcc, fp0)) ++FCOP_CONDNS(s, FMT_S, 32, gen_helper_movreg2cf_i32(cpu_env, fcc, fp0)) ++#undef FCOP_CONDNS ++#undef gen_ldcmp_fpr32 ++#undef gen_ldcmp_fpr64 ++ ++/* load/store instructions. */ ++#ifdef CONFIG_USER_ONLY ++#define OP_LD_ATOMIC(insn, fname) \ ++static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ ++ DisasContext *ctx) \ ++{ \ ++ TCGv t0 = tcg_temp_new(); \ ++ tcg_gen_mov_tl(t0, arg1); \ ++ tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ ++ tcg_gen_st_tl(t0, cpu_env, \ ++ offsetof(CPULOONGARCHState, lladdr)); \ ++ tcg_gen_st_tl(ret, cpu_env, \ ++ offsetof(CPULOONGARCHState, llval)); \ ++ tcg_temp_free(t0); \ ++} ++#else ++#define OP_LD_ATOMIC(insn, fname) \ ++static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ ++ DisasContext *ctx) \ ++{ \ ++ gen_helper_1e1i(insn, ret, arg1, mem_idx); \ ++} ++#endif ++#if 0 ++OP_LD_ATOMIC(ll, ld32s); ++OP_LD_ATOMIC(lld, ld64); ++#endif ++#undef OP_LD_ATOMIC ++ ++static void gen_base_offset_addr(DisasContext *ctx, TCGv addr, ++ int base, int offset) ++{ ++ if (base == 0) { ++ tcg_gen_movi_tl(addr, offset); ++ } else if (offset == 0) { ++ gen_load_gpr(addr, base); ++ } else { ++ tcg_gen_movi_tl(addr, offset); ++ gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); ++ } ++} ++ ++/* Load */ ++static void gen_ld(DisasContext *ctx, uint32_t opc, ++ int rt, int base, int offset) ++{ ++ TCGv t0; ++ int mem_idx = ctx->mem_idx; ++ ++ t0 = tcg_temp_new(); ++ gen_base_offset_addr(ctx, t0, base, offset); ++ ++ switch (opc) { ++ case OPC_LARCH_LD_WU: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LDPTR_D: ++ case OPC_LARCH_LD_D: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LL_D: ++#if 0 ++ op_ld_lld(t0, t0, mem_idx, ctx); ++#endif ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LDPTR_W: ++ case OPC_LARCH_LD_W: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LD_H: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LD_HU: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW | ++ ctx->default_tcg_memop_mask); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LD_B: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LD_BU: ++ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_LL_W: ++#if 0 ++ op_ld_ll(t0, t0, mem_idx, ctx); ++#endif ++ gen_store_gpr(t0, rt); ++ break; ++ } ++ ++ tcg_temp_free(t0); ++} ++ ++/* Store */ ++static void gen_st(DisasContext *ctx, uint32_t opc, int rt, ++ int base, int offset) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ int mem_idx = ctx->mem_idx; ++ ++ gen_base_offset_addr(ctx, t0, base, offset); ++ gen_load_gpr(t1, rt); ++ ++ switch (opc) { ++ case OPC_LARCH_STPTR_D: ++ case OPC_LARCH_ST_D: ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ | ++ ctx->default_tcg_memop_mask); ++ break; ++ case OPC_LARCH_STPTR_W: ++ case OPC_LARCH_ST_W: ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | ++ ctx->default_tcg_memop_mask); ++ break; ++ case OPC_LARCH_ST_H: ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | ++ ctx->default_tcg_memop_mask); ++ break; ++ case OPC_LARCH_ST_B: ++ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); ++ break; ++ } ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++} ++ ++/* Store conditional */ ++static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, ++ MemOp tcg_mo, bool eva) ++{ ++ TCGv addr, t0, val; ++ TCGLabel *l1 = gen_new_label(); ++ TCGLabel *done = gen_new_label(); ++ ++ t0 = tcg_temp_new(); ++ addr = tcg_temp_new(); ++ /* compare the address against that of the preceeding LL */ ++ gen_base_offset_addr(ctx, addr, base, offset); ++ tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); ++ tcg_temp_free(addr); ++ tcg_gen_movi_tl(t0, 0); ++ gen_store_gpr(t0, rt); ++ tcg_gen_br(done); ++ ++ gen_set_label(l1); ++ /* generate cmpxchg */ ++ val = tcg_temp_new(); ++ gen_load_gpr(val, rt); ++ tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, ++ eva ? LARCH_HFLAG_UM : ctx->mem_idx, tcg_mo); ++ tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); ++ gen_store_gpr(t0, rt); ++ tcg_temp_free(val); ++ ++ gen_set_label(done); ++ tcg_temp_free(t0); ++} ++ ++/* Load and store */ ++static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, ++ TCGv t0) ++{ ++ /* Don't do NOP if destination is zero: we must perform the actual ++ memory access. */ ++ switch (opc) { ++ case OPC_LARCH_FLD_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | ++ ctx->default_tcg_memop_mask); ++ gen_store_fpr32(ctx, fp0, ft); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FST_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, ft); ++ tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | ++ ctx->default_tcg_memop_mask); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FLD_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ | ++ ctx->default_tcg_memop_mask); ++ gen_store_fpr64(ctx, fp0, ft); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FST_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, ft); ++ tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ | ++ ctx->default_tcg_memop_mask); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ default: ++ LARCH_INVAL("flt_ldst"); ++ generate_exception_end(ctx, EXCP_RI); ++ break; ++ } ++} ++ ++static void gen_fp_ldst(DisasContext *ctx, uint32_t op, int rt, ++ int rs, int16_t imm) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ check_cp1_enabled(ctx); ++ gen_base_offset_addr(ctx, t0, rs, imm); ++ gen_flt_ldst(ctx, op, rt, t0); ++ tcg_temp_free(t0); ++} ++ ++/* Arithmetic with immediate operand */ ++static void gen_arith_imm(DisasContext *ctx, uint32_t opc, ++ int rt, int rs, int imm) ++{ ++ target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ ++ ++ if (rt == 0) { ++ /* If no destination, treat it as a NOP. ++ For addi, we must generate the overflow exception when needed. */ ++ return; ++ } ++ switch (opc) { ++ case OPC_LARCH_ADDI_W: ++ if (rs != 0) { ++ tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); ++ tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rt], uimm); ++ } ++ break; ++ case OPC_LARCH_ADDI_D: ++ if (rs != 0) { ++ tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rt], uimm); ++ } ++ break; ++ } ++} ++ ++/* Logic with immediate operand */ ++static void gen_logic_imm(DisasContext *ctx, uint32_t opc, ++ int rt, int rs, int16_t imm) ++{ ++ target_ulong uimm; ++ ++ if (rt == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ uimm = (uint16_t)imm; ++ switch (opc) { ++ case OPC_LARCH_ANDI: ++ if (likely(rs != 0)) { ++ tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rt], 0); ++ } ++ break; ++ case OPC_LARCH_ORI: ++ if (rs != 0) { ++ tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rt], uimm); ++ } ++ break; ++ case OPC_LARCH_XORI: ++ if (likely(rs != 0)) { ++ tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rt], uimm); ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++/* Set on less than with immediate operand */ ++static void gen_slt_imm(DisasContext *ctx, uint32_t opc, ++ int rt, int rs, int16_t imm) ++{ ++ target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ ++ TCGv t0; ++ ++ if (rt == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, rs); ++ switch (opc) { ++ case OPC_LARCH_SLTI: ++ tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); ++ break; ++ case OPC_LARCH_SLTIU: ++ tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); ++ break; ++ } ++ tcg_temp_free(t0); ++} ++ ++/* Shifts with immediate operand */ ++static void gen_shift_imm(DisasContext *ctx, uint32_t opc, ++ int rt, int rs, int16_t imm) ++{ ++ target_ulong uimm = ((uint16_t)imm) & 0x1f; ++ TCGv t0; ++ ++ if (rt == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, rs); ++ switch (opc) { ++ case OPC_LARCH_SRAI_W: ++ tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); ++ break; ++ case OPC_LARCH_SRLI_W: ++ if (uimm != 0) { ++ tcg_gen_ext32u_tl(t0, t0); ++ tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); ++ } else { ++ tcg_gen_ext32s_tl(cpu_gpr[rt], t0); ++ } ++ break; ++ case OPC_LARCH_ROTRI_W: ++ if (uimm != 0) { ++ TCGv_i32 t1 = tcg_temp_new_i32(); ++ ++ tcg_gen_trunc_tl_i32(t1, t0); ++ tcg_gen_rotri_i32(t1, t1, uimm); ++ tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); ++ tcg_temp_free_i32(t1); ++ } else { ++ tcg_gen_ext32s_tl(cpu_gpr[rt], t0); ++ } ++ break; ++ } ++ tcg_temp_free(t0); ++} ++ ++/* Arithmetic */ ++static void gen_arith(DisasContext *ctx, uint32_t opc, ++ int rd, int rs, int rt) ++{ ++ if (rd == 0) { ++ /* If no destination, treat it as a NOP. ++ For add & sub, we must generate the ++ overflow exception when needed. */ ++ return; ++ } ++ ++ switch (opc) { ++ case OPC_LARCH_ADD_W: ++ if (rs != 0 && rt != 0) { ++ tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ case OPC_LARCH_SUB_W: ++ if (rs != 0 && rt != 0) { ++ tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ case OPC_LARCH_ADD_D: ++ if (rs != 0 && rt != 0) { ++ tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ case OPC_LARCH_SUB_D: ++ if (rs != 0 && rt != 0) { ++ tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ } ++} ++ ++/* Conditional move */ ++static void gen_cond_move(DisasContext *ctx, uint32_t opc, ++ int rd, int rs, int rt) ++{ ++ TCGv t0, t1, t2; ++ ++ if (rd == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, rt); ++ t1 = tcg_const_tl(0); ++ t2 = tcg_temp_new(); ++ gen_load_gpr(t2, rs); ++ switch (opc) { ++ case OPC_LARCH_MASKEQZ: ++ tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); ++ break; ++ case OPC_LARCH_MASKNEZ: ++ tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); ++ break; ++ } ++ tcg_temp_free(t2); ++ tcg_temp_free(t1); ++ tcg_temp_free(t0); ++} ++ ++/* Logic */ ++static void gen_logic(DisasContext *ctx, uint32_t opc, ++ int rd, int rs, int rt) ++{ ++ if (rd == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ ++ switch (opc) { ++ case OPC_LARCH_AND: ++ if (likely(rs != 0 && rt != 0)) { ++ tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ case OPC_LARCH_NOR: ++ if (rs != 0 && rt != 0) { ++ tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); ++ } ++ break; ++ case OPC_LARCH_OR: ++ if (likely(rs != 0 && rt != 0)) { ++ tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ case OPC_LARCH_XOR: ++ if (likely(rs != 0 && rt != 0)) { ++ tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); ++ } else if (rs == 0 && rt != 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); ++ } else if (rs != 0 && rt == 0) { ++ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); ++ } else { ++ tcg_gen_movi_tl(cpu_gpr[rd], 0); ++ } ++ break; ++ } ++} ++ ++/* Set on lower than */ ++static void gen_slt(DisasContext *ctx, uint32_t opc, ++ int rd, int rs, int rt) ++{ ++ TCGv t0, t1; ++ ++ if (rd == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ gen_load_gpr(t0, rs); ++ gen_load_gpr(t1, rt); ++ switch (opc) { ++ case OPC_LARCH_SLT: ++ tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); ++ break; ++ case OPC_LARCH_SLTU: ++ tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); ++ break; ++ } ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++} ++ ++/* Shifts */ ++static void gen_shift(DisasContext *ctx, uint32_t opc, ++ int rd, int rs, int rt) ++{ ++ TCGv t0, t1; ++ ++ if (rd == 0) { ++ /* If no destination, treat it as a NOP. ++ For add & sub, we must generate the ++ overflow exception when needed. */ ++ return; ++ } ++ ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ gen_load_gpr(t0, rs); ++ gen_load_gpr(t1, rt); ++ switch (opc) { ++ case OPC_LARCH_SLL_W: ++ tcg_gen_andi_tl(t0, t0, 0x1f); ++ tcg_gen_shl_tl(t0, t1, t0); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); ++ break; ++ case OPC_LARCH_SRA_W: ++ tcg_gen_andi_tl(t0, t0, 0x1f); ++ tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); ++ break; ++ case OPC_LARCH_SRL_W: ++ tcg_gen_ext32u_tl(t1, t1); ++ tcg_gen_andi_tl(t0, t0, 0x1f); ++ tcg_gen_shr_tl(t0, t1, t0); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); ++ break; ++ case OPC_LARCH_ROTR_W: ++ { ++ TCGv_i32 t2 = tcg_temp_new_i32(); ++ TCGv_i32 t3 = tcg_temp_new_i32(); ++ ++ tcg_gen_trunc_tl_i32(t2, t0); ++ tcg_gen_trunc_tl_i32(t3, t1); ++ tcg_gen_andi_i32(t2, t2, 0x1f); ++ tcg_gen_rotr_i32(t2, t3, t2); ++ tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); ++ tcg_temp_free_i32(t2); ++ tcg_temp_free_i32(t3); ++ } ++ break; ++ case OPC_LARCH_SLL_D: ++ tcg_gen_andi_tl(t0, t0, 0x3f); ++ tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); ++ break; ++ case OPC_LARCH_SRA_D: ++ tcg_gen_andi_tl(t0, t0, 0x3f); ++ tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); ++ break; ++ case OPC_LARCH_SRL_D: ++ tcg_gen_andi_tl(t0, t0, 0x3f); ++ tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); ++ break; ++ case OPC_LARCH_ROTR_D: ++ tcg_gen_andi_tl(t0, t0, 0x3f); ++ tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); ++ break; ++ } ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++} ++ ++static inline void gen_r6_ld(target_long addr, int reg, int memidx, ++ MemOp memop) ++{ ++ TCGv t0 = tcg_const_tl(addr); ++ tcg_gen_qemu_ld_tl(t0, t0, memidx, memop); ++ gen_store_gpr(t0, reg); ++ tcg_temp_free(t0); ++} ++ ++static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) ++{ ++ TCGv t0, t1; ++ ++ if (rd == 0) { ++ /* Treat as NOP. */ ++ return; ++ } ++ ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, rs); ++ gen_load_gpr(t1, rt); ++ ++ switch (opc) { ++ case OPC_LARCH_DIV_W: ++ { ++ TCGv t2 = tcg_temp_new(); ++ TCGv t3 = tcg_temp_new(); ++ tcg_gen_ext32s_tl(t0, t0); ++ tcg_gen_ext32s_tl(t1, t1); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); ++ tcg_gen_and_tl(t2, t2, t3); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); ++ tcg_gen_or_tl(t2, t2, t3); ++ tcg_gen_movi_tl(t3, 0); ++ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); ++ tcg_gen_div_tl(cpu_gpr[rd], t0, t1); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MOD_W: ++ { ++ TCGv t2 = tcg_temp_new(); ++ TCGv t3 = tcg_temp_new(); ++ tcg_gen_ext32s_tl(t0, t0); ++ tcg_gen_ext32s_tl(t1, t1); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); ++ tcg_gen_and_tl(t2, t2, t3); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); ++ tcg_gen_or_tl(t2, t2, t3); ++ tcg_gen_movi_tl(t3, 0); ++ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); ++ tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_DIV_WU: ++ { ++ TCGv t2 = tcg_const_tl(0); ++ TCGv t3 = tcg_const_tl(1); ++ tcg_gen_ext32u_tl(t0, t0); ++ tcg_gen_ext32u_tl(t1, t1); ++ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); ++ tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MOD_WU: ++ { ++ TCGv t2 = tcg_const_tl(0); ++ TCGv t3 = tcg_const_tl(1); ++ tcg_gen_ext32u_tl(t0, t0); ++ tcg_gen_ext32u_tl(t1, t1); ++ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); ++ tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MUL_W: ++ { ++ TCGv_i32 t2 = tcg_temp_new_i32(); ++ TCGv_i32 t3 = tcg_temp_new_i32(); ++ tcg_gen_trunc_tl_i32(t2, t0); ++ tcg_gen_trunc_tl_i32(t3, t1); ++ tcg_gen_mul_i32(t2, t2, t3); ++ tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); ++ tcg_temp_free_i32(t2); ++ tcg_temp_free_i32(t3); ++ } ++ break; ++ case OPC_LARCH_MULH_W: ++ { ++ TCGv_i32 t2 = tcg_temp_new_i32(); ++ TCGv_i32 t3 = tcg_temp_new_i32(); ++ tcg_gen_trunc_tl_i32(t2, t0); ++ tcg_gen_trunc_tl_i32(t3, t1); ++ tcg_gen_muls2_i32(t2, t3, t2, t3); ++ tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); ++ tcg_temp_free_i32(t2); ++ tcg_temp_free_i32(t3); ++ } ++ break; ++ case OPC_LARCH_MULH_WU: ++ { ++ TCGv_i32 t2 = tcg_temp_new_i32(); ++ TCGv_i32 t3 = tcg_temp_new_i32(); ++ tcg_gen_trunc_tl_i32(t2, t0); ++ tcg_gen_trunc_tl_i32(t3, t1); ++ tcg_gen_mulu2_i32(t2, t3, t2, t3); ++ tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); ++ tcg_temp_free_i32(t2); ++ tcg_temp_free_i32(t3); ++ } ++ break; ++ case OPC_LARCH_DIV_D: ++ { ++ TCGv t2 = tcg_temp_new(); ++ TCGv t3 = tcg_temp_new(); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); ++ tcg_gen_and_tl(t2, t2, t3); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); ++ tcg_gen_or_tl(t2, t2, t3); ++ tcg_gen_movi_tl(t3, 0); ++ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); ++ tcg_gen_div_tl(cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MOD_D: ++ { ++ TCGv t2 = tcg_temp_new(); ++ TCGv t3 = tcg_temp_new(); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); ++ tcg_gen_and_tl(t2, t2, t3); ++ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); ++ tcg_gen_or_tl(t2, t2, t3); ++ tcg_gen_movi_tl(t3, 0); ++ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); ++ tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_DIV_DU: ++ { ++ TCGv t2 = tcg_const_tl(0); ++ TCGv t3 = tcg_const_tl(1); ++ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); ++ tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MOD_DU: ++ { ++ TCGv t2 = tcg_const_tl(0); ++ TCGv t3 = tcg_const_tl(1); ++ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); ++ tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t3); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MUL_D: ++ tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); ++ break; ++ case OPC_LARCH_MULH_D: ++ { ++ TCGv t2 = tcg_temp_new(); ++ tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t2); ++ } ++ break; ++ case OPC_LARCH_MULH_DU: ++ { ++ TCGv t2 = tcg_temp_new(); ++ tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t2); ++ } ++ break; ++ default: ++ LARCH_INVAL("r6 mul/div"); ++ generate_exception_end(ctx, EXCP_RI); ++ goto out; ++ } ++ out: ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++} ++ ++static void gen_cl(DisasContext *ctx, uint32_t opc, ++ int rd, int rs) ++{ ++ TCGv t0; ++ ++ if (rd == 0) { ++ /* Treat as NOP. */ ++ return; ++ } ++ t0 = cpu_gpr[rd]; ++ gen_load_gpr(t0, rs); ++ ++ switch (opc) { ++ case OPC_LARCH_CLO_W: ++ case OPC_LARCH_CLO_D: ++ tcg_gen_not_tl(t0, t0); ++ break; ++ } ++ ++ switch (opc) { ++ case OPC_LARCH_CLO_W: ++ case OPC_LARCH_CLZ_W: ++ tcg_gen_ext32u_tl(t0, t0); ++ tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); ++ tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); ++ break; ++ case OPC_LARCH_CLO_D: ++ case OPC_LARCH_CLZ_D: ++ tcg_gen_clzi_i64(t0, t0, 64); ++ break; ++ } ++} ++ ++static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) ++{ ++ if (unlikely(ctx->base.singlestep_enabled)) { ++ return false; ++ } ++ ++#ifndef CONFIG_USER_ONLY ++ return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); ++#else ++ return true; ++#endif ++} ++ ++static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) ++{ ++ if (use_goto_tb(ctx, dest)) { ++ tcg_gen_goto_tb(n); ++ gen_save_pc(dest); ++ tcg_gen_exit_tb(ctx->base.tb, n); ++ } else { ++ gen_save_pc(dest); ++ if (ctx->base.singlestep_enabled) { ++ save_cpu_state(ctx, 0); ++ gen_helper_raise_exception_debug(cpu_env); ++ } ++ tcg_gen_lookup_and_goto_ptr(); ++ } ++} ++ ++/* Branches */ ++static void gen_compute_branch(DisasContext *ctx, uint32_t opc, ++ int insn_bytes, ++ int rs, int rt, int32_t offset) ++{ ++ target_ulong btgt = -1; ++ int bcond_compute = 0; ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ ++ if (ctx->hflags & LARCH_HFLAG_BMASK) { ++#ifdef LARCH_DEBUG_DISAS ++ LOG_DISAS("Branch at PC 0x" ++ TARGET_FMT_lx "\n", ctx->base.pc_next); ++#endif ++ generate_exception_end(ctx, EXCP_RI); ++ goto out; ++ } ++ ++ /* Load needed operands */ ++ switch (opc) { ++ case OPC_LARCH_BLT: ++ case OPC_LARCH_BGE: ++ case OPC_LARCH_BLTU: ++ case OPC_LARCH_BGEU: ++ gen_load_gpr(t0, rs); ++ gen_load_gpr(t1, rt); ++ bcond_compute = 1; ++ btgt = ctx->base.pc_next + offset; ++ break; ++ case OPC_LARCH_BEQZ: ++ case OPC_LARCH_B: ++ case OPC_LARCH_BEQ: ++ case OPC_LARCH_BNEZ: ++ case OPC_LARCH_BNE: ++ /* Compare two registers */ ++ if (rs != rt) { ++ gen_load_gpr(t0, rs); ++ gen_load_gpr(t1, rt); ++ bcond_compute = 1; ++ } ++ btgt = ctx->base.pc_next + offset; ++ break; ++ default: ++ LARCH_INVAL("branch/jump"); ++ generate_exception_end(ctx, EXCP_RI); ++ goto out; ++ } ++ if (bcond_compute == 0) { ++ /* No condition to be computed */ ++ switch (opc) { ++ case OPC_LARCH_BEQZ: /* rx == rx */ ++ case OPC_LARCH_B: ++ case OPC_LARCH_BEQ: ++ /* Always take */ ++ ctx->hflags |= LARCH_HFLAG_B; ++ break; ++ case OPC_LARCH_BNEZ: ++ case OPC_LARCH_BNE: ++ /* Treat as NOP. */ ++ goto out; ++ default: ++ LARCH_INVAL("branch/jump"); ++ generate_exception_end(ctx, EXCP_RI); ++ goto out; ++ } ++ } else { ++ switch (opc) { ++ case OPC_LARCH_BLT: ++ tcg_gen_setcond_tl(TCG_COND_LT, bcond, t0, t1); ++ goto not_likely; ++ case OPC_LARCH_BGE: ++ tcg_gen_setcond_tl(TCG_COND_GE, bcond, t0, t1); ++ goto not_likely; ++ case OPC_LARCH_BLTU: ++ tcg_gen_setcond_tl(TCG_COND_LTU, bcond, t0, t1); ++ goto not_likely; ++ case OPC_LARCH_BGEU: ++ tcg_gen_setcond_tl(TCG_COND_GEU, bcond, t0, t1); ++ goto not_likely; ++ case OPC_LARCH_BEQZ: ++ case OPC_LARCH_B: ++ case OPC_LARCH_BEQ: ++ tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); ++ goto not_likely; ++ case OPC_LARCH_BNEZ: ++ case OPC_LARCH_BNE: ++ tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); ++ goto not_likely; ++ not_likely: ++ ctx->hflags |= LARCH_HFLAG_BC; ++ break; ++ default: ++ LARCH_INVAL("conditional branch/jump"); ++ generate_exception_end(ctx, EXCP_RI); ++ goto out; ++ } ++ } ++ ++ ctx->btarget = btgt; ++ ++ out: ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++} ++ ++/* special3 bitfield operations */ ++static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, ++ int rs, int lsb, int msb) ++{ ++ TCGv t0 = tcg_temp_new(); ++ TCGv t1 = tcg_temp_new(); ++ ++ gen_load_gpr(t1, rs); ++ switch (opc) { ++ case OPC_LARCH_TRPICK_W: ++ if (lsb + msb > 31) { ++ goto fail; ++ } ++ if (msb != 31) { ++ tcg_gen_extract_tl(t0, t1, lsb, msb + 1); ++ } else { ++ /* ++ * The two checks together imply that lsb == 0, ++ * so this is a simple sign-extension. ++ */ ++ tcg_gen_ext32s_tl(t0, t1); ++ } ++ break; ++ case OPC_LARCH_TRINS_W: ++ if (lsb > msb) { ++ goto fail; ++ } ++ gen_load_gpr(t0, rt); ++ tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); ++ tcg_gen_ext32s_tl(t0, t0); ++ break; ++ default: ++fail: ++ LARCH_INVAL("bitops"); ++ generate_exception_end(ctx, EXCP_RI); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ return; ++ } ++ gen_store_gpr(t0, rt); ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++} ++ ++static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) ++{ ++ TCGv t0; ++ ++ if (rd == 0) { ++ /* If no destination, treat it as a NOP. */ ++ return; ++ } ++ ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, rt); ++ switch (op2) { ++ case OPC_LARCH_REVB_2H: ++ { ++ TCGv t1 = tcg_temp_new(); ++ TCGv t2 = tcg_const_tl(0x00FF00FF); ++ ++ tcg_gen_shri_tl(t1, t0, 8); ++ tcg_gen_and_tl(t1, t1, t2); ++ tcg_gen_and_tl(t0, t0, t2); ++ tcg_gen_shli_tl(t0, t0, 8); ++ tcg_gen_or_tl(t0, t0, t1); ++ tcg_temp_free(t2); ++ tcg_temp_free(t1); ++ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); ++ } ++ break; ++ case OPC_LARCH_EXT_WB: ++ tcg_gen_ext8s_tl(cpu_gpr[rd], t0); ++ break; ++ case OPC_LARCH_EXT_WH: ++ tcg_gen_ext16s_tl(cpu_gpr[rd], t0); ++ break; ++ case OPC_LARCH_REVB_4H: ++ { ++ TCGv t1 = tcg_temp_new(); ++ TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL); ++ ++ tcg_gen_shri_tl(t1, t0, 8); ++ tcg_gen_and_tl(t1, t1, t2); ++ tcg_gen_and_tl(t0, t0, t2); ++ tcg_gen_shli_tl(t0, t0, 8); ++ tcg_gen_or_tl(cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t2); ++ tcg_temp_free(t1); ++ } ++ break; ++ case OPC_LARCH_REVH_D: ++ { ++ TCGv t1 = tcg_temp_new(); ++ TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL); ++ ++ tcg_gen_shri_tl(t1, t0, 16); ++ tcg_gen_and_tl(t1, t1, t2); ++ tcg_gen_and_tl(t0, t0, t2); ++ tcg_gen_shli_tl(t0, t0, 16); ++ tcg_gen_or_tl(t0, t0, t1); ++ tcg_gen_shri_tl(t1, t0, 32); ++ tcg_gen_shli_tl(t0, t0, 32); ++ tcg_gen_or_tl(cpu_gpr[rd], t0, t1); ++ tcg_temp_free(t2); ++ tcg_temp_free(t1); ++ } ++ break; ++ default: ++ LARCH_INVAL("bsfhl"); ++ generate_exception_end(ctx, EXCP_RI); ++ tcg_temp_free(t0); ++ return; ++ } ++ tcg_temp_free(t0); ++} ++ ++/* REV with sf==1, opcode==3 ("REV64") */ ++static void handle_rev64(DisasContext *ctx, ++ unsigned int rn, unsigned int rd) ++{ ++ tcg_gen_bswap64_i64(cpu_gpr[rd], cpu_gpr[rn]); ++} ++ ++/* REV with sf==0, opcode==2 ++ * REV32 (sf==1, opcode==2) ++ */ ++static void handle_rev32(DisasContext *ctx, ++ unsigned int rn, unsigned int rd) ++{ ++ TCGv_i64 tcg_rd = tcg_temp_new_i64(); ++ gen_load_gpr(tcg_rd, rd); ++ ++ TCGv_i64 tcg_tmp = tcg_temp_new_i64(); ++ TCGv_i64 tcg_rn = tcg_temp_new_i64(); ++ gen_load_gpr(tcg_rn, rn); ++ ++ /* bswap32_i64 requires zero high word */ ++ tcg_gen_ext32u_i64(tcg_tmp, tcg_rn); ++ tcg_gen_bswap32_i64(tcg_rd, tcg_tmp, TCG_BSWAP_OZ); ++ tcg_gen_shri_i64(tcg_tmp, tcg_rn, 32); ++ tcg_gen_bswap32_i64(tcg_tmp, tcg_tmp, TCG_BSWAP_OZ); ++ tcg_gen_concat32_i64(cpu_gpr[rd], tcg_rd, tcg_tmp); ++ ++ tcg_temp_free_i64(tcg_tmp); ++ tcg_temp_free_i64(tcg_rd); ++ tcg_temp_free_i64(tcg_rn); ++} ++ ++/* REV16 */ ++static void handle_rev16(DisasContext *ctx, unsigned int rn, unsigned int rd) ++{ ++ TCGv_i64 tcg_rd = tcg_temp_new_i64(); ++ TCGv_i64 tcg_rn = tcg_temp_new_i64(); ++ gen_load_gpr(tcg_rd, rd); ++ gen_load_gpr(tcg_rn, rn); ++ TCGv_i64 tcg_tmp = tcg_temp_new_i64(); ++ TCGv_i64 mask = tcg_const_i64(0x0000ffff0000ffffull); ++ ++ tcg_gen_shri_i64(tcg_tmp, tcg_rn, 16); ++ tcg_gen_and_i64(tcg_rd, tcg_rn, mask); ++ tcg_gen_and_i64(tcg_tmp, tcg_tmp, mask); ++ tcg_gen_shli_i64(tcg_rd, tcg_rd, 16); ++ tcg_gen_or_i64(cpu_gpr[rd], tcg_rd, tcg_tmp); ++ ++ tcg_temp_free_i64(mask); ++ tcg_temp_free_i64(tcg_tmp); ++ tcg_temp_free_i64(tcg_rd); ++ tcg_temp_free_i64(tcg_rn); ++} ++ ++static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt, ++ int imm2) ++{ ++ TCGv t0; ++ TCGv t1; ++ if (rd == 0) { ++ /* Treat as NOP. */ ++ return; ++ } ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ gen_load_gpr(t0, rs); ++ gen_load_gpr(t1, rt); ++ tcg_gen_shli_tl(t0, t0, imm2 + 1); ++ tcg_gen_add_tl(cpu_gpr[rd], t0, t1); ++ if (opc == OPC_LARCH_ALSL_W) { ++ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); ++ } ++ ++ tcg_temp_free(t1); ++ tcg_temp_free(t0); ++ ++ return; ++} ++ ++static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, ++ int rt, int bits) ++{ ++ TCGv t0; ++ if (rd == 0) { ++ /* Treat as NOP. */ ++ return; ++ } ++ t0 = tcg_temp_new(); ++ if (bits == 0 || bits == wordsz) { ++ if (bits == 0) { ++ gen_load_gpr(t0, rt); ++ } else { ++ gen_load_gpr(t0, rs); ++ } ++ switch (wordsz) { ++ case 32: ++ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); ++ break; ++ case 64: ++ tcg_gen_mov_tl(cpu_gpr[rd], t0); ++ break; ++ } ++ } else { ++ TCGv t1 = tcg_temp_new(); ++ gen_load_gpr(t0, rt); ++ gen_load_gpr(t1, rs); ++ switch (wordsz) { ++ case 32: ++ { ++ TCGv_i64 t2 = tcg_temp_new_i64(); ++ tcg_gen_concat_tl_i64(t2, t1, t0); ++ tcg_gen_shri_i64(t2, t2, 32 - bits); ++ gen_move_low32(cpu_gpr[rd], t2); ++ tcg_temp_free_i64(t2); ++ } ++ break; ++ case 64: ++ tcg_gen_shli_tl(t0, t0, bits); ++ tcg_gen_shri_tl(t1, t1, 64 - bits); ++ tcg_gen_or_tl(cpu_gpr[rd], t1, t0); ++ break; ++ } ++ tcg_temp_free(t1); ++ } ++ ++ tcg_temp_free(t0); ++} ++ ++static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, ++ int bp) ++{ ++ gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); ++} ++ ++static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) ++{ ++ TCGv t0; ++ if (rd == 0) { ++ /* Treat as NOP. */ ++ return; ++ } ++ t0 = tcg_temp_new(); ++ gen_load_gpr(t0, rt); ++ switch (opc) { ++ case OPC_LARCH_BREV_4B: ++ gen_helper_bitswap(cpu_gpr[rd], t0); ++ break; ++ case OPC_LARCH_BREV_8B: ++ gen_helper_dbitswap(cpu_gpr[rd], t0); ++ break; ++ } ++ tcg_temp_free(t0); ++} ++ ++static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) ++{ ++ TCGv t0 = tcg_temp_new(); ++ check_cp1_enabled(ctx); ++ ++ switch (opc) { ++ case OPC_LARCH_FR2GR_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ tcg_gen_ext_i32_tl(t0, fp0); ++ tcg_temp_free_i32(fp0); ++ } ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_GR2FR_W: ++ gen_load_gpr(t0, rt); ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ tcg_gen_trunc_tl_i32(fp0, t0); ++ gen_store_fpr32(ctx, fp0, fs); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FR2GR_D: ++ gen_load_fpr64(ctx, t0, fs); ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_GR2FR_D: ++ gen_load_gpr(t0, rt); ++ gen_store_fpr64(ctx, t0, fs); ++ break; ++ case OPC_LARCH_FRH2GR_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32h(ctx, fp0, fs); ++ tcg_gen_ext_i32_tl(t0, fp0); ++ tcg_temp_free_i32(fp0); ++ } ++ gen_store_gpr(t0, rt); ++ break; ++ case OPC_LARCH_GR2FRH_W: ++ gen_load_gpr(t0, rt); ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ tcg_gen_trunc_tl_i32(fp0, t0); ++ gen_store_fpr32h(ctx, fp0, fs); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ default: ++ LARCH_INVAL("cp1 move"); ++ generate_exception_end(ctx, EXCP_RI); ++ goto out; ++ } ++ ++ out: ++ tcg_temp_free(t0); ++} ++ ++static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, ++ int cc, int tf) ++{ ++ int cond; ++ TCGv_i32 t0 = tcg_temp_new_i32(); ++ TCGLabel *l1 = gen_new_label(); ++ TCGLabel *l2 = gen_new_label(); ++ ++ if (tf) { ++ cond = TCG_COND_EQ; ++ } else { ++ cond = TCG_COND_NE; ++ } ++ ++ tcg_gen_andi_i32(t0, fpu_fcsr0, 1 << get_fp_bit(cc)); ++ tcg_gen_brcondi_i32(cond, t0, 0, l1); ++ gen_load_fpr32(ctx, t0, fs); ++ gen_store_fpr32(ctx, t0, fd); ++ gen_set_label(l1); ++ ++ tcg_gen_andi_i32(t0, fpu_fcsr0, 1 << get_fp_bit(cc + 1)); ++ tcg_gen_brcondi_i32(cond, t0, 0, l2); ++ gen_load_fpr32h(ctx, t0, fs); ++ gen_store_fpr32h(ctx, t0, fd); ++ tcg_temp_free_i32(t0); ++ gen_set_label(l2); ++} ++ ++static void gen_farith(DisasContext *ctx, uint32_t opc, ++ int ft, int fs, int fd, int cc) ++{ ++ check_cp1_enabled(ctx); ++ switch (opc) { ++ case OPC_LARCH_FADD_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i32(fp1); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FSUB_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i32(fp1); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FMUL_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i32(fp1); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FDIV_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i32(fp1); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FSQRT_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_sqrt_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FABS_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_abs_s(fp0, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FMOV_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FNEG_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_chs_s(fp0, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRNE_L_S: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_round_l_s(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FTINTRZ_L_S: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_trunc_l_s(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FTINTRP_L_S: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_ceil_l_s(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FTINTRM_L_S: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_floor_l_s(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FTINTRNE_W_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_round_w_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRZ_W_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_trunc_w_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRP_W_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_ceil_w_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRM_W_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_floor_w_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FRECIP_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_recip_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FRSQRT_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FRINT_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_rint_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FCLASS_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_class_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FMIN_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ TCGv_i32 fp2 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_min_s(fp2, cpu_env, fp0, fp1); ++ gen_store_fpr32(ctx, fp2, fd); ++ tcg_temp_free_i32(fp2); ++ tcg_temp_free_i32(fp1); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FMINA_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ TCGv_i32 fp2 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1); ++ gen_store_fpr32(ctx, fp2, fd); ++ tcg_temp_free_i32(fp2); ++ tcg_temp_free_i32(fp1); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FMAX_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_max_s(fp1, cpu_env, fp0, fp1); ++ gen_store_fpr32(ctx, fp1, fd); ++ tcg_temp_free_i32(fp1); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FMAXA_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ TCGv_i32 fp1 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_load_fpr32(ctx, fp1, ft); ++ gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1); ++ gen_store_fpr32(ctx, fp1, fd); ++ tcg_temp_free_i32(fp1); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FCVT_D_S: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_cvtd_s(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FTINT_W_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_cvt_w_s(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINT_L_S: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_cvt_l_s(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FADD_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i64(fp1); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FSUB_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i64(fp1); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FMUL_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i64(fp1); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FDIV_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); ++ tcg_temp_free_i64(fp1); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FSQRT_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_sqrt_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FABS_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_abs_d(fp0, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FMOV_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FNEG_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_chs_d(fp0, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRNE_L_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_round_l_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRZ_L_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_trunc_l_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRP_L_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_ceil_l_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRM_L_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_floor_l_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FTINTRNE_W_D: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_round_w_d(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FTINTRZ_W_D: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_trunc_w_d(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FTINTRP_W_D: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_ceil_w_d(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FTINTRM_W_D: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_floor_w_d(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FRECIP_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_recip_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FRSQRT_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FRINT_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_rint_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FCLASS_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_class_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FMIN_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_min_d(fp1, cpu_env, fp0, fp1); ++ gen_store_fpr64(ctx, fp1, fd); ++ tcg_temp_free_i64(fp1); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FMINA_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1); ++ gen_store_fpr64(ctx, fp1, fd); ++ tcg_temp_free_i64(fp1); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FMAX_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_max_d(fp1, cpu_env, fp0, fp1); ++ gen_store_fpr64(ctx, fp1, fd); ++ tcg_temp_free_i64(fp1); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FMAXA_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ TCGv_i64 fp1 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_load_fpr64(ctx, fp1, ft); ++ gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1); ++ gen_store_fpr64(ctx, fp1, fd); ++ tcg_temp_free_i64(fp1); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FCVT_S_D: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_cvts_d(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FTINT_W_D: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_cvt_w_d(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FTINT_L_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_cvt_l_d(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FFINT_S_W: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ gen_load_fpr32(ctx, fp0, fs); ++ gen_helper_float_cvts_w(fp0, cpu_env, fp0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FFINT_D_W: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr32(ctx, fp32, fs); ++ gen_helper_float_cvtd_w(fp64, cpu_env, fp32); ++ tcg_temp_free_i32(fp32); ++ gen_store_fpr64(ctx, fp64, fd); ++ tcg_temp_free_i64(fp64); ++ } ++ break; ++ case OPC_LARCH_FFINT_S_L: ++ { ++ TCGv_i32 fp32 = tcg_temp_new_i32(); ++ TCGv_i64 fp64 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp64, fs); ++ gen_helper_float_cvts_l(fp32, cpu_env, fp64); ++ tcg_temp_free_i64(fp64); ++ gen_store_fpr32(ctx, fp32, fd); ++ tcg_temp_free_i32(fp32); ++ } ++ break; ++ case OPC_LARCH_FFINT_D_L: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ ++ gen_load_fpr64(ctx, fp0, fs); ++ gen_helper_float_cvtd_l(fp0, cpu_env, fp0); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ default: ++ LARCH_INVAL("farith"); ++ generate_exception_end(ctx, EXCP_RI); ++ return; ++ } ++} ++ ++/* Coprocessor 3 (FPU) */ ++static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, ++ int fd, int fs, int base, int index) ++{ ++ TCGv t0 = tcg_temp_new(); ++ ++ check_cp1_enabled(ctx); ++ if (base == 0) { ++ gen_load_gpr(t0, index); ++ } else if (index == 0) { ++ gen_load_gpr(t0, base); ++ } else { ++ gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); ++ } ++ ++ /* ++ * Don't do NOP if destination is zero: we must perform the actual ++ * memory access. ++ */ ++ switch (opc) { ++ case OPC_LARCH_FLDX_S: ++ case OPC_LARCH_FLDGT_S: ++ case OPC_LARCH_FLDLE_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ ++ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); ++ tcg_gen_trunc_tl_i32(fp0, t0); ++ gen_store_fpr32(ctx, fp0, fd); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FLDX_D: ++ case OPC_LARCH_FLDGT_D: ++ case OPC_LARCH_FLDLE_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); ++ gen_store_fpr64(ctx, fp0, fd); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ case OPC_LARCH_FSTX_S: ++ case OPC_LARCH_FSTGT_S: ++ case OPC_LARCH_FSTLE_S: ++ { ++ TCGv_i32 fp0 = tcg_temp_new_i32(); ++ gen_load_fpr32(ctx, fp0, fs); ++ tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); ++ tcg_temp_free_i32(fp0); ++ } ++ break; ++ case OPC_LARCH_FSTX_D: ++ case OPC_LARCH_FSTGT_D: ++ case OPC_LARCH_FSTLE_D: ++ { ++ TCGv_i64 fp0 = tcg_temp_new_i64(); ++ gen_load_fpr64(ctx, fp0, fs); ++ tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); ++ tcg_temp_free_i64(fp0); ++ } ++ break; ++ } ++ tcg_temp_free(t0); ++} ++ ++static inline void clear_branch_hflags(DisasContext *ctx) ++{ ++ ctx->hflags &= ~LARCH_HFLAG_BMASK; ++ if (ctx->base.is_jmp == DISAS_NEXT) { ++ save_cpu_state(ctx, 0); ++ } else { ++ /* ++ * It is not safe to save ctx->hflags as hflags may be changed ++ * in execution time. ++ */ ++ tcg_gen_andi_i32(hflags, hflags, ~LARCH_HFLAG_BMASK); ++ } ++} ++ ++static void gen_branch(DisasContext *ctx, int insn_bytes) ++{ ++ if (ctx->hflags & LARCH_HFLAG_BMASK) { ++ int proc_hflags = ctx->hflags & LARCH_HFLAG_BMASK; ++ /* Branches completion */ ++ clear_branch_hflags(ctx); ++ ctx->base.is_jmp = DISAS_NORETURN; ++ /* FIXME: Need to clear can_do_io. */ ++ switch (proc_hflags & LARCH_HFLAG_BMASK) { ++ case LARCH_HFLAG_B: ++ /* unconditional branch */ ++ gen_goto_tb(ctx, 0, ctx->btarget); ++ break; ++ case LARCH_HFLAG_BC: ++ /* Conditional branch */ ++ { ++ TCGLabel *l1 = gen_new_label(); ++ ++ tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); ++ gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); ++ gen_set_label(l1); ++ gen_goto_tb(ctx, 0, ctx->btarget); ++ } ++ break; ++ case LARCH_HFLAG_BR: ++ /* unconditional branch to register */ ++ tcg_gen_mov_tl(cpu_PC, btarget); ++ if (ctx->base.singlestep_enabled) { ++ save_cpu_state(ctx, 0); ++ gen_helper_raise_exception_debug(cpu_env); ++ } ++ tcg_gen_lookup_and_goto_ptr(); ++ break; ++ default: ++ fprintf(stderr, "unknown branch 0x%x\n", proc_hflags); ++ abort(); ++ } ++ } ++} ++ ++/* Signed immediate */ ++#define SIMM(op, start, width) \ ++ ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \ ++ << (32 - width)) \ ++ >> (32 - width)) ++/* Zero-extended immediate */ ++#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width))) ++ ++static void gen_sync(int stype) ++{ ++ TCGBar tcg_mo = TCG_BAR_SC; ++ ++ switch (stype) { ++ case 0x4: /* SYNC_WMB */ ++ tcg_mo |= TCG_MO_ST_ST; ++ break; ++ case 0x10: /* SYNC_MB */ ++ tcg_mo |= TCG_MO_ALL; ++ break; ++ case 0x11: /* SYNC_ACQUIRE */ ++ tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; ++ break; ++ case 0x12: /* SYNC_RELEASE */ ++ tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; ++ break; ++ case 0x13: /* SYNC_RMB */ ++ tcg_mo |= TCG_MO_LD_LD; ++ break; ++ default: ++ tcg_mo |= TCG_MO_ALL; ++ break; ++ } ++ ++ tcg_gen_mb(tcg_mo); ++} ++ ++static void gen_crc32(DisasContext *ctx, int rd, int rs, int rt, int sz, ++ int crc32c) ++{ ++ TCGv t0; ++ TCGv t1; ++ TCGv_i32 tsz = tcg_const_i32(1 << sz); ++ if (rd == 0) { ++ /* Treat as NOP. */ ++ return; ++ } ++ t0 = tcg_temp_new(); ++ t1 = tcg_temp_new(); ++ ++ gen_load_gpr(t0, rt); ++ gen_load_gpr(t1, rs); ++ ++ if (crc32c) { ++ gen_helper_crc32c(cpu_gpr[rd], t0, t1, tsz); ++ } else { ++ gen_helper_crc32(cpu_gpr[rd], t0, t1, tsz); ++ } ++ ++ tcg_temp_free(t0); ++ tcg_temp_free(t1); ++ tcg_temp_free_i32(tsz); ++} ++ ++#include "cpu-csr.h" ++ ++#ifndef CONFIG_USER_ONLY ++ ++/* ++ * 64-bit CSR read ++ * ++ * @arg : GPR to store the value of CSR register ++ * @csr : CSR register number ++ */ ++static void gen_csr_rdq(DisasContext *ctx, TCGv rd, int64_t a1) ++{ ++ TCGv_i64 csr = tcg_const_i64(a1); ++ gen_helper_csr_rdq(rd, cpu_env, csr); ++} ++ ++/* ++ * 64-bit CSR write ++ * ++ * @arg : GPR that stores the new value of CSR register ++ * @csr : CSR register number ++ */ ++static void gen_csr_wrq(DisasContext *ctx, TCGv val, int64_t a1) ++{ ++ TCGv_i64 csr = tcg_const_i64(a1); ++ gen_helper_csr_wrq(val, cpu_env, val, csr); ++} ++ ++/* ++ * 64-bit CSR exchange ++ * ++ * @arg : GPR that stores the new value of CSR register ++ * @csr : CSR register number ++ */ ++static void gen_csr_xchgq(DisasContext *ctx, TCGv val, TCGv mask, int64_t a1) ++{ ++ TCGv_i64 csr = tcg_const_i64(a1); ++ gen_helper_csr_xchgq(val, cpu_env, val, mask, csr); ++} ++#endif /* !CONFIG_USER_ONLY */ ++ ++static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, ++ CPUState *cs) ++{ ++ DisasContext *ctx = container_of(dcbase, DisasContext, base); ++ CPULOONGARCHState *env = cs->env_ptr; ++ ++ ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; ++ ctx->saved_pc = -1; ++ ctx->insn_flags = env->insn_flags; ++ ctx->btarget = 0; ++ /* Restore state from the tb context. */ ++ ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ ++ restore_cpu_state(env, ctx); ++#ifdef CONFIG_USER_ONLY ++ ctx->mem_idx = LARCH_HFLAG_UM; ++#else ++ ctx->mem_idx = hflags_mmu_index(ctx->hflags); ++#endif ++ ctx->default_tcg_memop_mask = MO_ALIGN; ++ ++ LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, ++ ctx->hflags); ++} ++ ++static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) ++{ ++} ++ ++static void loongarch_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) ++{ ++ DisasContext *ctx = container_of(dcbase, DisasContext, base); ++ ++ tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & LARCH_HFLAG_BMASK, ++ ctx->btarget); ++} ++#if 0 ++static bool loongarch_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, ++ const CPUBreakpoint *bp) ++{ ++ DisasContext *ctx = container_of(dcbase, DisasContext, base); ++ ++ save_cpu_state(ctx, 1); ++ ctx->base.is_jmp = DISAS_NORETURN; ++ gen_helper_raise_exception_debug(cpu_env); ++ /* The address covered by the breakpoint must be included in ++ [tb->pc, tb->pc + tb->size) in order to for it to be ++ properly cleared -- thus we increment the PC here so that ++ the logic setting tb->size below does the right thing. */ ++ ctx->base.pc_next += 4; ++ return true; ++} ++#endif ++/* 128 and 256 lsx vector instructions are not supported yet */ ++static bool decode_vector_lsx(uint32_t opcode) ++{ ++ uint32_t value = (opcode & 0xff000000); ++ ++ if ((opcode & 0xf0000000) == 0x70000000) { ++ return true; ++ } else if ((opcode & 0xfff00000) == 0x38400000) { ++ return true; ++ } else { ++ switch (value) { ++ case 0x09000000: ++ case 0x0a000000: ++ case 0x0e000000: ++ case 0x0f000000: ++ case 0x2c000000: ++ case 0x30000000: ++ case 0x31000000: ++ case 0x32000000: ++ case 0x33000000: ++ return true; ++ } ++ } ++ return false; ++} ++ ++static bool decode_insn(DisasContext *ctx, uint32_t insn); ++#include "decode-insn.c.inc" ++#include "trans.inc.c" ++ ++static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) ++{ ++ CPULOONGARCHState *env = cs->env_ptr; ++ DisasContext *ctx = container_of(dcbase, DisasContext, base); ++ int insn_bytes = 4; ++ ++ ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next); ++ ++ if (!decode_insn(ctx, ctx->opcode)) { ++ if (decode_vector_lsx(ctx->opcode)) { ++ generate_exception_end(ctx, EXCP_RI); ++ } else { ++ fprintf(stderr, "Error: unkown opcode. 0x%lx: 0x%x\n", ++ ctx->base.pc_next, ctx->opcode); ++ generate_exception_end(ctx, EXCP_RI); ++ } ++ } ++ ++ if (ctx->hflags & LARCH_HFLAG_BMASK) { ++ gen_branch(ctx, insn_bytes); ++ } ++ ctx->base.pc_next += insn_bytes; ++} ++ ++static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) ++{ ++ DisasContext *ctx = container_of(dcbase, DisasContext, base); ++ ++ if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) { ++ save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT); ++ gen_helper_raise_exception_debug(cpu_env); ++ } else { ++ switch (ctx->base.is_jmp) { ++ case DISAS_STOP: ++ gen_save_pc(ctx->base.pc_next); ++ tcg_gen_lookup_and_goto_ptr(); ++ break; ++ case DISAS_NEXT: ++ case DISAS_TOO_MANY: ++ save_cpu_state(ctx, 0); ++ gen_goto_tb(ctx, 0, ctx->base.pc_next); ++ break; ++ case DISAS_EXIT: ++ tcg_gen_exit_tb(NULL, 0); ++ break; ++ case DISAS_NORETURN: ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++ } ++} ++ ++static void loongarch_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) ++{ ++ qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); ++ log_target_disas(cs, dcbase->pc_first, dcbase->tb->size); ++} ++ ++static const TranslatorOps loongarch_tr_ops = { ++ .init_disas_context = loongarch_tr_init_disas_context, ++ .tb_start = loongarch_tr_tb_start, ++ .insn_start = loongarch_tr_insn_start, ++#if 0 ++ .breakpoint_check = loongarch_tr_breakpoint_check, ++#endif ++ .translate_insn = loongarch_tr_translate_insn, ++ .tb_stop = loongarch_tr_tb_stop, ++ .disas_log = loongarch_tr_disas_log, ++}; ++ ++void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb, int max_insns) ++{ ++ DisasContext ctx; ++ ++ translator_loop(&loongarch_tr_ops, &ctx.base, cs, tb, max_insns); ++} ++ ++void loongarch_tcg_init(void) ++{ ++ int i; ++ ++ for (i = 0; i < 32; i++) ++ cpu_gpr[i] = tcg_global_mem_new(cpu_env, ++ offsetof(CPULOONGARCHState, ++ active_tc.gpr[i]), ++ regnames[i]); ++ ++ for (i = 0; i < 32; i++) { ++ int off = offsetof(CPULOONGARCHState, active_fpu.fpr[i].d); ++ fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); ++ } ++ ++ cpu_PC = tcg_global_mem_new(cpu_env, ++ offsetof(CPULOONGARCHState, active_tc.PC), "PC"); ++ bcond = tcg_global_mem_new(cpu_env, ++ offsetof(CPULOONGARCHState, bcond), "bcond"); ++ btarget = tcg_global_mem_new(cpu_env, ++ offsetof(CPULOONGARCHState, btarget), "btarget"); ++ hflags = tcg_global_mem_new_i32(cpu_env, ++ offsetof(CPULOONGARCHState, hflags), "hflags"); ++ fpu_fcsr0 = tcg_global_mem_new_i32(cpu_env, ++ offsetof(CPULOONGARCHState, active_fpu.fcsr0), ++ "fcsr0"); ++ cpu_lladdr = tcg_global_mem_new(cpu_env, ++ offsetof(CPULOONGARCHState, lladdr), ++ "lladdr"); ++ cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPULOONGARCHState, llval), ++ "llval"); ++} ++ ++void restore_state_to_opc(CPULOONGARCHState *env, TranslationBlock *tb, ++ target_ulong *data) ++{ ++ env->active_tc.PC = data[0]; ++ env->hflags &= ~LARCH_HFLAG_BMASK; ++ env->hflags |= data[1]; ++ switch (env->hflags & LARCH_HFLAG_BMASK) { ++ case LARCH_HFLAG_BR: ++ break; ++ case LARCH_HFLAG_BC: ++ case LARCH_HFLAG_B: ++ env->btarget = data[2]; ++ break; ++ } ++} +diff --git a/target/meson.build b/target/meson.build +index ec6bc9733..a824a390f 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/BinDir.tar.gz b/BinDir.tar.gz index 9d090b54e78449dd0b521b29676dc5021cb7603e..15302510540896005ce463133861165238738cc0 100644 GIT binary patch delta 962946 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

^@6cKM{{tH}d|9u>#cKf5+ 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 Yy`awhd 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 z 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

e^dkFU>r?R)+$oj1|GxS|IfRUFAj( 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�}QwE#%H!oQ%3e{gdD-FXAJchkqqh$XrmJEK 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�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 diff --git a/Fix-irq-routing-to-compat-with-kernel-v6.4.patch b/Fix-irq-routing-to-compat-with-kernel-v6.4.patch new file mode 100644 index 00000000..cabfb3e7 --- /dev/null +++ b/Fix-irq-routing-to-compat-with-kernel-v6.4.patch @@ -0,0 +1,41 @@ +From efc098bec428dd0196d2a31380992b04c5116707 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Thu, 22 Dec 2022 07:22:28 -0500 +Subject: [PATCH 11/11] Fix irq routing to compat with kernel v6.4 + +Signed-off-by: lixianglai +--- + accel/kvm/kvm-all.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index 946ccb260..d38b73eba 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -1771,7 +1771,7 @@ void kvm_init_irq_routing(KVMState *s) + + void kvm_irqchip_commit_routes(KVMState *s) + { +- int ret; ++ int ret, i; + + if (kvm_gsi_direct_mapping()) { + return; +@@ -1784,9 +1784,12 @@ void kvm_irqchip_commit_routes(KVMState *s) + s->irq_routes->flags = 0; + trace_kvm_irqchip_commit_routes(); + ret = kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes); ++ /* Do not set gsi routing if not support by kvm */ + if (ret < 0) { +- error_report("Set GSI routing failed: %m"); +- abort(); ++ for (i = 0; i < 32; ++i) { ++ kvm_irqchip_release_virq(s, i); ++ } ++ ret = kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes); + } + } + +-- +2.27.0 + diff --git a/Modify-compile-script.patch b/Modify-compile-script.patch new file mode 100644 index 00000000..863a7dae --- /dev/null +++ b/Modify-compile-script.patch @@ -0,0 +1,44 @@ +From 3348474c6240e83170a6f11099dd8ae4b27c92c8 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Wed, 7 Dec 2022 05:07:11 -0500 +Subject: [PATCH 08/11] Modify compile script. + +Signed-off-by: lixianglai +--- + meson.build | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/meson.build b/meson.build +index 721051441..d80426b3e 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']) +-- +2.27.0 + diff --git a/Modify-kvm-cpu-vga-qapi.patch b/Modify-kvm-cpu-vga-qapi.patch new file mode 100644 index 00000000..31f84e34 --- /dev/null +++ b/Modify-kvm-cpu-vga-qapi.patch @@ -0,0 +1,371 @@ +From f29899c676fa49e0520b4e4545100f9f43fd4dc9 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Wed, 7 Dec 2022 05:02:13 -0500 +Subject: [PATCH 07/11] Modify kvm cpu vga qapi. + +Signed-off-by: lixianglai +--- + hw/meson.build | 1 + + include/disas/dis-asm.h | 1 + + include/elf.h | 2 ++ + include/qemu/osdep.h | 3 ++ + include/sysemu/arch_init.h | 1 + + linux-headers/linux/kvm.h | 23 +++++++++++++ + linux-user/elfload.c | 67 ++++++++++++++++++++++++++++++++++++++ + linux-user/meson.build | 1 + + linux-user/qemu.h | 2 +- + linux-user/syscall.c | 3 ++ + linux-user/syscall_defs.h | 9 ++--- + meson.build | 1 + + pc-bios/meson.build | 1 + + qapi/machine-target.json | 6 ++-- + qapi/machine.json | 2 +- + qapi/misc-target.json | 1 + + qemu-options.hx | 2 +- + 17 files changed, 117 insertions(+), 9 deletions(-) + +diff --git a/hw/meson.build b/hw/meson.build +index f39c1f7e7..a9a078ec3 100644 +--- a/hw/meson.build ++++ b/hw/meson.build +@@ -17,6 +17,7 @@ subdir('intc') + subdir('ipack') + subdir('ipmi') + subdir('isa') ++subdir('loongarch') + subdir('mem') + subdir('misc') + subdir('net') +diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h +index 4590bcc96..17057906f 100644 +--- a/include/disas/dis-asm.h ++++ b/include/disas/dis-asm.h +@@ -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 79c188b62..cd7808f37 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/qemu/osdep.h b/include/qemu/osdep.h +index 60718fc34..903475bb2 100644 +--- a/include/qemu/osdep.h ++++ b/include/qemu/osdep.h +@@ -533,6 +533,9 @@ static inline void qemu_cleanup_generic_vfree(void *p) + Valgrind does not support alignments larger than 1 MiB, + therefore we need special code which handles running on Valgrind. */ + # define QEMU_VMALLOC_ALIGN (512 * 4096) ++#elif defined(__linux__) && defined(__loongarch__) ++ /* Use 32 MiB alignment so transparent hugepages can be used by KVM. */ ++# define QEMU_VMALLOC_ALIGN (qemu_real_host_page_size * qemu_real_host_page_size / 8) + #elif defined(__linux__) && defined(__s390x__) + /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */ + # define QEMU_VMALLOC_ALIGN (256 * 4096) +diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h +index 1cf27baa7..cded95f10 100644 +--- a/include/sysemu/arch_init.h ++++ b/include/sysemu/arch_init.h +@@ -24,6 +24,7 @@ enum { + QEMU_ARCH_RX = (1 << 20), + QEMU_ARCH_AVR = (1 << 21), + QEMU_ARCH_HEXAGON = (1 << 22), ++ QEMU_ARCH_LOONGARCH64 = (1 << 23), + QEMU_ARCH_SW64 = (1 << 23), + }; + +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 7870cd028..a900fe99b 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -2008,6 +2008,29 @@ struct kvm_stats_desc { + char name[]; + }; + ++#ifdef __loongarch__ ++struct kvm_loongarch_vcpu_state { ++ __u8 online_vcpus; ++ __u8 is_migrate; ++ __u32 cpu_freq; ++ __u32 count_ctl; ++ __u64 pending_exceptions; ++ __u64 pending_exceptions_clr; ++ __u64 core_ext_ioisr[4]; ++}; ++ ++#define KVM_CAP_LOONGARCH_FPU 165 ++#define KVM_CAP_LOONGARCH_LSX 166 ++#define KVM_CAP_LOONGARCH_VZ 167 ++#define KVM_REG_LOONGARCH 0x8000000000000000ULL ++#define KVM_LARCH_GET_VCPU_STATE _IOR(KVMIO, 0xc0, struct kvm_loongarch_vcpu_state) ++#define KVM_LARCH_SET_VCPU_STATE _IOW(KVMIO, 0xc1, struct kvm_loongarch_vcpu_state) ++#define KVM_LARCH_GET_CPUCFG _IOR(KVMIO, 0xc2, struct kvm_cpucfg) ++#define KVM_LOONGARCH_GET_IOCSR _IOR(KVMIO, 0xc3, struct kvm_iocsr_entry) ++#define KVM_LOONGARCH_SET_IOCSR _IOW(KVMIO, 0xc4, struct kvm_iocsr_entry) ++#define KVM_LARCH_SET_CPUCFG _IOR(KVMIO, 0xc5, struct kvm_cpucfg) ++#endif ++ + #define KVM_GET_STATS_FD _IO(KVMIO, 0xce) + + /* Available with KVM_CAP_XSAVE2 */ +diff --git a/linux-user/elfload.c b/linux-user/elfload.c +index 767f54c76..9fb632780 100644 +--- a/linux-user/elfload.c ++++ b/linux-user/elfload.c +@@ -1041,6 +1041,73 @@ static uint32_t get_elf_hwcap(void) + + #endif /* TARGET_MIPS */ + ++#ifdef TARGET_LOONGARCH64 ++ ++#define ELF_START_MMAP 0x80000000 ++ ++#define ELF_CLASS ELFCLASS64 ++#define ELF_ARCH EM_LOONGARCH ++ ++#define elf_check_arch(x) ((x) == EM_LOONGARCH) ++ ++static inline void init_thread(struct target_pt_regs *regs, ++ struct image_info *infop) ++{ ++ regs->csr_crmd = 2 << 3; ++ regs->csr_era = infop->entry; ++ regs->regs[3] = infop->start_stack; ++} ++ ++/* See linux kernel: arch/mips/include/asm/elf.h. */ ++#define ELF_NREG 45 ++typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG]; ++ ++/* See linux kernel: arch/loongarch/include/uapi/asm/reg.h */ ++enum { ++ TARGET_EF_R0 = 0, ++ TARGET_EF_R26 = TARGET_EF_R0 + 26, ++ TARGET_EF_R27 = TARGET_EF_R0 + 27, ++ TARGET_EF_CSR_ERA = TARGET_EF_R0 + 32, ++ TARGET_EF_CSR_BADV = TARGET_EF_R0 + 33, ++ TARGET_EF_CSR_CRMD = TARGET_EF_R0 + 34, ++ TARGET_EF_CSR_ESTAT = TARGET_EF_R0 + 38 ++}; ++ ++/* See linux kernel: arch/loongarch/kernel/process.c:elf_dump_regs. */ ++static void elf_core_copy_regs(target_elf_gregset_t *regs, ++ const CPULOONGARCHState *env) ++{ ++ int i; ++ ++ for (i = 0; i < TARGET_EF_R0; i++) { ++ (*regs)[i] = 0; ++ } ++ (*regs)[TARGET_EF_R0] = 0; ++ ++ for (i = 1; i < ARRAY_SIZE(env->active_tc.gpr); i++) { ++ (*regs)[TARGET_EF_R0 + i] = tswapreg(env->active_tc.gpr[i]); ++ } ++ ++ (*regs)[TARGET_EF_R26] = 0; ++ (*regs)[TARGET_EF_R27] = 0; ++ (*regs)[TARGET_EF_CSR_ERA] = tswapreg(env->active_tc.PC); ++ (*regs)[TARGET_EF_CSR_BADV] = tswapreg(env->CSR_BADV); ++ (*regs)[TARGET_EF_CSR_CRMD] = tswapreg(env->CSR_CRMD); ++ (*regs)[TARGET_EF_CSR_ESTAT] = tswapreg(env->CSR_ESTAT); ++} ++ ++#define USE_ELF_CORE_DUMP ++#define ELF_EXEC_PAGESIZE 4096 ++ ++#define ELF_HWCAP get_elf_hwcap() ++ ++static uint32_t get_elf_hwcap(void) ++{ ++ return 0; ++} ++ ++#endif /* TARGET_LOONGARCH64 */ ++ + #ifdef TARGET_MICROBLAZE + + #define ELF_START_MMAP 0x80000000 +diff --git a/linux-user/meson.build b/linux-user/meson.build +index 4f4196ed1..8b8edefa6 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 5c713fa8a..66ddb25d1 100644 +--- a/linux-user/qemu.h ++++ b/linux-user/qemu.h +@@ -61,7 +61,7 @@ struct image_info { + /* For target-specific processing of NT_GNU_PROPERTY_TYPE_0. */ + uint32_t note_flags; + +-#ifdef TARGET_MIPS ++#if defined(TARGET_MIPS) || defined(TARGET_LOONGARCH64) + int fp_abi; + int interp_fp_abi; + #endif +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index fce2c0325..a544d0452 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -1614,6 +1614,9 @@ static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, + #elif defined(TARGET_MIPS) + ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1]; + return host_pipe[0]; ++#elif defined(TARGET_LOONGARCH64) ++ ((CPULOONGARCHState *)cpu_env)->active_tc.gpr[5] = host_pipe[1]; ++ return host_pipe[0]; + #elif defined(TARGET_SH4) + ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1]; + return host_pipe[0]; +diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h +index 0b1397593..7e2915d53 100644 +--- a/linux-user/syscall_defs.h ++++ b/linux-user/syscall_defs.h +@@ -74,7 +74,7 @@ + || defined(TARGET_M68K) || defined(TARGET_CRIS) \ + || defined(TARGET_S390X) || defined(TARGET_OPENRISC) \ + || defined(TARGET_NIOS2) || defined(TARGET_RISCV) \ +- || defined(TARGET_XTENSA) ++ || defined(TARGET_XTENSA) || defined(TARGET_LOONGARCH64) + + #define TARGET_IOC_SIZEBITS 14 + #define TARGET_IOC_DIRBITS 2 +@@ -450,7 +450,7 @@ struct target_dirent64 { + #define TARGET_SIG_IGN ((abi_long)1) /* ignore signal */ + #define TARGET_SIG_ERR ((abi_long)-1) /* error return from signal */ + +-#ifdef TARGET_MIPS ++#if defined(TARGET_MIPS) || defined(TARGET_LOONGARCH64) + #define TARGET_NSIG 128 + #else + #define TARGET_NSIG 64 +@@ -2133,7 +2133,7 @@ struct target_stat64 { + abi_ulong __unused5; + }; + +-#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || defined(TARGET_RISCV) ++#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || defined(TARGET_RISCV) || defined(TARGET_LOONGARCH64) + + /* These are the asm-generic versions of the stat and stat64 structures */ + +@@ -2161,7 +2161,7 @@ struct target_stat { + unsigned int __unused5; + }; + +-#if !defined(TARGET_RISCV64) ++#if !(defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)) + #define TARGET_HAS_STRUCT_STAT64 + struct target_stat64 { + uint64_t st_dev; +@@ -2331,6 +2331,7 @@ struct target_statfs64 { + }; + #elif (defined(TARGET_PPC64) || defined(TARGET_X86_64) || \ + defined(TARGET_SPARC64) || defined(TARGET_AARCH64) || \ ++ defined(TARGET_LOONGARCH64) || \ + defined(TARGET_RISCV)) && !defined(TARGET_ABI32) + struct target_statfs { + abi_long f_type; +diff --git a/meson.build b/meson.build +index d0bbceffe..721051441 100644 +--- a/meson.build ++++ b/meson.build +@@ -1822,6 +1822,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' +diff --git a/pc-bios/meson.build b/pc-bios/meson.build +index 05e9065ad..4f3f351f7 100644 +--- a/pc-bios/meson.build ++++ b/pc-bios/meson.build +@@ -86,6 +86,7 @@ blobs = files( + 'opensbi-riscv32-generic-fw_dynamic.elf', + 'opensbi-riscv64-generic-fw_dynamic.elf', + 'npcm7xx_bootrom.bin', ++ 'loongarch_bios.bin', + ) + + if get_option('install_blobs') +diff --git a/qapi/machine-target.json b/qapi/machine-target.json +index f5ec4bc17..682dc86b4 100644 +--- a/qapi/machine-target.json ++++ b/qapi/machine-target.json +@@ -324,7 +324,8 @@ + 'TARGET_ARM', + 'TARGET_I386', + 'TARGET_S390X', +- 'TARGET_MIPS' ] } } ++ 'TARGET_MIPS', ++ 'TARGET_LOONGARCH64' ] } } + + ## + # @query-cpu-definitions: +@@ -340,4 +341,5 @@ + 'TARGET_ARM', + 'TARGET_I386', + 'TARGET_S390X', +- 'TARGET_MIPS' ] } } ++ 'TARGET_MIPS', ++ 'TARGET_LOONGARCH64' ] } } +diff --git a/qapi/machine.json b/qapi/machine.json +index 03cfb268a..31b0350b9 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 4bc45d247..63cebef57 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 047d28a35..e62bb6beb 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. +-- +2.27.0 + diff --git a/Support-rtc.patch b/Support-rtc.patch new file mode 100644 index 00000000..9ae539e6 --- /dev/null +++ b/Support-rtc.patch @@ -0,0 +1,369 @@ +From c8ad7026f0ea618ff079c7c0f2896209fda51b7d Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Wed, 7 Dec 2022 04:21:38 -0500 +Subject: [PATCH 02/11] Support rtc. + +Signed-off-by: lixianglai +--- + hw/timer/Kconfig | 2 + + hw/timer/ls7a_rtc.c | 325 +++++++++++++++++++++++++++++++++++++++++++ + hw/timer/meson.build | 1 + + 3 files changed, 328 insertions(+) + create mode 100644 hw/timer/ls7a_rtc.c + +diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig +index 010be7ed1..b395c72d7 100644 +--- a/hw/timer/Kconfig ++++ b/hw/timer/Kconfig +@@ -60,3 +60,5 @@ config STELLARIS_GPTM + + config AVR_TIMER16 + bool ++config LS7A_RTC ++ bool +diff --git a/hw/timer/ls7a_rtc.c b/hw/timer/ls7a_rtc.c +new file mode 100644 +index 000000000..756f2fc9c +--- /dev/null ++++ b/hw/timer/ls7a_rtc.c +@@ -0,0 +1,325 @@ ++#include "qemu/osdep.h" ++#include "hw/sysbus.h" ++#include "hw/irq.h" ++#include "include/hw/register.h" ++#include "qemu/timer.h" ++#include "sysemu/sysemu.h" ++#include "qemu/cutils.h" ++#include "qemu/log.h" ++#include "qemu-common.h" ++#include "migration/vmstate.h" ++ ++#ifdef DEBUG_LS7A_RTC ++#define DPRINTF (fmt, ...) \ ++do { printf("ls7a_rtc: " fmt , ## __VA_ARGS__); } while (0) ++#else ++#define DPRINTF (fmt, ...) do {} while (0) ++#endif ++ ++ ++#define SYS_TOYTRIM 0x20 ++#define SYS_TOYWRITE0 0x24 ++#define SYS_TOYWRITE1 0x28 ++#define SYS_TOYREAD0 0x2C ++#define SYS_TOYREAD1 0x30 ++#define SYS_TOYMATCH0 0x34 ++#define SYS_TOYMATCH1 0x38 ++#define SYS_TOYMATCH2 0x3C ++#define SYS_RTCCTRL 0x40 ++#define SYS_RTCTRIM 0x60 ++#define SYS_RTCWRTIE0 0x64 ++#define SYS_RTCREAD0 0x68 ++#define SYS_RTCMATCH0 0x6C ++#define SYS_RTCMATCH1 0x70 ++#define SYS_RTCMATCH2 0x74 ++ ++/** ++ ** shift bits and filed mask ++ **/ ++#define TOY_MON_MASK 0x3f ++#define TOY_DAY_MASK 0x1f ++#define TOY_HOUR_MASK 0x1f ++#define TOY_MIN_MASK 0x3f ++#define TOY_SEC_MASK 0x3f ++#define TOY_MSEC_MASK 0xf ++ ++#define TOY_MON_SHIFT 26 ++#define TOY_DAY_SHIFT 21 ++#define TOY_HOUR_SHIFT 16 ++#define TOY_MIN_SHIFT 10 ++#define TOY_SEC_SHIFT 4 ++#define TOY_MSEC_SHIFT 0 ++ ++#define TOY_MATCH_YEAR_MASK 0x3f ++#define TOY_MATCH_MON_MASK 0xf ++#define TOY_MATCH_DAY_MASK 0x1f ++#define TOY_MATCH_HOUR_MASK 0x1f ++#define TOY_MATCH_MIN_MASK 0x3f ++#define TOY_MATCH_SEC_MASK 0x3f ++ ++ ++#define TOY_MATCH_YEAR_SHIFT 26 ++#define TOY_MATCH_MON_SHIFT 22 ++#define TOY_MATCH_DAY_SHIFT 17 ++#define TOY_MATCH_HOUR_SHIFT 12 ++#define TOY_MATCH_MIN_SHIFT 6 ++#define TOY_MATCH_SEC_SHIFT 0 ++ ++#define TOY_ENABLE_BIT (1U << 11) ++ ++#define TYPE_LS7A_RTC "ls7a_rtc" ++#define LS7A_RTC(obj) OBJECT_CHECK(LS7A_RTCState, (obj), TYPE_LS7A_RTC) ++ ++typedef struct LS7A_RTCState { ++ SysBusDevice parent_obj; ++ ++ MemoryRegion iomem; ++ QEMUTimer *timer; ++ /* Needed to preserve the tick_count across migration, even if the ++ * absolute value of the rtc_clock is different on the source and ++ * destination. ++ */ ++ int64_t offset; ++ int64_t data; ++ int64_t save_alarm_offset; ++ int tidx; ++ uint32_t toymatch[3]; ++ uint32_t toytrim; ++ uint32_t cntrctl; ++ uint32_t rtctrim; ++ uint32_t rtccount; ++ uint32_t rtcmatch[3]; ++ qemu_irq toy_irq; ++} LS7A_RTCState; ++ ++enum { ++TOYEN = 1UL << 11, ++RTCEN = 1UL << 13, ++}; ++ ++static uint64_t ls7a_rtc_read(void *opaque, hwaddr addr, ++ unsigned size) ++{ ++ LS7A_RTCState *s = (LS7A_RTCState *)opaque; ++ struct tm tm; ++ unsigned int val; ++ ++ val = 0; ++ ++ switch (addr) { ++ case SYS_TOYREAD0: ++ qemu_get_timedate(&tm, s->offset); ++ val = (((tm.tm_mon + 1) & TOY_MON_MASK) << TOY_MON_SHIFT) ++ | (((tm.tm_mday) & TOY_DAY_MASK) << TOY_DAY_SHIFT) ++ | (((tm.tm_hour) & TOY_HOUR_MASK) << TOY_HOUR_SHIFT) ++ | (((tm.tm_min) & TOY_MIN_MASK) << TOY_MIN_SHIFT) ++ | (((tm.tm_sec) & TOY_SEC_MASK) << TOY_SEC_SHIFT) | 0x0; ++ break; ++ case SYS_TOYREAD1: ++ qemu_get_timedate(&tm, s->offset); ++ val = tm.tm_year; ++ break; ++ case SYS_TOYMATCH0: ++ val = s->toymatch[0]; ++ break; ++ case SYS_TOYMATCH1: ++ val = s->toymatch[1]; ++ break; ++ case SYS_TOYMATCH2: ++ val = s->toymatch[2]; ++ break; ++ case SYS_RTCCTRL: ++ val = s->cntrctl; ++ break; ++ case SYS_RTCREAD0: ++ val = s->rtccount; ++ break; ++ case SYS_RTCMATCH0: ++ val = s->rtcmatch[0]; ++ break; ++ case SYS_RTCMATCH1: ++ val = s->rtcmatch[1]; ++ break; ++ case SYS_RTCMATCH2: ++ val = s->rtcmatch[2]; ++ break; ++ default: ++ val = 0; ++ break; ++ } ++ return val; ++} ++ ++ ++static void ls7a_rtc_write(void *opaque, hwaddr addr, ++ uint64_t val, unsigned size) ++{ ++ LS7A_RTCState *s = (LS7A_RTCState *)opaque; ++ struct tm tm; ++ int64_t alarm_offset, year_diff, expire_time; ++ ++ switch (addr) { ++ case SYS_TOYWRITE0: ++ qemu_get_timedate(&tm, s->offset); ++ tm.tm_sec = (val >> TOY_SEC_SHIFT) & TOY_SEC_MASK; ++ tm.tm_min = (val >> TOY_MIN_SHIFT) & TOY_MIN_MASK; ++ tm.tm_hour = (val >> TOY_HOUR_SHIFT) & TOY_HOUR_MASK; ++ tm.tm_mday = ((val >> TOY_DAY_SHIFT) & TOY_DAY_MASK); ++ tm.tm_mon = ((val >> TOY_MON_SHIFT) & TOY_MON_MASK) - 1; ++ s->offset = qemu_timedate_diff(&tm); ++ break; ++ case SYS_TOYWRITE1: ++ qemu_get_timedate(&tm, s->offset); ++ tm.tm_year = val; ++ s->offset = qemu_timedate_diff(&tm); ++ break; ++ case SYS_TOYMATCH0: ++ s->toymatch[0] = val; ++ qemu_get_timedate(&tm, s->offset); ++ tm.tm_sec = (val >> TOY_MATCH_SEC_SHIFT) & TOY_MATCH_SEC_MASK; ++ tm.tm_min = (val >> TOY_MATCH_MIN_SHIFT) & TOY_MATCH_MIN_MASK; ++ tm.tm_hour = ((val >> TOY_MATCH_HOUR_SHIFT) & TOY_MATCH_HOUR_MASK); ++ tm.tm_mday = ((val >> TOY_MATCH_DAY_SHIFT) & TOY_MATCH_DAY_MASK); ++ tm.tm_mon = ((val >> TOY_MATCH_MON_SHIFT) & TOY_MATCH_MON_MASK) - 1; ++ year_diff = ((val >> TOY_MATCH_YEAR_SHIFT) & TOY_MATCH_YEAR_MASK); ++ year_diff = year_diff - (tm.tm_year & TOY_MATCH_YEAR_MASK); ++ tm.tm_year = tm.tm_year + year_diff; ++ alarm_offset = qemu_timedate_diff(&tm) - s->offset; ++ if ((alarm_offset < 0) && (alarm_offset > -5)) { ++ alarm_offset = 0; ++ } ++ expire_time = qemu_clock_get_ms(rtc_clock); ++ expire_time += ((alarm_offset * 1000) + 100); ++ timer_mod(s->timer, expire_time); ++ break; ++ case SYS_TOYMATCH1: ++ s->toymatch[1] = val; ++ break; ++ case SYS_TOYMATCH2: ++ s->toymatch[2] = val; ++ break; ++ case SYS_RTCCTRL: ++ s->cntrctl = val; ++ break; ++ case SYS_RTCWRTIE0: ++ s->rtccount = val; ++ break; ++ case SYS_RTCMATCH0: ++ s->rtcmatch[0] = val; ++ break; ++ case SYS_RTCMATCH1: ++ val = s->rtcmatch[1]; ++ break; ++ case SYS_RTCMATCH2: ++ val = s->rtcmatch[2]; ++ break; ++ default: ++ break; ++ } ++} ++ ++static const MemoryRegionOps ls7a_rtc_ops = { ++ .read = ls7a_rtc_read, ++ .write = ls7a_rtc_write, ++ .endianness = DEVICE_NATIVE_ENDIAN, ++ .valid = { ++ .min_access_size = 4, ++ .max_access_size = 4, ++ }, ++ ++}; ++ ++static void toy_timer(void *opaque) ++{ ++ LS7A_RTCState *s = (LS7A_RTCState *) opaque; ++ ++ if (s->cntrctl & TOY_ENABLE_BIT) { ++ qemu_irq_pulse(s->toy_irq); ++ } ++} ++ ++static void ls7a_rtc_realize(DeviceState *dev, Error **errp) ++{ ++ SysBusDevice *sbd = SYS_BUS_DEVICE(dev); ++ LS7A_RTCState *d = LS7A_RTC(sbd); ++ memory_region_init_io(&d->iomem, NULL, &ls7a_rtc_ops, ++ (void *)d, "ls7a_rtc", 0x100); ++ ++ sysbus_init_irq(sbd, &d->toy_irq); ++ ++ sysbus_init_mmio(sbd, &d->iomem); ++ d->timer = timer_new_ms(rtc_clock, toy_timer, d); ++ timer_mod(d->timer, qemu_clock_get_ms(rtc_clock) + 100); ++ d->offset = 0; ++} ++ ++static int ls7a_rtc_pre_save(void *opaque) ++{ ++ LS7A_RTCState *s = (LS7A_RTCState *)opaque; ++ struct tm tm; ++ int64_t year_diff, value; ++ ++ value = s->toymatch[0]; ++ qemu_get_timedate(&tm, s->offset); ++ tm.tm_sec = (value >> TOY_MATCH_SEC_SHIFT) & TOY_MATCH_SEC_MASK; ++ tm.tm_min = (value >> TOY_MATCH_MIN_SHIFT) & TOY_MATCH_MIN_MASK; ++ tm.tm_hour = ((value >> TOY_MATCH_HOUR_SHIFT) & TOY_MATCH_HOUR_MASK); ++ tm.tm_mday = ((value >> TOY_MATCH_DAY_SHIFT) & TOY_MATCH_DAY_MASK); ++ tm.tm_mon = ((value >> TOY_MATCH_MON_SHIFT) & TOY_MATCH_MON_MASK) - 1; ++ year_diff = ((value >> TOY_MATCH_YEAR_SHIFT) & TOY_MATCH_YEAR_MASK); ++ year_diff = year_diff - (tm.tm_year & TOY_MATCH_YEAR_MASK); ++ tm.tm_year = tm.tm_year + year_diff; ++ s->save_alarm_offset = qemu_timedate_diff(&tm) - s->offset; ++ ++ return 0; ++} ++ ++ ++static int ls7a_rtc_post_load(void *opaque, int version_id) ++{ ++ LS7A_RTCState *s = (LS7A_RTCState *)opaque; ++ int64_t expire_time; ++ ++ expire_time = qemu_clock_get_ms(rtc_clock) + (s->save_alarm_offset * 1000); ++ timer_mod(s->timer, expire_time); ++ ++ return 0; ++} ++ ++static const VMStateDescription vmstate_ls7a_rtc = { ++ .name = "ls7a_rtc", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .pre_save = ls7a_rtc_pre_save, ++ .post_load = ls7a_rtc_post_load, ++ .fields = (VMStateField[]) { ++ VMSTATE_INT64(offset, LS7A_RTCState), ++ VMSTATE_INT64(save_alarm_offset, LS7A_RTCState), ++ VMSTATE_UINT32(toymatch[0], LS7A_RTCState), ++ VMSTATE_UINT32(cntrctl, LS7A_RTCState), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++ ++static void ls7a_rtc_class_init(ObjectClass *klass, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(klass); ++ dc->vmsd = &vmstate_ls7a_rtc; ++ dc->realize = ls7a_rtc_realize; ++ dc->desc = "ls7a rtc"; ++} ++ ++static const TypeInfo ls7a_rtc_info = { ++ .name = TYPE_LS7A_RTC, ++ .parent = TYPE_SYS_BUS_DEVICE, ++ .instance_size = sizeof(LS7A_RTCState), ++ .class_init = ls7a_rtc_class_init, ++}; ++ ++static void ls7a_rtc_register_types(void) ++{ ++ type_register_static(&ls7a_rtc_info); ++} ++ ++type_init(ls7a_rtc_register_types) +diff --git a/hw/timer/meson.build b/hw/timer/meson.build +index 03092e2ce..e841a2f6e 100644 +--- a/hw/timer/meson.build ++++ b/hw/timer/meson.build +@@ -16,6 +16,7 @@ softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_mct.c')) + softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_pwm.c')) + softmmu_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_gptimer.c')) + softmmu_ss.add(when: 'CONFIG_HPET', if_true: files('hpet.c')) ++softmmu_ss.add(when: 'CONFIG_LS7A_RTC', if_true: files('ls7a_rtc.c')) + softmmu_ss.add(when: 'CONFIG_I8254', if_true: files('i8254_common.c', 'i8254.c')) + softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_epit.c')) + softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_gpt.c')) +-- +2.27.0 + diff --git a/fixup-startup-failed-with-netdev-tap-vhost-on.patch b/fixup-startup-failed-with-netdev-tap-vhost-on.patch new file mode 100644 index 00000000..6788c1c4 --- /dev/null +++ b/fixup-startup-failed-with-netdev-tap-vhost-on.patch @@ -0,0 +1,36 @@ +From fffd8299975cf424c01b125c9962f9044e59558a Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Sun, 18 Dec 2022 22:14:41 -0500 +Subject: [PATCH 10/11] fixup startup failed with -netdev tap,vhost=on + +Signed-off-by: lixianglai +--- + hw/net/virtio-net.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index 4946b65e2..f2a818e37 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -936,11 +936,13 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint64_t features) + } + vhost_net_ack_features(get_vhost_net(nc->peer), features); + +- /* +- * keep acked_features in NetVhostUserState up-to-date so it +- * can't miss any features configured by guest virtio driver. +- */ +- vhost_net_save_acked_features(nc->peer); ++ if (nc->info->type == NET_CLIENT_DRIVER_VHOST_USER) { ++ /* ++ * keep acked_features in NetVhostUserState up-to-date so it ++ * can't miss any features configured by guest virtio driver. ++ */ ++ vhost_net_save_acked_features(nc->peer); ++ } + } + + if (virtio_has_feature(features, VIRTIO_NET_F_CTRL_VLAN)) { +-- +2.27.0 + diff --git a/qemu.spec b/qemu.spec index 643bc8ff..e89e30b1 100644 --- a/qemu.spec +++ b/qemu.spec @@ -3,7 +3,7 @@ Name: qemu Version: 6.2.0 -Release: 64 +Release: 65 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 @@ -442,6 +442,17 @@ Patch0427: target-arm-Move-sve-probe-inside-kvm-4.15-branch.patch Patch0428: migration-report-migration-related-thread-pid-to-lib.patch Patch0429: migration-report-multiFd-related-thread-pid-to-libvi.patch Patch0430: vhost_net-keep-acked_feature-only-for-NET_CLIENT_DRI.patch +Patch0431: Add-Acpi-support.patch +Patch0432: Support-rtc.patch +Patch0433: Add-loongarch-machine.patch +Patch0434: Add-target-loongarch64.patch +Patch0435: Add-linux-headers-and-linux-user.patch +Patch0436: Add-disas-gdb.patch +Patch0437: Modify-kvm-cpu-vga-qapi.patch +Patch0438: Modify-compile-script.patch +Patch0439: Add-loongarch64-rh-devices.mak.patch +Patch0440: fixup-startup-failed-with-netdev-tap-vhost-on.patch +Patch0441: Fix-irq-routing-to-compat-with-kernel-v6.4.patch BuildRequires: flex BuildRequires: gcc @@ -607,6 +618,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 @@ -620,6 +637,10 @@ targetarch="aarch64-softmmu arm-softmmu riscv32-softmmu riscv64-softmmu" 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" @@ -749,14 +770,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 @@ -764,6 +786,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 @@ -909,6 +932,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 @@ -973,6 +1017,9 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Fri Dec 23 2022 xianglaili - 10:6.2.0-65 +- Add loongarch supoort + * Wed Dec 14 2022 yezengruan - 10:6.2.0-64 - target/arm: Fix kvm probe of ID_AA64ZFR0 - migration: report migration/multiFd related thread pid to libvirt -- Gitee

V5?U8*yP&IPe4|H>#~3!%t=mhY_@@c0Qd<_4)2 z+0C6VgEeJ7Z9Q_l%*fj5w3;UxdU&+?epR&!-LjbVT;t`4xOf*;-30%8ecUgmyvzE2 za$IRkPPi%A`%6#D7=wQRGIM}mZHdcdh5p~L(lT zs1kgSyl3cWfWU~hv-d`;(kK^p=zS?BdzRGi8Cx>B)ZRQL>33|raM?55Pc=j%1z11d z%xy&|%t|VM;3Sq|n^qNI z>nF`S;Rrvb#4G3e?R_oVi29Q*XxKL+A)Y>cm{9%y2}SPt-cAVpejTlfot`ZO5;$e- zLfo8SRVG%nJ7xUJP-zk8>a-)eZsEfLq;>SZWD?3ZB|l*QP3C=L9?yq2!+jI;2cG*T zQnm?yrd=d9ejEXblL4AQb_4J(Rk;K4qq;{_iAGL%MjtrRx;%&zqlI9EJMe2J5?!v1 zs~~>}HlY8ZBqyn{U}*oG0PQ9H_}887Y=y*&FnZoz+{Q!Wq~=IAxhTXqqW2L~tp(}? z5wH(>+w*-}sSPs}mQc#T1)c~pw!`y^M;^iB_!Z0aWag}RAg?}>VJOYkmT+Q>k^P# z7zL-={PKVchgJ4Lpvc?!Rbsn1g{g{Qf_22y28FZsBd?jI&T)M5ruhETCMss{&+rO= zA4v)v@n9f#3|FW`T?R{5dXm?vT8->O97r*`TG}s$A7igPQ~YD-QrZ-MYha0n-mzAw zcxU4;FqNzpXRUP-zPnUz(lGP+PMUSKDw)0%q&MwrT}Ux6^9dqQB(2|=ZimB4Dr<>V z50$i-xLrGQ{`YCljz}R-{5MjSOe8b^Wy!4|zbdS@~Wx$5Kxq1w3(=0(*X+Gt%H$DP&dff$6pBWVWhvrS(2Bc`#ku@H@` zIser#7)>3+mvBhRbn%T7epTPuqA$wK6uQHDDidyXErmf!HAcSbSJE$UE41~00*p#N z*y6s`?;snQr)wB-g%yDgszkVW&x8JKA0Vo`(!TON=g20#;}It+kVR9E(xejavn)}v z2&FB=gU4^B!^tv(iRINsY}1p&aoWjojOgrp(g$sG`y+}szO-xN11iqwGWM5+Hv<@b zPWoSoLU%osFXNmo@4$$&j;70hPMUyHXh(kYHPu1qTMVzkUJKJ3;9Ms~V*Ep`APmf# zL=ZCoWcZLfBCV6;kFjY5uzb~)=a!m;9VOyh%qi6WJNoGJul*J6x!&V&{{=l+99Z&K z)S?Gp!%Dfb7Jv4(r44iB2Istr<8Zt4A#4oyq&x$KUVJ?)klMtLybyC37?MJaGB zX`VR~_Wccn-Z6FisOGq5$Pa5nTN@}8lH$@% zh-M8IEnibjrbNSk;-bwj05K>BU7$9Y3x!!P0BfeivpyO`d~g8O;nq=LF)%|Wz!tn) zBX+7&R6f>|ldK}-RKC?VB3{x;Es0|2-%q!(bFKgPA<#;whn`~EPdB0iU~=CVOb+*_ z(xn^9nKLS>yXW%xFB@~r0-HcBBF+am!G23m=gH$s_x{*_9%c!bzU@YQvw|R3I_i7= zKM?5D8npq1+cyUAD;&JIDl$muuPK)-hKyw1GpVHNR$J(vv}SEJm49p^Iw^t+gzWHB z557o%^ByjK@WO3QGnBWS>5=HR^(F3^C;LYCH3m;q zzYaJ8;GFZh{7h(^81}@%M?s<ib)}wy%mQtZZJalMtTY0Cv((h{NTr=%v4SD< zQg#@f^WIzgvOok-due3!fH0>omOwQS%5GbJQL;oa7dOZ3skhraxt7QCatSywnOjSL zwJ4BieNr_&dO&p5q4=1j(VkCcb>0CHzmKyG)vT}+Tb!1m0eK5Af=Ypy=Z^xurgT9O ze&3~3m{4y--3|LrR@dVZoGUiD)q`)gm&Y$WQHhM${Q4md=u|lhs>8 zTQYM!So(Ny05MDB0u5V&xadhSV4R5%{Nj)JBP&eB=jsK<=OWma%NLl7nhnK&0KbY= z7l&tXqUZuXY~O1bDbOOn**WDz#O*-3-4|byuYxbS$yy`&r(n-Ex8eCWDgQW5cVGhz zUShh07ndp*l`$BMVqJ*Xp>r!1Tjo!OmOf5yBwy)IJ)k|;TeU9dk^;yACO3Zh>SLSA z4xqq1QQg`HsKPxv#BzM99|j~B#%5D$RW{gzxJ?@bKTd%GON z(8nXSYNTXpaxp#eo`VA$%l*Mt-7G;j5>6oFq3WoV5?u#V(WvyFN_9?uzj&hrvL@F% zgJ-ufZ8*{MicjyTiWK2)rNIVG-;PA z`tX~?Q1mf4AEAF=!fz#hYO^uMw=Rn%w-lW=HJ zRPdZ3-_UcRo^7oIk{M$M=A~)-Twje0I0Yc2f<3r$hb4m`-4#zGZ11h#h@nP4;P1Fq z&Tk9?4T8C9%fg-=XF>vSESt!dJYBn-`&uip`f0DvSifF~ofJDQJ6s8QscUP|`wApB+_~-0xE%TvOy;!>&#v*DyclBk zfJkwkxVg9^Is0aR9LH{%nBBH@bwo_hVqK!)?;U&jwnO9rwcFo>OU>mLy9qOWK@SCxJ-HnuBFJ_A zLZQh9vTNw?AIKFKq_4o6#I-BaR-?(`t+$^qoqp8m8}_4roO4->CrTiaa_fJ~-#ABl@NJu7sRZg24hMJZW)=@3Otpw8RqI=S{ z<#SjPUIHS2724EsXgSA>d30YA0UtGb-qaj&(X7fUATCW@wYDj2Cx91(3$~T}GVaLh zPpVfA=}(_JHD7t8uxzk0TYa8<-=V`I)h4O2_%c~VOx(rr`2i(|hh8SN;NWP3J>Lu$ zQE8ZVu_PJrM~6olKUU(>C_-pGWoqc;l7`DvY&H^q|M;BtcU|R62pDDo@D$tbv4c31 z)^S!o1fClJ8)rZ>kMn^8b*_ny7c0x79sOVol*deMBrh zmqqLs8u`kcl1n=21}yfhtrm8n2)V)j!f!{#Mq3LKgi<}|j31-oQ#z0gjor#ZzOx{B2|DdLlKJo^UJA2*6)8nz-q^D|Y z_{!>-&C}CjIo(GrOtWp&{CaFB(=Z;T@gY{1fuD6O`-@jn)4Q7B+eb(NO)bb_)*p{@ zO5F;sW(70~V{^P%h3B<`4PmAws1 zptRykxLc0c<~l~Y@0`wQK?jr)YxXnfB5Z;z#ExW{bTmp!miD~zCB&kNf&bpzFtph4wkOP+Lijv?||9su@XIn1Pjn$&y8At zPIvE{YDJbr*r&hIJB+&YQfC;#Vk_R6XsF?l5|xYoN`LUCEf`$MxVM@Vi`DCV2+nqlZOYXD7pED)a1x8&x3ZOhsK zRzMGN{=i|g^0O3$9CQrU)ih|WBh|Aewqpm&alDkRr9C5%>GmCteR6{_yUs0@fQ~t| z^X)v~W@5YrfQ{=JqO>oxtq2|3pYC|w>UV5;7tAESLFqAuO0Ld>%vv^Oe5fK64^^* z+~nAIljvkZS-@c%9)MAXah84hP4qidEeia0C02EBM~`LJgIwm^qa84Rl+8zt_8(6W z75rQIp!p0U*fza$>;X}hPzF*I*%w9HeZ4mOX4>3-JT>YOg<&#t-T2Opw@*_Fb9-|; zjKU#3lnx`Vhfw?KxkiPMAbn7%DMe7MGfG#+M964=y#!lbE@(nD!lY7)U0~FD*;}*%H_%XRT(2@|Oq9Ot*B_*R z=bZSVvp9!^4dXq>v*$u+Z6Z=SvtV^xX-7I|`bO0bCPzZL9->1?A%d`#o@e zi2>)1t_EM!@?d^{6%I7trZgfAtvQ3dE+n@Yl({EQd6v?n_KL5nBeL_kK|F1Ul<){Z z1R$xuvKBar z7Ez|bEyce?oV!RHFj^DDMOXNXlC}|@4NQDW>cyYj+gC4t`+~}zD5{^M;|7TzJeJ&9 zGs}g>+IcQ+1>pNq5(4V2wJ!$e*-@F4N$}_ym(y=<3fI+&?Op*z;ELmBP}2S^#CDQq z-UmK(%{F-jK+Jeu_Z?gj?I&)8w!1~>Et9Ei+fp6B^tx38qGY}Vzi4C4iVo(~7uZq# zvf+Kw*0>0NN;79DMW>D1&cTOxFm8_)wj6q?_q7<{rQ;vfPa-OmOhquS7OMR#KYrh@ zD!lR{2!mlTJtz8A;3dACN3lSOmcHN=2y{ucKJL#Qr=~~!fWIfE*B`5*{6A>nyjoD{ zuEm|hMwoq|=K1KLC(^o;)|{JW$N*GmiI-!T&z(SjEC&p75_H)OfD^(fEZ$=P*U@QN zCS@?;z(iK2F#2N)aM9=MrFSm`_+sk5+2cb1EL^94?yfT~vWzuL4Iqb!4ZBZ|;GGGn7cZo8+JQCrnJ$9xlaNGht-{0BTL(0 zR=^>j8RKH+7rFaa&#m(+v&-U0qY&;8))1|9HINQN}*3gKCq5)hulcQPOh?apaP+l z2zi_pUfV7EP@1> zuBq`yV3z>AuImnj)|J&m%whSd3t*ZeTETpz;sKC83nCxta1pfB3QZ+f8N;=mB_#Nq z7t)*%08K!$zyDfsU@_-)aNCUY>}ynC0O_^^vlSu8MQ38HvR5vx>&1mz0?#2m0CsY7 ze+PTx=od1k7gXHj#h3@mFmP)#$H`a?)ZyBSr)I@H(4*wuQL6UaFsoB)8l9|)c8P%z z{!B}J$cRx_o149#Dg1oXH`9xZy#`&2dwMSUfYdg3v){^~|3$BoPU+4;^yny?fEMLb zHvqJbSw5oNy-UR;LZWXy6Qj0Q8hc%gf6d)g>gv>bMHicjz%@aCh0>rRbIwt7vYUng zL2+m&2W2o{+fXXD9WSU%vvGYoUpaIaJ-A&h0CDO4br&;CgcBR@j%~fTZKwV6#*%9S zBsf6&*>Lx(4$snJ@sQmU)PhZ9s!&T0@ShyCJgGlhV@VIJ3iLMcf5{>_ z1U{I-R!N6N8OSQd5R`)k6m&JxlRL|yjRECu4dn6?iArKfqZ^s2+9kB7fG~n;u;(=t z_YKE{QDlEOrBSi}D^q-4=uuT`n~1#>WPwmBdL`tNsg1F&G-SABfYbL$YUmA}hMaF2cHO0ur3RIE8eUSf1kW4*l;% znkmMTkcjo>G)D^}4hkhkxp?j;3Yd$(xWl$JNJg2Oc1+3%zS9~?RRQEC7D`)vw(d$+ zs*dnNG#D=nX|WmD!uV%D6ayFnHZ!iv!%*t+CadfK7Ky%^;Z#MW1WQG_f9CKko!Ss> zjGL=GZ_5dAGY0!g@mgw3V?>s6<$IP`Y6x~02i9MLwX6cDWV!qK4Pa`siC+I3G3nc& zE_}Z96Q$!hZdhIMD3B+60*S9}F!CKH&>F!nr|mooxs%cA<0CUnXS*NAA9S{R@n8H-W2B(&M|K>vcDsj3n z&j5x=^~7tAd-*<_`@-tl<=+baiH{-18^9SG&Mre+wPBH2v~F0$EY{ zLANXo)cbn)Ya(u}JT@sr4rH5%9q=B2?%=^cH#Kn8LPm^4Bj4bwRJpQDcJlHQb*}WZ z8aVJP2`=qHVVlQa2p z>{5*{QDh}_xwx)cf5ncAYpzb9IC~kZWDsMqs(zJzJZpMCFm>}@qc*@^)PMF5cgF() zpuv0)j~YqZ!zz^~=-6$B!5pRff6SKl_G(6|U1+H$eI&Lt zZTGl1N*glxrNrX0~DL2SXao@b&3Dr zOCD2KZx~bPl{&i0@{=W;-(^W4W?`bmyJ!@$_ zwg4Km753|7Cdumy%DaH3^||orHH_AysQe}wXj3P)&ng}VZJWm^=&mY#@5E~S)3o`S zIpj)^viNv|Zs3-tnGud2899j9J@Hwl`|GN5AK>%WS*4td%jfh`pcF#TSkM566Kpv{i}mx1Lk7@utNS;Lm-7%s z05+q!i|vT%+zV7DmBtmmj_ECtwF4k5&2Q5jyH?6pZdkBL5N1o-E z#!}1m7ka+|Daa%amPBS)M2>0VynV!RoGp4Re@2)<-3ob$sRGgboQbp95>Q_?inlhi z@%`LV=_w&Wq(IVuH%pHukg}kZ_)aQn+FLr*+nm+&3$}w!=&xOM2+X6JIxB6V%kzJw>*9?dIf5`zQg!0 z_K^s)GpeYuRfvMJPQ6^GKuv+D_cC(ne+?=V%#NCLrvOyK(s($uMK-Hi`rIQVIf9#E zpRjaF_NK<-VXH);2G?IU;5DqniYusvDk5D@Fyco_=pZwFO>Jjt$21YDgHs4#a;rRK zI-GcPDYSzU$gEOYfc0`LdA=2RqhgD{=hOlMrUKBTpS9raF=SYpNl6Q2#CIy+e2vT*+qO}b5;3<6+ z>RB)4s)pA4==q@q{QGovMt@IdJm8a*lk_{We6uewm;^>K0yBgHF%L!4-qVa@Sb;ym5v8ft$_+(? z3;#YHyDWSY5ic%hn)?h^;|G>dre#&cvJ=1$9#t{YGdARAtoPtun#>TZxCh78=zfxlaI8)<{NNGhe}RMUtSfBg&4LP#u2t#C`-%WG_R^iAFk8B&ST&f?apqVGGnw#!{P zrXTG2v_|&WuY2Qy7F+_JC!Om!;7napS6DY~x2ME7?pZHPZAwOq8(Iy7a+@f)qJnrh9F6Kfbhsbmze?~vQtt+ysn*J-9=g*o9Yx(HF8XJoxi$JCLISv_erI%$EJN_DmLs^XhR?A#bD8`XcG3yx`GiRi ziEGVIn0$5Up2t(gx8xBsz|r}o7Pdc00+MCef(6&NeXNt+@9@OnrH9m2eiyLfpG+Mn z6mPb7u2%UR+sr+7f9%=DJtRK7#H@VUAMOG)@b#zX84TJ}>7efkNmzGW3eOJ$+0tQ^ zCxKu7yY%ihSvW~ydN;;FQ9*WJxtW3)Pb2P$a&9kwe&ba6P&j!3tB%v%oiElQyR<%z z_DQVsVp7@cMle0H>zr+FtVI_V{$I2`UslYz5Y4=HM4ve#f3SZ!5i4^Ti_c~u)QY;@ zHKiK4aNiHQ_pU~0#2xBmi}0S^kzq^wxM1B4zY-fckK^WuTL{`kNwlXWjT=; z6W+?%`>)d1f6=1jq&%F-wx)e=oy(a+6pG0mAa5Fo;(S#_;a+-2>|&JCbV7I-iUMyn z`Sr@N`RiAb+!s>%=4*k?G5UX@kd8nqqZ5Is6Denv? z{IJKD;v%Ib2+h>^Q)8APutUAu~hxRf32i?PjGmvobpotANt;7KNj2} zKpFX;?x3++i&$lGXRSH=iwmAYBN1Skp0rk$@|^}f3cHxEyk|?z{vdJ6p(AD`nNq~S0PwbK&s z?o^cgyX9sJz0w7=!?|+xX9D3|WWNN*nfnilai6wemJUkj1sn}xfPAu`#!)Oo`hum% zUulxe-(umLe#BdBz8(kkP7-MwL<)34nL4eoe>@(Y<+CNM&{*~kr)-(R_qqIojY=mr zyN*~mq`~Hk7=OTC+=#T^TV9}Zp&LgCIhiIL9dV2oj*{=`@2#VeImZMR&*I3sC7Gkg z_NpTP#Foeez?`ph+(bT8`yD}3iakv#eh757RSz?ph}CTTy$9K$yKqq$HX&}#&d8iT zf4c~xjm>_kz)DYPNN?orfKB{fY5UGepielk>eFirVsc}_g4m4i1M8n~pd|i*Er3{( zsmmF(%>Iq5aIecY@dW=%FYKYzsT-}8s;rTWz@oN=2S4vOy93|Y7DHOt#UI#bsd)u4 zicqntknP zGoWT=CJOx%SiuoWn0FB@Tu$J;(EDd&ef%UgKo!=jHIcOmM;?<96?Y3OFM~eBuT_v;kF{WgPM4VISi=C>vS^9#BFu)e%)gSSiXM0Qpz1IsKMH>EfNJ z)O^KLl2DeIAMhAv-%0m4fBc{DI`}=|KvC}$a(rwgBZo=xwso){Dx+vX&b*gWegwNR zPo$=T|4S^XYpBoR*44BbHsjQ2{f1!5M)gI21Y%pW zs@W%-4c)}MWvAbC=wy zYUj*g!g8XXEm{59?%!avFgFX0d#y5V_@QNSuU3u*ZAcGJI+wdl($<_{QJx1MyEVU| z{afRd?OhKWl}B_C)mlqRryLz*?4TfIYZ1&~hDB2}W#GAo-L{Ru+s(Gbr|Z%Bz}6`A zG)q3rux4$7CoD7Ce_8LD5=M1DqfpXuXp=X3w-X#Iw&RD ziI=})!}N?h4ZFj6_&R6BG|Tqk@U^&A_>T)a<=d|HZmXF%^eYA@JBdxtU|Zsj_tS!M4+hyYcl*}Hz~WT|bg=4r{uLT*m5}7IV1;q~@B}^{ zUO?yn!8j6Ldyyf`(@Hs!t+MFbJ?9Vy^s#aBr#o60nDdA)F}dwk*Jbpg0im=uiw}M5 zN8$jwE@e+ce}G>RKnZT1;| zJj-r#Xt%x!Vba|%HugeR6rl>J_Nl8^kChBR-1VI^e<_a<+d(}*!?A$E{@o}WlOhwO zc9Pb+Pl&ZE)SJU;x%xw5%^{jw+E3Vjwn!EShyf2PUTONf3luUrW{hM;u!_Kyqu-+Z5%fAkHQp8a;94wCFdh`T0zJ9u#`dd&hWE5u8k0x zh*8#6ND+dLkqG+piXiVU)|7UlT>{DVYHpG07h3`F1Zz>tAul`c~tido3b5YdV zMJ$_t!P%1WuB9GL3R5=3Dx*8WLU;q!*fz_uf4S0yZok8uYn@2B4P7E{h%f~3>at28 z_}egIS$d|I4}CZ6-dxr_veW8arD;0*x)P+T%{db0@;fAo4QxCZTA0 zDTs8YjX_)CN9xvJHR=;zaD2Ea50SMKT$GFAg=vrH?40-ZWF3%MYt zu7PQQFR@sYz_MoF;;PCb9*!gax_}1oU|LhXzHvENm2(Y71WIATFES~pK<3O&e{hX$ zccJ|q1Uutukzf_ZwpzN*2g7?ujBE9$MU5GSKn|$dp4&r~oE1W0uzA4rgXxO1x(0pn3 zM=6V0_wZ(YSWqASIq6`X)5iL=yT4k$Iz<;~*Rd}RuN2IMy|z@yz8Bzk!pG-X*c@=I zIsIRJn4Y)UO((`>O1BZme;zrox6nQpP-oZ!SD=P5Dl)m%V=f^f|; zf%KnR$lo?5{upsrX%nYUDr34lTOIkZVR3|A9-<|#3|}o=40PW8QLn2&dgrwgGQfAe`jf6&rty8tdnoF zIgfU6WmZm1z7GlzpHxE|EIL0HWdj%nChvORPMhR1E7;=HS_)u#6iB6pHTIX3qyk>q zi741%txC6H9v{B~1m$kM=QiPtRkVl}dm#VR7y3|P@BEP`-taR~Dv`~+m50gUtnA^8 zXJG6RHKB|x*KkWde?erN%5I)A>*JK{ zIL+_{SY6;PM!dVehh?VC<#E)*2*@u?l7fp^Pxcp_of2ruFxKe9Z>{7!X|Ccgx zXFEb4UQ(W>@~evgx1Tzz&OnFRv&&GpEU4YX`RmMlA{s?Uutps6vuB_lr3sMk<^`&Q zbwM?)O>TzolpPB`O3Nbwp~8~ndoS>P4=2v)26l>Q>h6Dmx(Z!;NCU}UO@k!?rr6%J4#b~<@!93lpC6t9Jen3;e=7hTPSNr^4ryyYx5N?7Vwu6& zQT?WEUV(TDm3T5|MS@Zuz)x7Nh}(1j>NxpFCh{v1jIf-V_H!WHPjPp0@rZCPBk0J; zgOw1SI(m()38T{s91&6Z%m+3MBuZw7$6qas~_83Y}H9|Fwxh zR?&@x^K(dh@HghjG7h4|uV)MiwaZ6B$f!dX`)CTJQ$z0~)gYQWvB1lO~$=Dy0 z5{oZL(ITLn<>7LD>8DgcuCB1`=hzv;0l1DxG;)feJdvm|_~%;~W|Aa^;zQG38uHwT zf1;jC%G^Hj$8zrp;HnX1CmN7A=grqN{cipWjy}%`R3Ku?r(;7fsK3^QYmGDFp3^Ti z+dIi#fp|nGhthO~EW7IpJ!f$vBNo?F9Le=>+Z;>ouLKYBYMiEK?1Y!=Acw2y9gCeEQ; z%uyPbt1c4h`+R-IQahxtm~+Kc)gJPgJ<3j(P>9a6{zE!wqp@xcE!zJ3D$#TxUnS$} zCjFkAGG75fhvg;1nxAaf=U%V^a)8P*Ze*#9#U{VROco|-mWWR%lQ8`Lh&qZTe`8&I z2(e*Yw*UexQWYvjL`yYGy<1q&=Md%$^;|BR20(Zrtm3IF&CRfMvo(b1d}#xe;f3f^=Oz8gxYogYoj#{?HaIr+;(I=w{jw|+adKd zyUfEN_R311q-1jKce#0iPE;c`fyGnAt;=EkBMSnj%sL0{hmK5e(a`ED+*S@$$7XD} zmI-@iL7Xz^H>@U0JAjbB_h_uuQ4W`B;C2IL7By#DTLruPoZfA}?@E!Pf2oc9>DvR) z5)p-y@)>aZme8$5cX61`0=gCc@py!9-4g>5c?Z>Ity~!(Yktx8GS6F{c<&PNq{{tY zKoOeyHjR+mV-lRBT@w;U>QFQMAg z5fA}l0V$7sc<;w%f3X=l5z4N94CklWpZuWetMHv9{vTscbQn4fJO`We_3TdwI=2OUU}gGRU)+|V^>M6r&2iB-;78CGs{mN5 zW)`IRy~L-Gap)j*Dz3yZdO+q?B)WfwK&lvwBZsT}ktxBNf1JUeF*ooyE!M`(V3u}C zfoit=Duf=~8DpoYK@g~cyr)DG(#S7ly+zzSee#g9X81OBH}NzE_>_KqTY`mgKIMlv zlvkq+TQB#e%)E8PR`A+kqU79-Wo1zBllpSe=;WnB0CXv-mH>Z}#rd!39N(Jg6BNAS zA-5|spnpPpe_y8Xi7ehOdmKacc<4avPB63%XnCcKh58(zd?9sQh{S|XbPD{?fFq!0 zeBV80?LfXw>B@0RM(7xK_?yC7{td0?Zv|CUA0#Hzy%lVlBuxm9{1sZhiS-NFUsi(b zB)-Ej_qa%LzUR;69U}p9n%5V3qIk5fg-KX_R|wA4e{lo$?%`>39Y1S?_7HNJU$ZT~ z7eTcMXS$$2V+)zJxT0~l%={OiT}$^?OX6e$wm?|;5#c^(UuuJmtob`#sV{gMpyW^cxuc)0V-%b z;Zgaef40%M`95|%PT1iXeM=)58q?u}rzA+PEe+Fo?)KWd65?Bqo}V`e##g1omg>0$ zT*X>@yrW^shyZ@fm%;E?+Kt9qjvCC$lY*OQ8h(ZX!+38Y3{kl#aA@sj)1nj~vh4$# zcwmbL3)VXXR~>O{q@T2*U|f_zoD|KB;K^g*f0&TvB_nEcQLn%n`h3X4Hg!)vE2N;K zLN-o|BGVyf3ENR`o++Whx9DJfJpTt*6rw?F%pY$vn(ZN8P9j}MOkD;T_c8ge6q7}~ z_Kg*z>be@-0LrzQ(Roag*jq0*f%addU*Q1s(-mSVcYm*3U+%1g?$^Z3GPK9|y-Kx5 ze-i-IwND)@VGZeL<$uSxyJ5Ybtdl0%jt~WnT#nPYp_5cZ=JO?p$4mHW=%=tBB1Lsr zW2}{))-dZ5qval{&JN*U9U_dD5{*8cdOd&yE8&jVL3SPjT&ClKY+x$FDn-pv`h7j4 zTG0Z+rAP!c?b&(eJM%i$UninDI+|u6e?tymskSRr$elkafOEX@=+Ncrs6YLfW$x{r z<1s)n_v|S!PPm%lYX)Td$j;L>z8_;Gon12?49NUCn=Sh zB2K)p1@=Gr2$t>t6Dt{%{{$7bj1rnKIl1j;i$yvi-MsX*vM%^y!ADUiV`1gSf2G!^ z@A|jcUG>lP+fp@Sf>Plmp9)X7gyj+g-|*Qs_P}Pw?Y^>3aW@UnEtg4HDTm6J;TD|k zV;$sQU2Trcu+m3latg_H@kiQ5i(~qX| zg<8O<%j8 zJ&k6|v=kpZ*;E8G=ICjje?WuC^VXfB>YFV@q&|l0ylhHDxQ0%T67ph}Njgr+Gr*|C zB41zfs#ZA9s295zx>Q#1UzEg;gonz!Fg`I$qf?G;)$%1HK-?iV%hm4BHxGw*OY@4T z^U4oq`HvYu@xYlNoK|bSb^u~@;5vL|@6C|;s;9@Mh?AMb+^F+ff3!Eb?XP?&Zn#-y z#FE(Jg^oY+kS)^MiXE|GeK zfK8w@WZe9@k4iULe|aDIhLyR%Ru3u{XST*Lm}9Z2!|4V9qCc32k4;~!q%^*24Zh-u zds0i_oFEW#3X+E~bBLT;t(A>n8q{<-yuT&wkU~P^sRLxYDfbPwGIR_QOv0W`1Rl-& z;jq!8yacAPssUp_QA2zF1rv0RyYi)vHXU4>5Qd0|86~&!Ge+rN~ub`Jgh6lG8m^pT8QJq@F&P)l!fMF+4RQqyLh4=kJNP=q8 zUb1sxps-faxb;0e4XAxc9FgAG%sgdAyia8@Nk9f)ws7DB`>{{Sx1qLkF0z4nnL`?z)dmR#xDSGG_J{}~qx|TjafV$bQ1776VYncG)dO&F@UrXHje&`= z%*{lrC}~eGDeaGL^nGP1Q3FnVQ#8~%!sLQ5;d=GqfAsa6{#xn}Q&*%{y-I8L$yhVm zCEyt%$^I5ueMHiS{&J9N*HM`$f0#RuemNgqPztHb1ro9vp=49UxJ;jgOi-W=)zgeUF2XwjK%-?fn>&w z<{&PCXCCfzFx7~TuBWU;H|M=Ave1RoEd#T1i*8HZs59zk{_^Ij*8y>hJ>A)e!(mt3ApO1MhN_x|$N#be-k zpAUYA2gLP2v>~9R5C^Ih_m_QBRd^r7iw5LS!CiX%%tVyi-!D9Nl*%g`@Mv^Bi_uXk z6uJyOtEPZ4Fsn{xfi+vGC{;gGwp-JRf0dA&BE8+VUkycn-C<;7{In+-ukr|NEE0wG z>9f$IfArM|-i*?RvmAZUXfX+H`{gB;&eE*!ocv|2L|g9RH-DtZ&&;hPbkGTOMHeRC zXE=QNCvg^j3#i7^XU}9-DIdh7h(6~a(#>k+zp@dd_CtmPUT0dJNlJ3MmTea@f6DT~ z>&PNI-2BRNLISvW5~$S)Wo5tURAYvioVqtsQEIij=?HB*ZK=UnHzM!{Z|f6zU9tlb zqba`Uu*c-hkV6Kb9F#YZoen9s^Fr(4@J#*5y$ip}Ue2^E?d-m3Fesl?z`;&|1YpR2 z#8h)e69gQKkyPzhV90iHq{Mr9f97hshL=)0cPW#`abjR|)ZpCh2H!?NtCS<&uEUU7TM)yKVybW{{!@?{svR`Or>o)ZM_B#@MgDj{m@d= zEPx<9o5Gs+3bJletIBRKe=|FtU$TLKWL22vTqk*kEET1}OFxB#QZ9NbwE-4i5Ha~> zj*+%g-2aruM3+DB9vjG(%Iig9Ctvhie8#}zel7EH4~AmOGZz!rkShp?Dphi7*1AVk z>L|2^s%8`NBDsr(n?7I&dH70M-)%i}Uod-x8U}2$&+KO+AaU6IfBcNFlHsYt3#Xw| zg1fH?FGx79mAH2M_=$0fcFn2MOsoL%ISkRl5ql~yYo#v6J@-nHKbK-RSuz35%&0ns5PNVE;6%Xi>y=@tCc;JMPpSFy`QO08;&Ia#QI5pMNU2A`=1k6B@3%H`(vO z@U6$7mj42iiSJE>a&48&o8PJN2=Wua`Jn^(e;&=}h|aM?I5-8MU|r4J zYY6PW+AVa7?`^@Dj5n4y#>j&dU`?DSJG~w$JRoeuo>lL993N-pYWYT|U~eUJDi>;d z;q^UHK0bx}voAOkaw0w`Xx7NDhTDhgY2cM~mko%P-CHn|^M2Y8UP2_9V|LfpG!oYb%qH-@#aXdYd;dC)+ffwN6+BH8RW9L$zSFG&DA~v1^4&Bd^xIB z^iblbm+8sc&n7ZsCZQ;dMcnF^2&-8gp8YxwOpNjrf8q`vLI8qn@s;Ligl$5W;pk=g z?x28#4*_pH%A_W|6Zr#{<@QmX5?$sLsKm&JRE=%{v6^_1%3_~X;C^mK!(dSU(}{it z_cL(2Vs}Dw2M*$p1{G>>U-e2A7a+<}@Cr*cOo;n7Z(|AC_?IU-gGx+2Jd=c(C0O^x zl8~*nf2mR135}3h2!C2#kviEFZV6F5njQ~1?D*v|&;T3PLxQ<~k`0)|%nEatHmN5x zt|)P?65}HnxrP*TpBsQ0;z#kuiznGIpLPtiGrcEZoOdPrG3S6#(ePdF2R7bNUTGvf z$p2ra%f5O&D!Y>JwDWv@N%yb$3KbS3TB3U--{AiT z;A#Blb9Q=QE)8R90fJ6#NIpx@1EC!e?#>Va38`!xz!&I%xSGKmU(U0e}s9x+&z_d zC802n_l8xA?p21|P=H}4DQ}(Dy-f~oyDbea5SSy5RO$p7VQ)Xz)b6Iin1@$S=nA`k zY_g2@iv$s>=?zfH%4S0PGGj#P5z?Q<$6F6lHr&!wdi&O8v#1yX%B8r`sov#}e{!_- z(*DHQDhP@+yl7Oa$J&aFFxugRMECv>u$ZeHx(uP;rjGy@jZAu#w%0_wG zT_JRk)T99n6KP2)$39s~}4saZHiD`c}smekfgY{o_zCV#LreBW-rS zP5RMcVmKh(ht1@nHu01xcNg~7VF1(p5WWFg+V^~Sy)n%d2);=&G-L}!e_aQ-F|Kl- zW>cT|G7fpYTkRkr+dY{j&Yq^}cQWukfGUr)(3bHZCl`C~Kb|aL0Mht}rdc@7u92Sf zc60NWn#xlsE4?0@5mP0`23P})`X3{EGhSy?8hCNrt|$adh&So>y=%-)xpgck z7|Il$2V+u<OFL!1Axbu z5%aW%;i@jUo#3B*`+J=7@-!oBT#P49c{Wt z{?J6aNmT1V(CZB?+1`8k{96WkqJNpORNm|snwE9zLo4(DJMN&3s zf3$Ez>znp7zuqJ0e_bf0iNeRuo(3UH7nr(`iynL7w8BZRuT9%(cBcnNbkMKe1xa>*j^%qr_#>Cx1>+LNRU-nsgxrQNpi+ett@nei5fjdH%3Pr-|#K&`xg2ohiY zY#n3z)t5ul>UI>hp@HqvERUbV;y+!s3$CSjDyWGi8#ymce>IOexFn}jtu9c>Nc+~l z(~~frS)JAD{B?MVvAaEBBc{!;=rke>k!4f25aKuHz=uCQ^3by%VBm`ysD<91QiBlBpZ_1{uE&>gHE^ZUA5Y5ZdzK z34{C7%~=gTZJR}a#u9EBCW2b=-EO$Z0v^gKF)6P7d_+`+vZ|7v`z>9sV=tn*I77ZE z?0_?MqJ2HFWFs9Hu8Wo;|M|en3y6G`rjtY^06c%g3ox>*wLA?0cF_E!yoAac_c_gg<*Ts7=Z<~ zP_{L}?M;MmCNMSNqpZU&YX0}+K$Ej4=gGQ17f7O8mea9h1N4c8> zGxXJ(e?i7FBDdiU2r{XiEBZl<9d+kkCs0CXNilQFK+|8+{FjqF-G#{ZN`hfME zsE=f$;MrQI?NwQ1b^8f}fh*{)uym$Wdr@8Hf1@jKfi81L ze6BG$lC6FlW>5!0GD#w<3T;p%!RG2aND0-rS}w2gev8sIYLR8Fq(Y@9;>l@#gJt>a zf8r;h+CQG@o_ZFvbZ&XC*>)+3ukse3{UOW63Sjqw0=FC!Vfo0j&vNtcHh&%*$vm{1 z_{brWM&6H0Yc@f_8ef`|T>jKQJwn;JZ zENE~8@J`-PZMmYMLe*ni2^|er`J$a-{G|iVL^# z(su-K9auY5LLf1&g$;uSr1wE}f8YJ)vE@GGogLL0PJ5s3@GXJ*Sdc{K>MRCr)=#Kd za$gddcZA12G$V_+_nI|8%v>msNh2>O;se`VtEh-e3ONncY+X-gmOHpN`=v20 zHM|ba%9}&=qL;>HbieU+ySHpXs`Vo8IdX}klZj6>tQ8BEarC-67kvme$s(Ct@3jzi zLAdg4R^LIS+G!|254@4)GCtG#9e1`Y0Ap0l`9Jwu#Fd#lyVXRlfBIvPZcD2G%ZZN- zFJXGO8r{cewd>QF`YcxF^rRFq{=k3fFkEELBM}}^c56Z^r|s_=y_89MvNT)oHGW~@ zf{-+0VnRlK8uodUXxEY`FEZzHJ}!!Z#42AO$CLZx7n#$%WU-E6S+jS zX9WzxhAvFux7}=#e*yaU*f2Fq!waA=m)?eM~XUh(w*@A3+#CD zzcD{Prbv1cBjrgZkcw&u34y=CNy@Q3p;wpft!y+&VlFzmKpbXGWD$sYWAkZu-jyG< z0E`nxJglNGZor-`PjLv6LqX1(;LEBd8nK4%LWksk%YKs5Il~(qkf8?%(e~eG5D&@= zyH2!a+j-x>f982}Yt_(}V|CB19UQ}i{{nibXLUlo(T{EkQ`||;wJ->`S@yq}nAhi` z2?cU|+f;pn9y@YfV_HHfALx5n+{zE@E0l@?ue8f$^~9V>d{4WMQ%?Jw1R zT8EgL?a*-TnXQW1mD>x4i&Pn=R2F9HIkK)7Lb-}|Voc@uXlOa9#)jf)E(s4D2tx?Q zGp|?2Qu)K^1C}t%6&`2Fxg(e@ynC>_pa4T7e=K2|T;F6U5C%E3QvIj@pqbAyUdnwN?42OD@l zL`qfcp_2h$?&8nh=f6H2j54r;?;L{GYL#Yj*l8Z@H-X8vla4-v4c<4p-T*O>SY#&l ze?iHtZN&1ti(5L6i!A*oa^M~I9bMbRe&9x(-*}@bXy@)#Nt(Kgj2P*Isx4bd&;H+3 zHTw;U8nVMs7Z7ur5$TRQfJ9+;1r8293~dcwtRJ{PqRi*`u88+F1`9^}fqje-cvXka zQq|foxDh}w@e|r^f%FSZ`&B9d2;|0!f8QkS&sV4b{^|lvmGjKbOpd|vLP|`1absm{ zm|aflq!hIk;LNR=s+SzB-hf7~FsU+yh7;*SC-E-GLfI=yiJ_?7qIWgq62&otd{$%3 zD(WP#>`;0B$cwC52mURB)dOBq z16l(YkS2JCalTy zu+``*n`khJiAMv)Oebv)3A%E2|q7i9?k({ zlt=oqJfANWJ!g8EKI7BcNaF)gGsB#gEVD$Csc%#w))hNLuA6iGV!HaAz*b5a)Sgcj z$;aAJZUX90p%(JgeCxxgf84*|*ar)i_u90TrWBG(6b|If<9poX(4E3p$6(0j>|bY} z0z}f^*z{yB{^Dqy>Oia7`^}CZO&luOv+}z45H92;56_`CG3BG@ym6M*RI}LV!8XD` zTcFn)VNEmIQzC=KL#~MWSe{+VwvYx*R;=Ehdc<-IVITIh=T4Mmf6F-WQR))}lfRes z>H)xRk!yQkLzCKr0uRVo!V)cSO5yK)x9v&`rBi`*`mbqjm3p(xUSpyM_EEpfcNdCCA zLW7v(;U;JepwJrTfA4}(Dadb(qfSNvXtY!Evhmm+J=vnJb0tjJ13Djiu9q*`Ty%`! z7CA6en>`N#4|nsvGevwfY3}yY$7HyetL&YfUtyo`(bhV90L}uGxkZao*btb4}qa&Ez>-BEF)LIBbbIhf2ACr0DzH2%~)xCLT+i$ z?`nvhFN`);3XsgG7Hu=#0mYlTt#qT6^HE?XSv&Hv+NmxTa5$Y9?~xN_rVM zj5y6{W&Dh!{F)b-+TnXlWb$;wz0wpSMs(@1-r9jm8NRly+rh=Pl#KSq6x$ma(^4mh2ivM>B_+!LAyEr?DH(A}Yw}#C+ploS1bCqb)A@;_HiDok|SA@RKe-a<4rw+u?Z}2qy)fCM`t96#U zdSP}uz}}P7d#v*T7#Og8++%k1?Xd}y;y93|S3g5>t84W{QL+?*QD+MMO$I(x)y$51 zeq^3}XC-mEO8>4jL2cLrp}MyjQe!DrwD~6heqmaHN^+}Ozmt2X_JG{r1<<@V{G+-` zRlFK>f2DY3>=HEy3K=nJ;ej&25HhU>NazJHq5%bH)eWOYHp%D-vh0Q(Lq z+72_%mk^e?!6IWe1!#dAz@*G7#L7y8jd~ieKzo{&O(vpp+il!U|*HRA0moUiGRxISno2= zUw>NR_azaN`pl+t5*OFCp;7A84P3S^vnJ3AcBT8v2TCwhwWI>lii7S|^bG4L}$KWH`6R|ai z(0$SY_lmLdh9o0g5rTb4a%@OMxv&`qdZ0t)n!`fk(g*5Znmb!M+!@%+Z~V-ethf~=^S#+rAC3x{xoR3;wql6W`EDo zU6CxGmVYiQ)87PcJuOCyisRi-dl`^z{ft~`#?6+s8`@Sc{FA&%F6Z;$!{%xA6|@@? z@MZJX6D%LO(CQT4W+$M{oU6l5D}V1y02v5BKu7FO_#FUvL?<+qEv}LC_GGJmE^^2S z{2Y@T_VzzyARbFvG6!ii<-fx;P4k& zt7Z=(rht*Q1ly`y-sKfk#tG1^cPQ!dRPCwvEQ4OM8#D>AqvcYw9`;|401i8kUvSLdCJW!EajBSNL0aJj zD4Ev7j%;*o&rtEUB=dGYTdJ;aO9nHJ?3kNh=@p#IM*HPJQ)L5$$84lg48T|;)^!It z$Uvvqt&wPx1`W%njA)|{w_0Xx5aFeZwTKuLnnoE6RkdvGXAJYQxPOJd+?pS0#&Cp> z-!_k;Vl=i(e!a`F>v{43D92o=qLD^sBUprWlJjVPZrHr2clC``Xq`)^^V<5_gwE$0 zXtJs7al3SgIPj-IJaKNG;Tob{6kK#6Tpm zRlN)*zvWjZ7{DI2|9@Iz1+D6}lQq$a)hSRnrxdw@WgFi&w<9R60{D*()fH4iCjm5q zDpj0}K^o;RBZ?X-JMO`t)C6HKh+A+Uf6zB-hT%T;B(A1iF>+L+Kw$$63-J}Pre{4A zl9VTYW>ieZj%x33v?$I~|LqwI8tu|PS((w$6yJ6XVnrAm^1o79BT)c^7ZYM*kf%%2dh2UZt6eH9wdN3J zNXLNbsz6u;wyH^W!oZb;eY$xCJ~GZ(k`B*%8aA-={lOFu5Di&t1LXkdkq9k10t?V? zp66XhcPxkK1J}d+er36@J35pNtrSgN4*M@Z1?#Unb$-jitk#3 zcg8V+)hIq`BMOVTxK|*+_!`tJyw*opKyfO^^ig$SGG^`ju;GgGFIoolh(d8a5bby55ZLxj=&hD3$=fBs>xSVc@S8$|EI zvpE3S`7-qH+Eur~v|ks-Qm^Ts>^pQSswsRPh|U)5VqkveG4cL|{&V4o7b#mJIxIay zeWgF##rZ#}zkkvLQ-qqFYO}#9SHO#uc_*rI0e{km%`MHa#cYFe$Tr0Eu*3;@5AtjF zCdz^gGT?DQG0PMhTasP#XG72R>izpGS$b=+KSU8}mRDzUuK;8!W$cr7b(HN8yj!5;}p9oEkNEK)?h+^ynI z-hVs!+BLZ+2gTg_QnBnts9WhM4?2gd4~`C$+UhOxono9;UL}V(mMRXL7`v)P7eW0t zFQe?TM{Ne9zUwkdig211V*fy?j%zwQ`7oN^T+<=ac93E%WQX6)GTKxd7M_~ll}G;qCLmM>AX(Z43IW#z^<0A4U7 zw{7nqP&knhp!Z|(BG&Wl0FLO%cHh@swy|B062-L)y4*6fc>@RdGjuk3|6wW@4fK z2Y!o7O@~6Ys{ct+V+l96e_nX-+$9Dr-3l1((EI<7Jdy_XS4!j3r;X&zq=8$Rn;Tbd&2ZzeP(k(mh zKgBJ5YiC*oT?9_*bQC}o{yWjNrFO6P$U7c{W36znhp6>f0>fos-*Xx;N25#pREFu%??BuuwEic zVwKCA7$n6_%NlZ)AD*(=WK!=wHZS)6RcZp#Ot5E0;m58$J`em^3aC#dkjcJB@!0MD z?a=iLNBqeW(;Gb2o7q-h;bV2!wCz40WvI5{y&Y5&T%RUk2&osazwE94d#L&Aedz%q|iJkB0xrf0KfeRI(K6q9O2Sxx$ksfA+lS)KHkr zi2E+P7oq46K>3@|dciPS@Y?!c=vsBLY_1Ro$RsGy<83BW!$jmR#Utw5>3&T!fobU6 z>SD6dAp0w!l=`J$;|l0vYaIX$OkbjRREkk&p!#u;jTc8z&woAWq#6Eo2}tW67ix6V6{wfh2v{E6lK`j&3x1^Pli;-~0m^tgP(+ z@@nc^TIoaaYe@r4ep9HIfU-*f5oEV#-f$Z;)z%+hAN9wPiO~2InS`>t3%9p!vvvRx zz<&gOu^Em)xk%q+Sw&Dk^0F)#&h$B3GMMdIkAy1?Syd-}NiZ8>9pFAi;f#dB7S?f2lplQ|$=2t`++DW7hR*B09)AZV*{Z%gVvRU^reiG?x+-Dtb`*fT>*#_2p<4#KBdVfG3JBhCpv6r{I>@h47q8#< ztC?`vw1GCUo8%aw7Nw1kzlwt5$`hFh&Q)*VG|#}XLxPHn%z#z9-R%`YkKru=PtbmCep#RN`DC&Ku`KC56>F z>=IFx*{Kr9sAa^*StTCRJm6B_kp8ECtln#D$7qvK@-~I`5G!})XSnymM6;_*1)-AN zK{KCt;9@Fgl>1LN30VnDL-APpTCa#)4{-~E0j^ul8%9C(@pYYrjdG}f34cOhWqvPz z^%=Vp;sgv$n$qr7H0-^|m3|gl4umu^Xg4?ly7inS+kUQ#GSk}RSm7TYYAxH-oX#aN z`5z%)lrrIe<~@+>5qc^yhs%V9dDbsjaaEPzqnqK|-HQ#z|HCqRF1*LkIaC0uZz zwk;!R*Lw9qCDhsZL4Pz=UXcwf>)CJ9EVw76YB-dPJSxnTp9VPxPbn4<0Uyp~=-I;b zqdYTcPV!pkFI&&?20)HgT-K!c+PgJqU z%$e3*Pk_uSJ5^Pt$n z%WCl?W(MYe=~x~|S10hVN93uTQ(fv)$#B|^s8^>w3=}Co;9%jBc;OCQgjOGMlzXmE zN}3$oU>gtIyw-Gsb$@U$?y_Ax47HKMT8#P;6dr4`*xvuxDIyS=YQDmqFe~AGwwa$^~`Y3 zGO{OqkXtF%0T9LSig_Jn#h34aHq$2P6jCZYrb<_~CgLEV2pTTycrwm{q%NcqV+~4} zg7y{qB`bl!@i=ADo>n_J&4VS;Cm)C5`D&iXdWsqUM|OVHm6McQrQQyAF<(>}cSpEx z3vMSU%e3rOAAf|WARFLGE^D?v6bdc=wNyi6BtliBp^|M=zz5=NmWZ2qBwS8lO$^}b z9KTwCbP!6TCHRaM#u=(S?>&bQUo&3MlTW<> zj}vO=W2oT~T)P!p7&h5<(%wZ4q_?%jx~RI)Z>q|lWPcnQaBLGV2XM^8z z>JKk~#>T6}pxB@zR$ZP1_d25qH z0BHpT5ho#Mf;op8ko@ltbH=CZwXq*kUh>YF%6}C`9oS8g#cL9ORZTAvJdD+gRbn61 z89(SR2V}c&DW;+vyH4rW+|XbV#0aq_vN-{H9!!MEnd8Dxiicz0f*BHGLve;4=-&<=hFxAH^kP{M{v!}*lg(LnIm4ew1gv1}{1V0+0mm8xAU6p*n zqYxUC(u6~42-hgPnn{NUIEL_B>cEe&UVlo$3`z%Q58$ELIBbtloAjR542yr+J1QxA z!v;ueaLAmt`s>0Ygm&$r)497zHf5A_|&cDYSsx zQaboZ0APz@!%rr0!Ec(=#*%(&7m_QL(PVW_9Q)NDM{0X$DAPQVXrfwj!S1t=E`JK` zVc^`9eqjZU*q|A6)*COlG;tyBBSD1HtJsv+qP+%wsbwH&*Q%gA8>5 zbvhC!=6znH+MKW2V~SLcAr2otOn;2kXmu|tmx6J?wkMI*gaL2T$F;gHp_bnyn0?}? zgzmZK|A!ASY?dBFeEnX1P~R31!Hr;BW2xoE9*4!JnDZfdwfkX+D5{8Yn*telxR?~C6xo2jnXJW1WN^5b!;Oc7s57d=>an4x%d>E~@a}hfL-Av-kAJo6itg4s zPPLNlge!I=Vi;<50f4G+21FtQM^EfpWmg54Sbh`dgPMR|k|SG%Dp7Kk6yCWi<|<_L z)2_ZYBj&q~f`mes6PeS?|5!HC0$uq>-c>I-$4#wzYFYna+P^pXDBTFGrX{@|BQPdd%k2~-_RNh z4faah;RCNRZ@IV{I6?yYpnp~}S%0WX`K-X6@>K&ph6$pR{H@W=#N~Olg}!8DaSn4j z0}I^mkKMlue*#m-*JUC>|NZwNyhRPg#@7oI`$+ZsqWU)L{WyRD*?$e65Qwes$i&9Z z`jEBhLKv*b@fQ~jO<_SkPnzuOv;fLAO6xRk0^O0KR_l@%sLI@E2F4vL%0P(s5QSTT|)9jscvpHKX)Zm{Cf7N zL)r70#ql7tS)JCYX`TRDkHvk{>uqTr(fvPZ8Ou-jAM8_ z-wyEV_jk(mBY;!Ag19EbQ$VOF=YzlUyUzPwG6&r`okVWIZn|Mo5)Z5$5$5xR?+ygQ zmY#wK*d-Z)C4ZQ7=xqjCN)!+p^Q>gnWE|?2I}>hkMXG2~s^x94DKDy1Y}L}at5s5) z5lCfgylj>*5|)SgeC)4e^fOg2)G4C53_}cn7>P(KuVjG0CD| z%+{z+jXPFQQkka9n@r81#)CtznCx1=u=Tt{V?IuZc2kVkwc+ohTQ1@6JH3Zi zB~$DIYkwm6()(tHxS(PYOop#HW)N9$B6eBVf~D~8-d)(aOL$%?s**V4;v!(j56r_Ac*{c28rWJYf#^ocnreC~^an!ZwNHB!zb$|{*tUtx51i%_bqF#1(z zt65(xQ)$LKb4c?K1f#75XnuI5LIP?qX~F5a3KQdmiTpwBop0sxE_J~194QCW$Ue=L z0DlnhD%45^uE-!yLS+fuYOIe}tsHeW2DHq6kK&GWVypf3US=ckn%t!mwB_hC6&?#x znz}m%iYOD89Fa-5C@2EhUTKcdIlUz`lF*8Vx_ZcHP{wpOZS_`v`M2@!5NxG*Et>Re zi5JS^*x;c`^y;!HgQ{TyaE7KXmks2s41ciaCrh?m9sKJ51UrygkYz(8{V!c$KBbE~A3ZiQ%UwBxu6BCQ{0Z$JCwuEma{Xf%`y+%uIbW<>SH2 zm_!Vf_Ns5fLsL-Quyn4E1Tw*Z07-R?d4Kz#9&1qCCTQ%TCI*_a$jvn&F3UJM`YNU( ziS^s7>2!cnl_$jf$>Pcq>eO>S_o9-KGY&jP4N2K>zkXu07h)*P1ppmSSASF-Ll&=m zG4T+4BF2ToYG#xx>65MajaXf?rrQKLYGzTFC@q6KC%^s z9N?n~DGxOt{w3K1oqKF^{^pVtdNEb}A^;D7@PCpADr25F?^xN`y9spu{BVIDyvQm0 zDMX6^-P7(8h5HUlQ3Ej3Mt^A(#Ec^C$`nG#VoaUyaW78LcEvr9O?~IW1;uILQ5Wqd zxO8*Wuu)4fLBa<$)k|@@^t8$;HgT*)%G>0C9v3@VxgZ(B{#fw;d zJ4pCn(Re}RqVnx1IDaL%OdLgASmv@PdJU8fk%1^Vf7f&KStJ0Mkt~6Ba-s$^aJKLw zcqx_<6_2s%57`fn6-BKx zOq}A_@9B%W&F!Ph^J7oJ?Q?S9eRYwwV?(ufhH*||Q#YCDu}72l%`+{Yb!JM%yN8Ew zNcOebK0`Zpf`9CLZP~e?>(~rXpL$u-62tUk>%XCJWbEVHQwwdk5c>={ofsQFm#4$Rs#YK7+1n4D^$^)0hM}~zn&*ekpuk1ZdK{?;QIN)N5t=Y zK9|(8Zd!(nNHBhQU)92mYeoj5Xu6aM8Z8 zq7M@2JTE1q%2BP{M-NG4sly>Dt2EPQuGq)onb+a*W31TV8*?ATs8L_?iN*YGwugn@ zPtoPdd4Ga+s6(%hYZu|=x+7zB2gP)Fo(p{5OqCYDBxPPY>!7H^9^)MwizBx3&W+>Q ztIzPCLHnI!2Lztwc}!ZH>dEhN_LQCWHhJ{2odwsMi@Jh+w7~LKccQravR?*f%G^?D zsH$&k*}Ae4OY(QH~j?2Nyaof(W`2gIRHm*ze>jIpH3EO48e88#FcIb0Sa zM1QGz&d)#GK};!OR}(;6bcI1R5Ss*LEqnl<+{qKJFi%!~-kZqEjServKRg&kx4FkM zDmw;$tdY?@`68BBq`B`T-6v&rM)VmQunq%*8mv-StVrBFctvq2TKH8*jFAMurAyKK zG{ahUow|-dCF{ z$nJz==blmsL4x5Qr`oF`&#ipu&t~DfebMitxezEA8fyh?r0bheve^zBzv*WkRLNZ* z92BA|b0z^&hl`F+U;y<&u)2~Ie*lEV-df!G)#ngh%KSv2G{x;}QFxBh45&i+GJgxp z@Lw3~OO_13JWN>FQ?z1Fb8R_7TGo)}9wU`U8Jt7$B}XBq3dwkzmVITrEOdGmjY_oE zKW+g>Zopb-#i=AU9VX6vEdzDz^fDq1+KMB(UIdMz7wn~Q=fA1({|kDlfhLgWbA+I` zW-HJsr9+MWJm;m+cX$eNH|UZsI)B|bCm)Z=8{K{;3m)wDXh>rz$RwM|}zU7BX{F9l5TEaof+YlL-(AV>fG5PT|fK{LaL_0pt21LVs@45volgltU06NVU`XL&9oLf-h&P{Y`xrNL=|ma z-wecG7VANgfcn=NtE*B2e3rHVzGb54#&K z|K2drEMAqh?a6kMiZ|GA6b+{M<)sKW%S~n;6)V5^y1X+ILX#lrESDJZ@W8tFjbHwt z8F6@0XqHz!K?n-8Kc1B@l%k5v?YM^3I1=TFBzu%wwe<>@!FRQdZht`-!#fcrd#Cv% zCt)4D)QmZrignSOVXdNE~ho7IervKV^qJwuri`R#Ol`6hB&m`hfFgJJhL*=bAMF2DF$;27_%Kh$9^2PZD5{l&LU{DVHD=&ZLZZJk@;L1cL)n8 zS$CbV@nx;`eOOKBS#$&xNkylRM_@bUHf(Cg2bzZ&dKiz>A3;QQqjIhb+1-$(ajg&R z(T&}U#8BnBm>UTk zO2~Dm^8Pu3>;T9GYC+a_9!@JS@-KxrOycM~JCj@>cP?1Mbhw(eac3R&aa<>!s@7U} z7P>v(;mC?ZJm)k0Recb2VQ67J{^vMo?`oHGb96@CPJbnVTE>bRY!aQ$o_LfQP+tFs zJoZ?v0_+Ziv4viz8bbfQT+;wzlcDp}Z9!KQqtXRk$6ua_)=j&?^5a?7gWegit@wOpg?uosO>Y@~29SjJ!6oUQij^9M(7{ zpRNmsh<{?{Pw*2q`xV2nlpORIe4BY~YBVRSAxKR~Cb;aukbwRSvcHjT$v7QQK=_*r zxzALBS0BWB`W$8z6Hn{CZyky>BA#}KT9xBLXY*D1u3zGIF!XKB#S^;D43BF0`-9sWRq_-ke%-D0ap(e#U8! zILqB2J_=8FQLvWMhP?TFvAg#!xT$^zX!K&8&KKDDw^i%fv?klLAl@#PGi zrKSyA(_5btMT{}NeKfGpXdXw4i=hpM3{Fbfh_IK&(R>WhH92TDsewC*;U}>6enIOf z5Pw?Jx_U=5cQ8~l`Yl62Xm10o6U(VN*VW5AsKm`n&M?Im9=Z;_{Nazi9GP9%m4XPm zZ2KGSo?(nxBjQy`l35nMtBT#RXGrD_8Tm2_{9!)Ai*zEaa z#Yfc-0g~Ns1f0oGgIh2}NY5aEFYpN=$A5{3lE~(LMQbOVxVWBtfbJR3gGtMZQJ)NM zlf)`)`s^1+7gaSs9@Xfa0YD^Gb4}WbQnh|i8Q`|tv%h)Fh)6`pv2x2b(}Z&aMIl_L4VW5 zycwDDP5!1-Zku80koRQcyUXBgRIlK@HwECIwPwriMCpbyo<8dOvNDMUlrBAKSK?4j3t*FTYe^~jIe)hmi2Pf* z5^cS{0CZ6MGKZoM4%W$b84mO$vo^jwQGT=&X5?a+T{H)ahcn?*UzlDY4BkYAxx(KD zyiANc3S0hmm}UY%433gEEFMxdGy4rAhx2{z#-xTs z2tt7+<3n@3m5Fs?NG_k3xPKbm(=MijZN-P!PyU!(%)opWGZXt=WVc;}M5BBFc!l*& zG{e1=Xf_($m^Cdtbctk4MX(DN{hSm08|mz1=Oa^hj}KW&z|-vIE;FxTTMF;)%LTn! z5HDBa)GcC&b#uT-reV-|Iy&(!>s+>6r#H|bB0L+dVqnY{G(S@PO4ubQ~BjyELzq@34W5;+X=s8idVcw zDY-oo=XX!wf`YJlW|1D&9i--yXmdt_z{vsLL^dou!c?RXv%kFZs*racC|-RQ*F zX-QzjZ0$@5aF<|UI)7+fZh+prllVdI#5iPIh>vk>RJZ z+uY`^cV>!CDQUE?qN(^W^0MC6WC7&aYZrbrA9LZ$L-PEkIzo*dlnskOLsY;m; z#Zvh_!~FB0LeR@Lg}lcMu;Pi&6s5@7xsxu$JJE~|>sa1bu7A%P>>ia|x$|17YUrGu zv-V|r2dhGr)$fZI-x>uO7apjW3;{w=?2;S?IaiYd@@XS#p0DZjziiq8l|^JCjZCF& zL;n_Kg5q5es{p}`HfS#J{DTYj&m?&Ue$@b+cE0D0{&CkimzRhPp z7&G7(zut~_!GBQ_6H3OO(d0WU7x~R?frh8i&UWcKej{W=jWL>As8pEQpm)>L-SuM55&{2 zW?9`O?V5-fGY#{qa8~)h??Ro}&Xcy1MMf1b=;E|Kbjxh6b3tI3sGI7KYIo&5D=C*z ze z4L#4bZ!gP%v{DduvkE2!_KK+E^XKJmQAvZ4$qU%Gcc_P5&Hirs@wN=D2YQS8D~cBU<+Ia zIe)o~fu^)0W`>4eg>7ItSN>W2Qo}N!{vcQ$-fVI&NXGm06xKjmPc*k2ioezBXkl&5 zy%*4H*H@YlZ?EM3Gf2a0hLjR$^$*7e-U)GgrF3muhKV26Cm4x7Kzm)|5|#2G>qaH% zoMh*MD-#{&`0bYqMizD@WmTuzDPr@;&VM9kGw!Y7epZ|C<&Qefe3dJ3J??%@R!zQ& zbnj%SU(|$R9tRwc1!H#F?*U356Otl|9DHJYUkKK+WbmALduFSPH?n_IydIPI^5N0U zw*qtg4t^zvmPzQwYh++qrJCeYEkF56elk7-mzapzM2B{U%`d2fo-I5RuVB(1)_*tm z+}JI^!-77Bjfey}&e^c%huJC-rOG&CPaF^`aw%Gmitt`i*TEW2a*@^L1zHZ&FF$2F zxQ8bfXfHAu|B!d*n}A{43w=CrV1aCFOcG?-3o{x|p{whx=$Vcs~_zoeB7OH~A* zq|@jE8<>5hV}9s7yO*BiFvUPIu7BfAhx5>n=PbfS>|YY6d4ES8rx@~e3t3Jg$mVwv zSrPGZ;Z7n)FmtOA-v^tMf_MQpjCnSg&sDR9o(q87J{}ha=;}2I|A3+|Wv){(|MIRt zEr#FG+d~g0J!SWyha3{jm6Glk`_~C@2>h#|9J1-R_l4%Aw7U;Lr^L8UWPeb=(a(kW zi1V=6kDHJl;)6{<`Ij}s5r3;=wC4v&WQfO(;{z|ZDVaZA|A+ec&!aYc$CqA~LeUSX zVx)idpQL{8qzVMAmxQFBQeVq=fW17W#bto6KX{HclKo4%oB(%rZXoTI;BHLJk58@) zYZ@1dSWCfx<4TKRVe<%kB7g3?tiT8rNnqOdSvDW@{`N9tj~SwZVW!pb>Rhs161(Vw zsS^JdoDlT6{O~?W@pOC~QbyE~a;*|=@6{D&!3%>@|nHfQ?j1FUdrT1J>c@T4dRU6`o!2(vI#|1@|^tAG3SA*i}~u{7M- z-ZwwKy|#5eEj2$r{bQ6g@b%(}2H7QdX5M0Cmyx^O>U}39-H&jzCyZkm%nJ%*fU+GH=XCO0KX_f|qlsFYzMcq=#K(^= zc_Dqyz=IoQ^QEm8>VL~<-q_SVq1FqcXAZQ<6yA`I6YnpXMb(ZI0IU%_AvEw^&TY!^{lPgg7;wqU(oa z_hq$@?>;pwk{O~WM6>7@Qk^l8XFRo0S!HV(~{RTKU|0h&qv6yH`EN(tD`-HGoA zo$G+){W`UNF@Kxw0DMP(7MXBQVqi|*-U{{)&kUIV&-LdDX9~FQ%%)g1YjUdYYn5P~ zhUreCKWBb3i0`G5PDAS<(XCU#E5zo#b!*=Mg@UqxdiqXzn|fb%$1r;f#IsER%I7ooOQCBzm#Le7XZL$ph?-d9dmZxfeE zYBbGz0Ni1z3e6{5xZIHkYo9mBxSio3tRI*5+p5~wIYFVFfoqn$N2J8?`|o!O$GCk= zUPzE)5u^280uRL2BRdvrY@-Ma`N%>e<_6{Z6f9?iML;w4D7N((1pdhKBh|m?UJqy% zlz->WE2y-2IUdj(rMLtSjo@b{ZBNeIqQ2yDM&E@*D`e+4c;I-j1imp7y(rTU|45fE zX97)@t;A(9obVqL$4>vtF=(+IEnAO|(UetAZd293_u94POAC?ZGvF!aCC+5l%rw|Y z4{uEnuV7MzpNjG^e^^yRacY%>a@||nE`P16n`gFTa?D)RH%g~adZWR*3J2RH4+jOv z6!Z6k^QSGS*9N)%ZZbdU5AVXW=h}M<{g5(X*<&Xu?H$_{%I+LOu@gzD{32hy~+0k22Kn|5|JmluXOmg3}EkN@};dN)05%D>EsMEgp~C z{e=$Y9K1nWkSrC^v5URn7s&e}pe{71(Ie?egsu#AzVdIQ`esVxz@JhJwtB7|Whcsh zQFq<{jMS9gF3+sEmJ9{pKsyb%Pk$x?BFhLT7kzgFiPN{uO9;<|NvY}}-TYzfEjZ0X z4w+xxD9}xY)0v^%vsmu)a{D1NL8|==v*1C8Se6k4_n7%__`Ju^9!p_=gdNl{=myEm zGNQ_NlA!}8)t^9cZg767)aXa}U53IYjho{b?OCX|upCpo9DnHcpf=u1 zP09ye%GB?&YNnn}!s%l>gRGX<+B*dSlf#VVrXG_wLPVG|PdCl%E$h0y=ywvD0;<$U z&#>yC*slyiQwoK-_KVU`>yrdD5qxKlwAMU#FdAf<$Jv;wE&QZ8w8c2IhDt#8tt?#( zV=Gt4gQ}3@XxSmN4#7Y$dVkeq8_)v#WTgf=z@mUrtJvBg?KcXspqTD9W|X~|Q1dR9 zG8-QPLk1Xrno)~xSZX3@u;Z*&mAK`^#9t}Jq^UhO5drOW)Be-Rj1($-JRKA$;czNg zMv_hobl>Ln4Eo$jh6HAUA^wmcQm24>8Sx3r@!!n`iqLz1dWjHvJbyHq;5_3d9V`XW z^NV(u%_(4425nSi7?YCQvxZh)$%H!&h5#Z0!sb01HIb5bv9Xq&Y0OYfrm;44$Ix zf5w;x5YAjH8r4f=t$&(12~zXhb#*`P0Io9$iM$h_7H@uc9ZG6Wgz`Rf8VFLEeuD<{ zcnb((tOT{SB8;DoT8V3xcJn~}cr*)gNqim#TN)l0X9SY0`w7=u_AxIhW1o`Z%*54Y1TE2&isISfv?qGT5-NE#}mwd&k4SID#Vjvly{#`J+bnK zwlXSB{C`M$JDDSI*X+z4?hKkrfsktk05VOAg|>tI-d4d5PuacX`RYs&N+1?fl8300 z$Uku{Q-)$sxm7ba-V7RNKF<+<$o&UKK=`mvyY_#)0lO{e!Gt7eU zm;bY+i>@UuS-n|(=E98A^e3@6)RcdcR%4YU>whs(lmtZGXbMg^QflZu83S&wvSx9n z_tK4H0{6I?{&{^>fN%M{w--_`y+3+?r~j@^*g!G6#n_g}Ape4MsOLkZ_aBOP>~=UJ zUwPEhMn|zbu5Hcove}dSQ^0uk>ORiMh|jVU@$ zB?uFW2mWi{bbVy&@-L_QkAoEhgVwZsSczjVOYUODCF^L^BB0CpCDg-V9Mhh2f6@Tx ztML;QPsbDvTCKTqbk$1)(scOg237q2oqzRFgK1j^#X50D2MJk9eb08SzWv*Rhav$Y z>UL#}>kSLGks2F6lP5Nx|IFsiUJ>L=CP%5v6M$Er^$D{td{O%;88~fC`>E`FBVGoI zt5{=)psaGe=sTILk9(fZf%%H}u8<8EC`5TsPvQe5vBG~nuxtiZlS@;+aw_rP@PCSU zx3ouJ+AT2PYPE`@CZ}&CQ+8G-A)t-T(PXAR#0SA-K&N0|l)M=bt$S*gcW>hs)CS63 z!#(?h%lK};&&}^q;;~3fRyCHdbSFF1YCFc^Cy2yimL?Nd{cl6?Lq{Dq-`eMpTD;|t znG>ooY~MM_b1Te>Dw03V#zf`#>qvj0$K!S~!7gkh9)qd(|uO6sEL+`}X`? zS0NBcR91Ge#HYI)qt!6~q-$Z(-zKKBp-keqha_2mUMH|d@F0G}EV25SM7eI6RUn9U zU|Q}1*wk+Y=&JEN0PJFP6rh#;$o7W+v;mNA4{cUg)KR|PK-@wl;)jZzq<_CWH{r_u za_htT*$ zYT3jz{^F5px08GU6Pur4f>OQuOa5o|w|0!0^OV^^ zADH0!hE>p4{lIR5P&9<(;fC7uE8wsLAuQIy3Y_Y(06{>$za+5q5CA(zL{A#h)>(Bz zz;XW*ncWR`?Do6d?qr%8gEeLHb*Si|gD3yfCWQaa+I58iotu>NKdv>pxS_#quyEKgxY0H9p;ORmBEvs@78>3s83QtRGMH`mD&S*u-CQ zEz|DapdUMQwYf#?V*~J{1Vbb}9wLbToEg||36UdpwOIU>W0rrn_!{LD0%l$#s!$5! zx*CWIRN?rK{B;{!^=L4adaQE`z8M54nlXXh^Gtl7SDyG5t$Lba6fX#MnFu^+L=JQg zU=Gq$_?HzLY~~Oh0a53<{M8zM>~Oh;bS@9BD*3iBlbm2L-eRni{cDVlXTW`-5zj6O zg}mAs1SLx%`bcvdOF`+c$y9R7rPq{_Np*}$rQnAGkVKtJs=kfQeGuj@8}0T{TL z1a3s%^+q};kEhg(MDU0#;%^ku_?ZAaid`~+r1hkLQW)0gO(pRtKNty&ZEWJ63cR7y zqMo>o4FQFDyacbqzM4mZr4A#)c$`jSd}!8?lg#89t>Az029$#Lf1#p)T*7Hrq=jAc6xAvTsVQ+=ErzS-JhC+IR1oSUNg2h9up3QDyi@Bd z?rlzU$|8U7CFAt-p{mF1!?3vDAC*$R?3RbkgmpS}6nEMS|M6|ZjQZ|R{x>d}?VQ&R zrpRbSc10O`LMF&PrmYn3R0q%%_UxMp+Hi&_C z=?H)N8fo%~zKCbsr;6s9ZST-ETdU!dn03uFp{V8V`u{MjtA@TfFVDYxP19Sv zMXHq%N9yjppnRJHJG3_m^f0G?JYSM6v%jz;*MQke<>dS%*PB3DZCn}&!+A7jq_p(6 zO0P%|h^BGZ0oq~*Uf)2Ck~XLm)(O zEk>3aN`aw;a~%J`6r_I)-~r5W+DPDfgla{EC1ZK4g%Wt4id_A4W+}?i z9XWMbfPR*Sx*F*PVMJ8J)MbiI4q7NRQb?QG4k#47-qU^TaWKvr{mF@aY;`<0vfZk$ z7%Ec&2JnEQLo$PZt{-{<-a!54<@6v5qCf6pZ;j6n^knp{tz@VelqUw51F5=s;V?R1fx8dq%vkg z(PYJSH-j0Ssv0Rum$j62KiQrrL7f>+tg6Oph^*IWt42!3FLi8RT*qvdJ%wHBY%kbQ zy&AQq`I4lK`44Fc4!^QPAH{zuQTp;?mlcgrbR1HN?gY(SoJ4)^~_D9=WtR3;seS891BoF zolnWNa&+Svjj9eJN?k7gCN&t9M9>ef?q;DXjl_ohMFHSjCc#Za;^BW%A6qGspGG;Q z-P6g}%=dZNc8zDH)4O3}Lc#Gnv5w{2P%o1gQ#hvpsd z9Fh%_v1!#02=dZJWg^9$zdkO+7bWS_aw~WZdz||dOeCo7 zDIN+xsUXaNBuc}_idv0|ZiqzA>wmK-m(1_h7J7x`7&XD;Y%;$Q*8O5j!#4C8Ma!w; zriGI-YVafWTT=F`%)DHfj-bC~64>RV&Dw#!0IvtzGDHE69k!Hn$(v%zYfO?Z(DT}u zrMhqAlw&jQB4~eT44?&j?=S=S1Jsx!h1VP$FDGE{5+-^+@po*8Z_H#;IGL%>#c}BK zaJgO0WLd8Ixg&Uwut#Sf;3hZqOK#Lx(rbky?I{+*MK$pI*m>lgRKj&eFK!tffKx%wA&$N2KNGt^s!RM-Sr&sj>TFM+?} zRnUJnBtlC?XY+_Hl$FWsDmcUhfU^i%T|;S$MFDf&yFRlbn;_kILXLG=6pC&2bPHnV zWfh5bu<+9j+RDfj^kcX^Ln&rBG5 zZZu)fOlHE%mY-)5`Yys!NJ-@YTGNyL0CM!yvm{3^Gfd>H*gHI^?$8Nv}BW%IV>FzHC;OS za6&-}8_#e<{Hj+dqMs>#kDvqq?-+-E2@IFFQDN)8om+XSQjNbbTU>^#v_!{`i&!nv z?$HB;1vwNanbv@y`~C09L6o#~I(UDXKA+0EvL}l16C=_4w?xJ$X9ZTPu?QnP{|8Cc zRj1I`yBIr3AC+93E{#6tGqm7m*;W6MtRPtR_U)@sGJb&2Hd03Jm-Q+k>U(Y)>A6D- z+D%HP*(1<$t2MAm_*Kg!06B&0j{cb3U|D5rxrX^JaAp<2*$N{~EE4rDOVoe5LV+Fh ze}D!GSBfVrmgOXO^Hg#x4!x4Q2EJ9o4B{K*t@38d%)aZ1j3^Fy0@%zfEDV^%HKIcP z4IY3R8^W%wWhqr7jlnW~e&*qJ^G`R8mq6P1{8phSGtIc6go#v6&y6dEk-^=pS@abS zy+TkiDYP}aHiny=JN7N-x^I6$S7KLjRGeZ4q3mdvWZptzB2ZX6MZs}NvC=qYfJ6Mi zhaRp*8J{1_hmwOy?}#Mv0IS{O(3{mzxbOQg+TFP|_VC-eZ@@s^Y=dDhvMe`mh*&u+ zcrQyeE&&FS{+xErpu|=r>Cjx_kfwY?&f~3(t99-Oh{iLvjc=B(AL@Sz_4REVfh?kP z>c3}U?x&FY)+XD~acww!8(CJL8qtgnav6r0g2cKD>?0G*x?7^#!VT@T0F)heumGpt zn#ut1b1a`jKyTW|S1^b*ODP<*jul6L{DAR_f^XkMz?s7EM%1~v&`Xk9ef%7#O6)zD zMZ~0lGGpC#9Ue+r{nmfuU*X&ew0p=(Xt|p0`#L2PYhhlYd)_TL3FH(c zA2^N`J(}?^i`ENJY&V!4JNIc@hCaXJVb!UL3&Bz099MBg(qw;ijgZ1V&3ZGj(0r8w zdPc2ojFwBL`#ctBOQQt+iOi9&%m_QCOD@7=6n`)(c#>M+*Own0_ekFQz!hpT#6o0c z5JpZiW5YiYH!eK|0*My9DQgen?YekgzW4wJU`I6(!U_3y{+E>S!z~i3?`|g}QoNr$ zuZzU_VZ!$rmK=X88SIP+oSsKxP8=XJkt2o|lf3#wadt3}7-~vrpNokagZpVJnA5ZiQF@JP1Q6&nP8Zn^0AQ5b)W4oGo(eh*%jjRd;k&Ch5b zSF2u4%2Ov)f@0k?c(kuoQJ;K$2_7oC=EP3AC+au$@G{e++ukWYK-$^cEd8=_c|?yi;Q$0W9%MpwFrbqdyTs6M0lB0U`tLLC z+9_9PbG(1GgE@?;@Cj>%kE3akw36&aPBh7`+Nz8sZxuE?!RA~l*G_C0)7SUsE__L z+K9xB%UbnKbz`}|9PPCp*`tv3unOxfO>Q;3ii%%->|SdMvfd}{ibtObO}cf7t98J8 zy3l_&%oYml@Yu4>^t(Q9?L_itlX8GY-)M2M0uksZ2cZU@ad%n0nWOTYK=ssjnQzhX^OPE2jsg>So+dme~vaEVJTIzK!&Y8l` zpHh7uQZiZ9=5l`@H|;@`70IhSC_`_^od<4%^Gs(tkbUf7!>tr^ zGG*%Lx_E>OKBw|zS}6rJMvuY}O`2!AkuKI`E9b2!(K zQfoy4>7y)Dtid>RSY@k**W&M53nLmP8-;3F7Nh{^@lM02tlPkC4-IgZ>h6;}Q$7Np zrMNAiuy$c%!=K3HIW@}t@p*rI0wf~UQ0A9oKVjHyyWx0!P{JxGGANz|(2#eKTjIRK zn?C5XhhZpfK4L8@Vbl~A8zcgTU(*PNS!#gIaVp1WkB_FR`Q*(D5Tbo}XUt#|kC=tW^N(DfoRf(6TS9s80f@%Su7nVXDxi7bW-wTM_Kc;o?=cB0JV{uj zvg+R1U0imlzn_|VdvSj&hJMx|o+vwyVEHoXIkX0Y5rP~uGp%OgqHkMz6ox(h~RlIK}FooJiH)mQ?Si{T_kDIqOpv z)XY8V4pbHqIann8G(Pb6%(}G<+KXQq08cGV*6oCH+jR<6we@8uOOS8z35g!HkBTzq zO)MN$t3O5z;R$~S@?H_EPhxLWA$tcS$QliU2hCilM?Yc{ec55a8q+AJlFg`C4i>2fgU`uFiIW;;PCsc{cVQ*4ZDfBN+4{Q8{(t3TBhI1$6r8^& zc*K(T%=ZbyPlMKhJr?8TBgC z@`XB0KD34xnIOwP$R1y?W}KRoM761Ostem*E4%2vyckoUW^$ZSfwKE*E=L{+9X5n> zRxL%d6h~d-|MfTe$zXfSk-mwJ^xR~#-R6i^`>21V^e@r!xj!3}qgSxeos!FuN?4;@ zpX@2FMle>gIeVad$hCH62l<+yHR;r&yA^9|O;>B)vFqF=;^|&2>vCGdQOKHVv$!c&2*Y7qB2$Z0cgp*hquzhX|UpMf=LmtHMddbVURPLy2oemp_KSmNJ zz8`-k0&nqAUP<^a`hMG=I+-pa4_kJ>G^^rLyn)gEFgO9Fb_aT43Bqu;eXOHf)QLZ` zep^a(r|5v~(|1a$`u+6rv~`2&5uLDlNW-q5sc zu~C4*C=y<`$*DJswh$g+N&;J<4`Gy1hUvj*in>Oc9SmQQhWL30P_5@Kl4X9c(S)O! z&Y}b3|9(L;0|X?*L|_praq$_%&pb(PLkXp|kcf_`VAOqV-*h__9|*X{IO|X;6UvT_1Nigj9e7k9u^ce-p!o@v*LvRI<)3 zW|EGH?V4~tc1!*Zm{9;Z=nwM|Lk@rZ0~E8daUByjiZCz41n4ABqv9rncEkR3O$Pb^ z9x9eD9KrK&04a2j#b6RTS>qsk5xckaJkub_21widI1wV}(D(C+L+6u_x=1xd(NQ7Q z(e;!vykXdZ-8p9n7PCr`Bw8s;1RM+2!;IYmaGqsBgWVJWeNVmnMgV~HtDb+H8`*8w zU(T_Tj2vQ}C)6oEvz{h(L`g{DS8(49aoaySquJUR?+s(W{#t*NeHDJo%yY`Pz>FzG zC)Pep7J#mza3>wk5#nXB}da7)Nre(wVs?%c^LO*hr3Zn!C84G;xq( zA%2&IG!5cC^;j2Z@|59JjCo8O~ zv9UBm;t^#HY-!YZJO$mNIq*}$voCCn;Q>!j_2NyOxWP!F*6g8;q zlJF=SK{ggMx5Sd{TieIvhZ|0AH|8l&f(5ubSJ{=$1&F6jGGFdUt;;c}4?gs|7|GfF z5?|jeJxh^N$P{$N5C+7+i>)yLx&=K^P>a-_pg)Sg6JPXZso~=QZmUjbe1aW`EIV+w z2RrIg%77=Am9+;16jXnV2O8gVdETvIA=hB(EYjKRO-#+d@8Irz_TZR*HY-@<-}z+= zeuGl;Ikz;AJv{9*%Dh+Nh{gbkNE~sa2(}`rGm?kW?Pj2YxI+Y1jolDUV-M4h5Z|_UeM4y`Oaa3&0^4_7!1a7@!&VOM zpB5S#2BrsUp{{>Ih7vEO(sO+{zHpR65NcYKGpy!tAJiwTg0BBgwbt83Una|^kG1)_ zp4{jB94Z?#vQo}8$7WM4V7+O%-)D@@Y=v21QgAGYMe|gw%0#DNX*MXoOF8g)O)ZJU zms1u#e7q+S>60*-pk@3?bhCICkLBw8E^CR!+3V5n-EDt@8h~9^kZ`qZ_!liWb}I8^ z?*4A~qou}EG6eb3ogW<#j)CC4kM?&?@J1@EP;N{PYo<~3_q4~ec~nh`y_qVkf&Db| z|MI|jG1z%>Zy?E(D)dy)vtRLr9z~gdcZ+7=h8w4C*Xy7$;7umMC-e*z>4DCnu@~+H?m;HoG6YPZm8j7KVK$Uy{ zJaqx>ARCTXy)MG5v+Dua61yc+P}UUabd1w&STnC^W&z}q&i2O13gEINAIE9GNr1fo zo=nnN{P@9Q;nIVo*KrS*ZD(SC&5#j=mC9~$ma$_h3s9@N)CsGR(tZOqfka3@P_elj z0jYns!C+z?XHV6UKPYR_f{-KOih-aDOr6>On>jWd$Do+Xxm1~<>Um9vlwC_E;a=bP zt7o`3+pCA*SJ8$HdSaiU1H&4|*v|^dg)>XKyWd*p$M=P|DLkx8Ljigg-f|9jrP|RO z6{coK8a9b-((UVZwXO>%a+Nh1-rI`Ehg*MYg1F?X_wmX>N0sOPmAMWne(d;GY3XJ; zsScPTF->oP75Dc_3L!puQ?L`9lDS=)+cltg?U^j@D#r7)ityOPA2GFdc7Ma&04AVb z#NUNQxl5=w_}wiOKwJ}f>0XVx@n&WU3|O5blDM7l2#yx_%V8J25FS6HNXkVzNl<^( zj5O`hyM!(^rw)G5T`$3Qnw9NdpD`&rmY6#kNI2Iox&ln)n(G0$Uwv+0whiWu<-mCCdvtP(qJtjVD@+lnjE`uv=X! znLg`i;N6-@;g79cVTgX8xWj+4+sDLhm{GCb&^zMhOPOZ4`WHK)ksJP{-6IS z3-%DkO-1}s+bID!HxqyVX@K;#77w2-um3XHJJz%>7M|MQ%?~})QBFNKnI!Fk`9YR( z%HFaUbrLx8C^J6jSNXQ{Wg=PCWSol6@YlPl4=!`ZFfYqS$UqF?H4T5;Z0=_W;kjhb zCo%Z(EErDs7Jhv``UIEg1F!4B)KkV91i-!CgX>w+Wd>?Yt08Ci(Cfd0&lBFWq{ehJ zEOXHKhAR`YUaPx&~sg)Lw+JjUXC;b{Q{cC2^V;j146{kDC0T zn{S#VK>i#2n03QJ;WB?$E<%f$s_+GpVo9*G7S>AqS-S!#a~e1+?rWehWAW2JJ9OBI z07iTVr*1}Ow&xhcGbPb2a-14-+xn4e?o2)D|3xTvqbS{w8TSD6ePYjOqKm8UBqut% z@f4a1m+bK#{>`o_>APs=|0Tl%;3}u`ha?_`t4B~v1Bh#} z=ORhr(NNq7h7IpY7197iPH zKqEncxYJB!Dx?mPZ=KvtA;Nu{hh+>Q{tjp^s57knP+A*?Za1;n94Tg$3jp5xIW|L=`|&4)U1?JgizW*u-Bu7A$?>1O6rEbxTR@Vyn)MMLxvCl*p1RBl%*cvL!q9Fe@4?%={q4_P znV))#RW^S};foeGyl@p88a4V9nP(_#-M_$u94N|m%G;^p$ed`uob9G>JzLpD-zDeG z#2{)YY&-V`nQKL0gyhUCSb(%ex&EZ*&Z`Q688SqYPsesq1*Sw!oG2Y22H6@m*k((F zAM}lZPIRl+wf96uK>V$84ZxoBG~JJo*!&U@k9B|2(xPP45O6AXG*5qJ_;5eSIrwd@ zB+XRiJUk7VS4^>x%plQ>h4JZU*P-d#tvb5p>yQr&>xH^WFollot|*Y&#mtV0!a8pD zhj41Y_s0$TKB#(j&&;Wf5lhA~h1TbEjzwMI9ziNQ;2f2*bOV9#u1-=rfv*dee$@V) z*)xB;)xJ;kWep{Rd_isL6`n-B`3n$#Fq~gf0H7t*WcmVog?w_=se*4J_)(#~{hBS? zK&3&T3l(gYY(RUUGW!Z2H5?`SXLfck$g8_0`meNP6#q;OKfvEeRQ|W*W{R~zTB-}t zT+G@;CI}h{akTk1`LYvpe+up}>hNhH_Thh54@ZP>(7UHJsyH@*>c*D-F8L4`n;b*s zEbP6?smfqUCFt}+Z7d(2@T_mP_Qs4UZy-^wQ^l%NFgf!iOSFerlwl*%ao$<;`i-RB z@)PHrSSgHP9_@>~Qu_gU7k*8Va}ve5!|R44G4=aMY&~0%F45ScK=@cVMg@IhdMSS^ z%kmf3-n!9Z#JWmsj?{DYeg#%LxtqJQE4;7mVVVCK zs&Ul_+SfF2S5(}C5@06-g}Z#qy}6wtAlii%ApZLzug6Q9$^d`WaRWLFb3)YwCxf%b zQ!DuXM`|e(S7Z#W-Q6D+@A3Zj>A`>ThEF)i`W^!bagRQ_!B5MoEKWzt0)@&JS~V<# z9>|9XU9S=N{E=7CHWyH?h+kLqRZ3=xQoq6OeKyfFot;an&8yo2F+8y5g2jly8Z5s@ z-kW~_G%MTnW#Kc-pOfmZF)mX4`MGm{?uUMUt+O}LZ~c}Wkv)>>-z1J$H;I4#%~4~! zJSN~CUI?M%f)f@d54~rT3ga+Nbf=*a z2<+FA-l3PQQo0|(@q`8LxZ66+05v;-h*D_sCMcn^hqclew^bwkWWZY*9?CF`MGX~E zlb>kpcS!3OoW8wj_7I6`H6(vIK!GcUvQJ>K0BJ^-qBb+wZTNhvyH~y0JsmIaCwN$A zDk(U_6K4i!Snx}X@q$%f?5e}TTUEPb=ChhqAEQLA z1+NobyryA?M@{y5_Gq}f?vn-U0<85&AV{o#uj5O6me`loZFE#%fy93;m*M9(Yz3K6 zA;qx<>t4*Y{TbSp!{O)5-e@A~h8_?jv>?G7uxY&$5)op(>aS)czH!AuIVm00ck==Bz(%OC@ zRNOYEVKvt21!D?s2bgp}3-IRZhCwhz%Az}~`v^`gDB+)cN`M})r0OrF3>e8opr(!Q zo6Bmb7%g>msWp~a+W3|Hh3?50@=5TCOo%vJ$?m;MZK%3jq?o7-wOV;$9~UoW`Gw2MuO zK`urB{RTH4CFXxx^^5NMD@WH9dp$@JJBB+oK+1bw^wQ3{{c`7Sn4x&c=XX`u3$t&|3C|0c_V)OjGE-O%6`bmIDoP9g{VfhR)!&((~b6llyr{+*Q*w zqVa$w44mP8bMvgX1(a4G=q;%*V1o~l-O>m*s8VLYp zM$~qo4YGfB|Ey;AOUjFQ0m{DSOY#5tqg_37t)Y5(hIy{;;l%B}3EYWa8gxjjr7GH- z(JL>XFm!Bzyur!ExsZgjJQ<@eqH7of7~Q}Kcc0`2UV_P=>ck=QR}jXQSyB-WI6Xx9 zKT8v%^1hFNZ7#QXF?VrxDLSV`BV9shJI+=Y$WMPmzEWYx%~TDq7gCAS52H=!G#)K< zXuJ`;-tW4VaC)5a`d=B7vemtpHL{MGkZPsqgoojce}!2H7sxPH2bHC8*s*1XQ_1mp z9EZEVA+ijO;px|HBGSC>b|OA~zc3NZ>g8O00KFJ=G~TQe*cpf6*^ux9dkOAr`-dnz zBaMGhI;UY~`Q&-~){ehOn}caT>Xw4`P4`3r-aWV-S&2&{#cfIJYWM#3ZYhi&b{7tY zdA1>lj{c9Qn&h;!$8-vj{I8>+EcwH=Pb$34N32;m_<^}|!po;f^d9hPfzHMm7?Jvs zp$~C~S6eL;e`MVcVxB}+@Q4bQZ8r6TvyYoof3V~-ZufK%B7nYG_v+vv|1hfed zVuh1d&HjU_9EabC)cq0Ke9~a9J(Oghnhh0M@w}rZ$X*6)_c*=!X&0K}-Kxs+PVr;7 zjgvOgT^L0u3*=W!OuoEwE|NBQ02hBK1PNc>V_%}Y{Dsq_Pz_BWPan!zb$OO;#dm-3 z{Ga*J_JbPbz>qGLCjtcTN0B7DUA|-tGY_>}Rxyd75s@xv$XGEGk0OPMtAAmi$9}~h zp+|tI<+@mKL=?~Su0cP7u|2fpCBcIT4O=ZeMd_riw!!w~y(E+Yi_#Bha)jeR7zVr+ zQRka>(_l1TQ%eo|5|%?XGrX<`qQ!r%gF3xVr?OXGI+9U6GG%n4#MHb<<4a*nyNW7R zI8HG%G8QDhP4C<~iLv)?OWrGo#}y-lzNQ>F8@N7PY(pZvi=ROO!d6G`KGVE|oZebU zTr3u1zfuN2ke}dqkXi-;tkYWdQZtO6Q$Xmc%l!00$^P~Mo$^MVwwnR=H>4Tx6zR64OZXL(5?qX>hk+q&kuk(~K2%)puq6 zt>=9|#Q8!^CfG#U{YigtT}OX%`08;LYYZ?EGH4E<LV6%czj@rg}Ue|`HHf5RFFX5MFkD@*MMWh{!9TkLhrWG$>wE2@;1Q>^=smfTJ5W&(-0~DY#KKt0j(|JlsZpv7HNO6(L*ff4po2683=K@=y=!?fovgB zJ+Xz=((1;vS5{9j4hG=E*RfrQi^VQ^(4Rpg7amUKr1k&y?1H;ENH_m9dB=Iw9?+Q1 z0R)!K#szC0o9Soku0zH8DMP6|7!h#u(k8LiSqNb8TmjB=Z@t*##k=lmfc5P+orRYT6>06Dt}g z_;;}Cr{okt5S^=vwwjZsqtKMzhrX9=^tX(fSF-(r=3?-bMf#oPwQU={Sqc}&&{y7= z7UhWd2x;xYS*WFLm@B#M!3wz9JW`eKVZ%<58G5LRQilqz%MwM@R^7ytqtVUxu zO96es3@^YRt5I2HYIC1OB<8Az`5)tqN*dX!-QjV57t_3Gwaaa7PWhXOHKx5_qI{RO z8oa1lSrS5YPY*;eHD&ayqi2+EPUBrc(ILhB?UvYqvI0kYj+T;Cs&zMy+$ZNO*zlGN3$P^R`Vu}v_2+(PXcSvlu z=1UOBg0{DIpuOXAp(x5mJs5`4*F%$+tR%0VBm94)Y}PLx8a{v}wc zCxw68g4~}DB;^|J%~&3Qefmu07sKkueMdPvIDY@K{9^dFvczQ@&GH)k{VE7eIbX{{ z7bDvu-TY$=Fg}DnpKZw6gg|GSK#=TNX3}9UR;+u4z;6x<8LHC`EjdY_phGhS#%q0d2121kqu!>QUzgrgR#J6`FrM z;4rw-(nCKAC(T;4?!YUM-dP1!OAP}ERd8z)vatpL`IQr`Clk???7+Dt4@bFvJ$(*X;bMZtTe6G_rgO|vzD_HbDfcJt21)kvF zjy_1@240ltKKAt!o!S$V#+vx0%+{+a=7Eo#irb~|!-PE4vp>!Tx7B|oILfDS5G*=b zmf>J2g~krg%IoelM*?X1n)iQ`^6_s3)u!3p{_OX9gaO!CSldKm`df8CtG-p2C>^16{m;Z4a{zmgHH|(j2Wr!1s zSiN?f^H*>Q#2{R$fche-_1cIC z2J;+$91yC^UQRB|b>3%Nod6O?@dJqL!hGrmI`A#dP&q?q`^jcJuA@4djh=l0rZA~d z!DUam4VmoUNf;HJqfZqnLb!qEhIuIA04}D}1$xFg6Y`GF&s@pQcxsLiH z3xQN?XW*m*rn4i!y6|b^VC6JZ4rAQvTTswR^qoo9Y2t@2{s<0gzZ2jCi3!8iSYg<970>hh zl9_E+gB03cPgvqq^w&%&t@;oH)&hPv!uZ`$JI8TtnV z=rZ~54i!7LuN!AAiFb{5IAr33iy30rXSILlxMLejAJ@5Cq$o-V29)*+RKR!4 z+rMHY3&`~Q*RwPs-TO2~qed|eCGi3gXTAuf>3)T?#U$`zc)b1Z0w;kPf>nF$E9>l2 ztjCoAi#)BD*4^AWoK0WfAyeg*kzL@w2YN~Hm=N51>aqiK+KXyvd_~82&eXNQtbxaK zvs`}^gHeRh5iy!Q?7_C&kHlTWaPrGk5YUnJ6n4pA&qk#iIE86O+u%74jPNz1Wa85e zkr4N9>I(0$Jd)qW;*N+U7@w)pl5^pz3}S$}q2wy%7MNKQN;Q(LD)IqXUHVPUA~x_q6r|$$!!WpD9om<+}(DhP4<5^Z1_K(LH+*=pss_z@F}qX^Y?dS0IYb? z(}@a2OuUK!Gh27&*k3rQZe`*7ak+0h?zKDm^T~woGn!MXJUa+kj{amH>=ocpYyGm& zyR88nPdJ=g+towxg!{W;&X=>w3(+DB;ryJ39{moS1|ioeI~{C%R2jM;`D5Bear1vX zk%hiwA=u5WFRNFOvMPR~@eKcXqkOT7#hL(~Wye^ySk~2De!kE77!4Qjw8r7<}DM zBp>pmPybTbxs8T|Z~(Y0IzPWne%%o}j=3t3_DITsBbBcis2?mTZ@F~kR-Fm@lA~}$ zT|Bin&Y9%X)FrQP%I^)hVfVggMv^@Xkd_Ta`$vk}JmyhJCPwVzfXSkU7(<~q3zI0QbJpzd9b{u3Nyd#d6B13;c?l#IG{HA6t zi?jD?XET2_nXWmsph5*zA~0tw=R(Je&GFP9JRbsE9(#6b-0gr8h0myCi6~k96VOa% z=rdSn2M_!E+x1)$G8*d>7~Wvmz_tOWnhK%dK)9Ny0uM|U zCuUG~WE{Negr1DB{vUrSVC|cWfv#Rgwd2*dYcziultvKR`(_JsA<&m62_>vu4cxrW z+|`1A3qFe3I5m`*JsE@Kg|y3VM}J~v^FZMpU)0N3+OT#rV0*E1K()1z+MJ)^6>2ljvB$Vv}T<&j8^pI1_$ zHx=`2vl`h>M%?aA?Ffxo6qY-)n%-s=ghDyK*6ZtbU%+PUKv}mG>lW3QSZ>G*T^_C} zQ#6co!nA%B4QT_kQ3eFr&WEIc?j4}=&iM8uc*GOzo^R>gB>Vc`tUCI=*jpaQL#6`! zc>w|$52;qOUig2w)asL$$MqO$?^;_+HBZ1=BHU3d`6dbr!t!%Yxehu02qi&!eGQst!rybN1nT6O3&2C0uUiWqig6V4{~-J@zKvDT4TR~n+G${ z>p1;{-A15j8$Uusb_|Go@^i83`9d??_tQ!VxX}T7^t6BA{uuk(m5l5*+*wP=WPVLx zF>AP$A;9ax-Q>E@r+95TcV>^_s_b2}Lt>x$cHKhZ{mk(P3S&d*jqhz^(?uo=_z_-+ z;bq+M`8&6PU^^g|^Gj0l*MkpAnNgVSyF88#jo0T9!;>t@c&sO{VTx9ftxFhn^5{ib%8!J$~DhT;kPd;8tS zJ)}qSvv=wcCK0k`N_H02lfx?iZ}sVfoVVPS4I9fIIt`{1nhe%X(9Aymwwl_GGGbHZ z@AeR;U2OZ)x!!p<795hRgtztskQS3rjTD&*`~`oW&dOe*<#k+(Qk&e*=*0}5IlDA? z$w84Bq(nEqOyRH*JA&~=mZuci(^0n~=^Sw#hTY@2?KU_?G5I<(vJ^(i1oQ$Q?VeJ0 z$a&6lv^(i?0&|8mAIQuI?d)?rDo)MB{yJ3UPCLg^m~6((`E_`#r$QDO?QAuOl1p17 zIsAVq%r3zV7MR?rYR{B_i@Y41ZV~troT&*r3$t#~ zl8csGndWhd05wp-fk8yCBR7{{Z?qlfHFtY+7%=Od<^;z^;+pLgcVnRsT2GWq9P!3u zkg6I=W1C@BQ(A0Lx0n}J)`i;dg}?C`0x*sn;iEyylACgoQ)OZb%6oyVCse#zq-%fL zhb4426?Vov&kKIt=M z|Fpi(?h@NFI8FtGwzCV4UrWAA?dT-$;A2jZ3M}(CC1yU!SOpcd5@5kQdg-sbG5;Jl z$H`=Xz~at|9uARZ9Hr6hv(Ar z>ePfr>#{Xgqg2gyI=-lGV9?`Jr}MLaLqC6LOLuy{(&G&o%^@t?LgU8=L3kNZC!Pr& z4l_1)ruy9o(zB~UuPhyM5G?X?wKk(&q~2YdP4Hn`@sG)J3C7oltrSO)oHwP#1dwmL*2LebNLb{B^*}PSa8hV@{&aKXZOrb zQbU`FWrc0zmfn`{*AdYYYCFtw28zs-)QFL%?ck8N=uSCKkOFmoQqje`2-U5MA3j1F z{{6WKxX~^de#Gjo#9b$A3lD%LZO|~#C$sMAF}jIny>{oo6054LCGZEjM4xI9Dm(e1 zs-jxCLCZG^fxD1Jr7W2#1aP0CX!XHq8(7EX%eN{mWI8)5<=Xbiy7Ttsn-u#&&m3dZ zbW0ucYZipOZeT`#XHYk8xwStjevc*4T~E;BM=3O zi%#C@A~~5AyjJ=}D-+RRl>ExZ5G0NghqlActm=3P)P+y?M9ro^O!6df63FM7P4Hum zg7^|mE>6@BpQshXq~+IjRsU;mfb*m^BrhDx$9+jdqb)Ii48`f$uOInwiAt|s(sdPM zO!A6Avv8!w={JvT`*+*sJO82*>=yDj2={WfwJg#1`q*r%vqZSzK_%}p?;L7WKrCDn zDO>b6VacM{G&QsBY0zxM!{@jRlK(4PK4<)Ph+tS zasg2~C#=YS`8t?cs?I#I`hugdWAIMj0O>uupF<>x*rjWHzusA8}=30ls7*WZ#<3fT%#Lp%#b;g$2e%>R)- z`OnN;u#*khh$hz_8yN9o^r6zV+*Y*ZW|8#bbNhApC7VG~Afg9`2dMSS;3P(3K2Q~# zBm21$6{R6$IJ&T?7R|XOzjB#G4p zPs}0K>}FZJV{9aUag_sVS71#~2R(W0N81s9!Rp5cd&ZhzZ>W6(3sTx*WoVGDICqF0 ztzQsyxQbP~aUje4yIfwcyM8Puv)=;M#Mpe^MdZZZMmeKx4vrJaSka$>K(^WeH>5cpjpVedcrUu<@_O8Q;Yt_5f}t&) zO3#nU$K1}E@5j!UqY75kf}J)lgO* zfr96;<+f_;I`^@d4W{=AtwG$Ce63kM1|cz2hN+4<8&*J^Tm5E&$$HqHhj9hh&mm%2 z4e z65%UR4PyjW%D4Ay#HuR&^rD5hY0ph_)o$7`*<2)u6{!uB@R9DoNdZDxqB1Cg8z2Rt z!ffS?F5ZhwwpAFM+eUtM?y>Fp>Ja&uR#JcyPpFQ&6*2obYsjRAhCT{I<(gtv@ecfyTN%r|H2pVE`uKBrqXlmz|(k3== z)$R<=ht3(md7e-?y~G{&S|x1bl0RiUkJ9#3xgqL2V;3@!;RI|;PO+@jXG!J!vzgHa z<0bt;X*1K>adyjhpJ{JEk^}y^`ReRURdIz^M*@HC_bPSQnABuo%I+M0QQOrvK1*q- zzk2rfkV4vim0VGr=vg$`c3u|Zq5DcpD!G=v82{A&-8`DKwYIpMfU{t3`2~Wcg2f6R zRkZEhN9=n+1yUof*sei;+d`Z)j>~1oKpE84)QPf9R#q_@zXFM91L;o>v!jT!cNdVu zHdM-nIUgG8i1f}=_*FZ9tont$svvvRcgkNoxm?h;ESHN_*YWw@2)|1lg*A+CYYTKk z-l#{j=TvaKcj0&iNTN^B5Py&n>&za#X-jbY2!`I2#(qE5ggRs`Ca%g^b^isIhTGMx z{J!})&vZ#@Mly5=H^+%h1|Lp*hCH;25p3UrI3CLL!vaf27|5P~Xmig)x!6qD{)Ti{ zeUv!Wj>k*jG%L3@*GmGToanKzdz$t#U=tgag>Whsb)Vu}!8d7dQhWW;NjPDDGK zrIZ?S;|?_{TGeTtQa&&J;g<(m{-zkfUb4C|YJRs2x6*LAx4|1rXU_sy*cD8Gh%e=LsU;wwVi zR~pOoK9(F&>EfJXZ(MRJERwj`@Y+vgvsk{7v_}B%{U&YkX0E0L+e-aj|0`w>p)KI) zx8|dzbUa)9u&ge6u-)CGW`tDKdZg2Kp+UT1bP{FhY~PwUYE~DJy$zEy5Pm72$0_7j zyWe9*Kui;Vbfx!9qRoDHG4prV1ieESvJO6RR0A{zqB!D)!Qs`QKevoE z>gz>qA@QN|_XeKUJf-ha`#OBcMKby?t74Y~w>yI}5ixgWf9<)@cBEyS10qdfv(oJ>&-2*npNK+0c9-w+S+`kbvk%p(l_=1G(-= zKMELY#dd{R@M{v+61?=IJTWP&2RiVdF^csqf&fp=3G}vy)lA#g5aUPohE+ckA+Vez z(bZ~yX8>|77HXpYjW!ljgWKYe@r)|-v|L|V*TQhQ7vQNU&IJ=lQtMA=2X$&EYnw9D z6u&LL!GZT z%g|1LQoMI`cV)=T9gOo!5T-&w5ZRi^zQ^5vk_G5|%`9Z`{zw3R1vS6Eaav zk_uMo?OuEvgWD_2F(5{SoXn|U{qq=xZPA_Au4$S+P9?ul)8xFX+`fuAe*?}*-Rnr- zdLI9Wc#A$bE8zl1}p4&?U2zH1041@(`HPr{e)7 z3{b9=zI;$ricZ)r2J7?FX(~SOPh`rK+z=@NcOfJ}iH?%1^yq?Dq2LDdP9d{HgujAm zuNOxFlYkkjilUT64pL!(>d8h6f$Jzsf{3xb`K__KXB zqqy;-nJ2Lr-Fgv8xJqT9tupT*7`zY=U|&=jhSg@W;O{`IZ^b_Onc zptkzeEJL&}uNuQ6jf^yeriYqzIHmFy(6$nw?H=-?fKFS$n_3E-zspTe6Oysm|2-G9 z(RTS(yee#2h;79j4A`J%fHL8K^?5YcbrkCTNe#@G^5zLKVg073A$6IK%scLXRR9Ku zcVg_fXyf{%x_0}!C5D13UA_tV?OD`;-LA=`%jM%5$j)~zrK?Q19YBO^ENzbhGbpY#jb1B%*&;a3Y=3YR0kXcknmwyHV`W~=#3O4&MB z_Uq)tCpko4Rz9!!UoO06Bm93VigGoL`tH09#$=$Tsj3~97t&OKpz+_l>U*f+gnk!vq9$g4%dku#{I!R5l}|NW z^f2j+?O;iZ!?B^70$mdjI}oU3T#;RIhmr1~3u}qWl|q23iPZjEK7i?{rMf+)y>+Fr z3kG?h%y!UrM8CH@Uv<{Eu!pef@&MAa@Q?pA1UZ_^0r|wLTVH1JoX94{CoB)2} zZ_vptQ*Ie3cSIw9TPS`ABm;D%phA@seC$TrUDXiAu!ioH;O2#AOZftzT9|QVjN`x( zu#FE1&C*Wll|O1MXACtDVVu5Pcy(g^z4mLX$9W_^BlUf@rWGD-f*Byp^d_|A_G3QygM{<) zXz1Bph;G+0osngB7R(Qa*#eiy5%9Ag3BmN}KxE|pxwo%f` z+vux9BIL4v3Dg58F}X5fXUfN*87g$@L`GQL-1c2XvMW*t%2{`&(;V^9zWsTL$Zw%qw!xyM3T-5Oz zKDoZo?X710jgGXDyvQaE%sCEdlvM@>;x1}#v=pR&3-7tp`>}+Y7g~>Z?{~j6;*xa~ z$)n5I%Co1D`m4ZC0Z==GOsTw7V)VROb_bxS%VOkx>}*?Yw1Ks$h66u^blDmZki4!H zC1k;Q^+$L|xh%45io>UySVQ0HT*li}JgjYf@U#m6)>x7ziDj{=^vENO6;t`_lFkig zIwTE$HOt0Y;^U1~3@HTRnetKLJ)5Ig0faGktamW1_e$dZL3>3UN-9_|ZMt~jB(d;c zgu*UxSXR{Y&Kr?B>HUl4Toz;ibfOy9UAOvtDr`cFM2pVj#UbrCKinVb{(SzT?0rOD zy{6S-4CYj_XDG~~;Xg!cN~qVs$(Ip+Jdq23q@rUVy00e0My9^p+~|0 zz7)A&V!|8C1i%?#cjQr+h?xeK((!hYtvg9<_bl-d%7a+&pJq5CQw}bKgLcvjYssd6 zg7(GDF4WJy_ok^T-z;W)Hk}NF;=_8SsvY}gBZJbnVHP3}g8~T2brVl%F*Xic5Ccp8 zC_JcHLHSFMFVFaeyXcxE6}brKLIaw{1m@Z1pnH$9#TK^Xinymh=|72#PfjHrS3u6W zu<_q8WK*J7egfJ+Re3{t_9N?yixi1}Mms-!Lc`(6>}#Fxq(By5c0TvraLO1dGLhyN za2Ek=!}k8zRNOQ}68jLSY^Iw=_wPKRU%w?PAjpQa9!gyFUGj%E(Ay1XioT8MjX}wpR?rOC(M1W?faQfrl23(Sn{^vDqg~}WrB`u{{+719_gJ*3;}iGjOy1;Xd!h^9 z6fR7 zqLm%Be@)Cp{DAv5F7tT>I!qaJlD?v33;D=Klu9qcDbOe+%4tT|8@W%m@9rq?+Pz^F z2{aq?a*v|PiJTBP|>g3+74-{EyD-ksCgrde6%+la-pAzC} zHEkfpB34@7x4mnBk3)$&D!+FI18dN0KQ~l1?xIs|(aa4m>M1M|f%2Dof#pgRzZf8K z$Z|Gw^z=z65d3wglSnE|gDsQmTv_Kwdw&~nz$}=(u;a$MviM6DWus|@Dt8lPK$&fa z7l!YViQ5*lHO$=p%d62X&(j_WS?lAEC^<$+$(D3DKxQ_7SK0ugEL5;_0oOHog?})< zIp<#M+ZXljIztI)nKz=>6V0ArVxS|Je{XQeEf*~)^3ah3kJ@sezFs zijS*EymLS7bC(j$7(`;j#FPd)&~Ia%YIp8GIYiRv@xgfMchz#5ko3UC--X;y|V zY2VK96HY|DZ;2;9mVKSl6aqg+BPyxgbX%)maE-B4@D=jMpr5R~c;OyVYtMCfD|x^#uflP~7h!J>Z&fo(Npn>>;3NL#pqqqI#(oGx zpM@JWan5`ymBRLLcf)9P3Mb@S4rWp;cCpjGb;a^zK0f{aEe~b7WKzYh_=tp7{IlX{ zaPt)1$xlhE40D=C0yZZ#zW@XD;0Z{2clMrt{s_z|u22p9EOZ*Bt}D@T#mddG^*N!& z1wrQYAXkd0?`D;?)AQ^xSVkvE&K%45o!G{Y+n?dl?`>LCf$|TGLr#@*0g5ak{!GZQ zWJV#5-NoGLL4j2Ge;;kh^!CgYUBz`mG`_;u*X#A?n!cH&zj04wCV7ZfnN1g;B>Vq= ze&^U&r}j#778SILSIi{X+5Otu+ylM}zQRqS=yP-2m5#MhS}H-1kS~b%WgYLdJZ+@G z+=HgNM(sI|J<6A?cP27$UJY>ElHISuZ8pwHfA`#rOD|bI@79NBx$91q>6p_sB__TU zqQu7Q(@83kC&d<=l5OIbbNFTS0|W4XUy@I!A98=?BQR?S)6U-=bcEIpEUV1rW5Oi) zzCAi&<0yy6wS1xA`QH!!hR_fWaO`6~00=xxj9-!_`dv0Ns_yRv{!D=f8cB>^m{bTH z$w~vt1l9gUSX}yTI#i8=%>!^?#aFvlIED@&(K^4Gu&X$Aa=@&5c##diiEbnQU%k% zU82#d@R(30E6-fm$2R~&hZE2rw;Se_^3LQ8(Azyc2Y=fb{u%Vs#cYpVlnl!@K;WCt z-LnMc<&=G1qaZNbXDjv=Rd>pNOw$5}@Yz?`SS=6TeF#=VZsj6!ue!XvbCDM@DMi6q zeaqncUy#;W$HcHTD@mXuk{N$c(nHnYGh@{~mZ^O^Hm;ZgVN2vD#i(Ih<3^e7(46|{ z57v4)Ww?*uTOT@Q>)77r!b%Ha4Pfm|{3I6sbU&;75jHrk6)y^wb+)yCqF+0{L}lt) zw!NEjuLnkY0rZ+nL@gMs1}W`4Xx8DexS_mA#CZIcssi#L*5!J4Lqlo&oIDTP+1CDm zzm$z((~udaVTlW)_* z6qb8I577gB$Lb54{!GMxvr`rJOD42_B9?Bw`Fc%Fp`0F>VWvT})j1*|+yX2FY3##> z{hbo;s~YH)?`OJy`Hou9$_PaBXD8E7Z$aKpelmF09!(f?bLW1LEL26ZLZPAT@HZs~ zSokXI*EL~o*ob)-Miyqh#opDse{E$g_-bWgf8C&8kvPUbrrw6J-U z*v98S53y)%-zS;l3rBy~ie$+jHE@0dVR5I(IlLx81G(w*poC#DMty;= zRc6=JI#CR-fSyn1j)!_e^Ia56n5ieso?dYwL(wwEyQ!7zWARJ>3ktpjNBl>Z1bq!{ zz(EaA%r}{TaBPv?j2MLk$f9`3d9e(Knc!dp_*THR9bE%izZ=`dfhmm+@?HzK@cH%J6lWBMhHXQv&6lq5T zaU1}*=f`th;{XnT@qb`LsT8q7x21+Lr7w`$cEn_V=zpL?{@~~rEmXtV@R7VBv?$Hk-*gaHoi4`QW1|vdoMMNG;2q^8eutu z%#xTdZnV|XbT7Fxb$vUse>6VHJ*Gi`(;xh{zoB|5J;km?#B8U=%f15-ou$$+?HuarJSBIzUoZ4KZB4jq6r>{mafHgX z2$fC>z&d{4ctYTu^cphIu4AIKEBQj{qRaDyfi+_ly42~1lJHK>1-oOP4}I=`Bk~Z+ zvUQUG10Z)NU)f^C;|t^3WE{aS7kTu9pV$i~ezYi4%Kg@hEXpy2-O@ZC_^n1x@4C0u z$52cdO{jAb(+&`tG#Eb?_=tBxH3AVsw+*0-&`t`m2^BAbD^q=&z(PAG(!h_XDS(E* zuCSyW`2s!-pvqz!gx)Al^aSjGu5a!eAUX$XFh(!7dmb|`WQdai1!?z1XdVpK7OIaS zH=fni;2dY&dN$W^ThTdppIaoh5d);xlj<;4el-haz)kHY#P51=i99mpwbetQjV$vs zGR%^U_kUP20Jjy5Nv_wnUB8TcOC=MpsU1)N&E+i=#HQMtwJ+x}2dR30nx>*>?ZVUu zoBqqpbUzUO33KnV8u4nIb90t%V-+F$Bybar-NeME?sYluPe`%CM- zx|!(xe#jT~=Bcz%Hc;(4Bm=3wYHf4q9?f)EndNK`c-~jJ@T@EK9)vCco*&FbLnou# z`CFl#BBQ;%d0r3v3JnE+_zMDOi-HGY8JjR^uD;8#n=TlvT|26_7}=ZrJ>an4#YI%u zmp`84GTt&ShqoUEY`kW}0 z5XDY}Bnmq3e^xD42TcrH8WmU0g;4@EC_Z&3V)MSwsMn|9I91nX#5v4$;sjD%_%J;3 zTBt0~Ves@>{MmSKwp^-Z`|emF))(u;v5nQMPq*sV ztZ(BsjuGBGnjNG>w0-NJ{7k=Z+Vg_H&LdwU6JQa@m25G8v#Q}Dz-#Y6)B&&s1L)wz zk}gEZn?-vyN{p?$fgk7}k2mBgG1+R7X=h~vw>GW#`v#NOhfNI<{}STXxFQR(Jm0nY zPcF#)we!^NA6Y`IDZQlc5!*+c`stu+Pp!R}*&Ur94Gq{dwZPGW!L^D^}Mp zl}>Tx>cxR6@~ukF-QfT*VN(jL;MQ~!(GJ9u<%xiQWvl@x;}li87y{=a!~2|A4QLzb z1~V*#>NwbM%t^Er2XuxU^U z8Rv0PTX8}~&L8hlxP;MHjX#9wk~fW4N0p|N?gUD!W9M8Hp=?MonF(v)3{aW7c(0tiPe4*=i6inf1lx5>GG zbHg?ZSP?I4&UE!=fZSonc5~Flg3*cs^Q82Ln+0stKR)tXs-WaTg=` zvyP3}vm8J*;v+QQFzuCLy7hRdowg7rqD% z(x6vBu>H4mX2ptK#4+r6N#9)=*9eX>Z?5BCltd?#gNwLkF3CLCB;ZJWipBwd zi~KNi>K3UC$96T!lX_Ebo)f`d5lY13bq;SIale*H+6+`WF(@`ZzWD(|Ne54OmFEQo zk^Y=_0m8H!^?pCD9!qZU75L3(*P}m9lZ4`2CVCw$2+Z>Zd?Xvqc>-|bW++=qPVskG zhn%bTo+&1}!h*C-X40f2Xnt_zkxn&#7V&*ID*BQAT3g>P3t%34 zZ&7{;>YANp&mv@^YgU3S{|p^apklxXDIs;$*Pg;L_EbesjPY;^Ttc_@f;=S0AGUv& zJVg(izLWlaOialG;~7^5Z$S&_Yw?kJr6Kt5_4gywTzCSFN9L}N@&5Vz_ZRqoo}bb# zT1r=bNQg2g3rBRwaFd!_&8#JlKOs7Dq63jFhE(2N9fzXU1kBRo?)q{?>ks$Bt|6S@ zw8_Y%oPqv#mXV=c4db=Qnu}6@%=qYqAi2GenL(tjwS?}u8V-6TwBq=!oB4B9I|pPe zD6-U`ajno*mYMm1cZYikjYX{|_{!~&&`A+Zt^rCo;hElrM6LJgl#qZzd(ilhD3)>N zHoR~HvEJ1fAwqK@gqnM0vsOFgQ2_XGw8)PnE>Sy)W>|a>pL%URCjsbxC~X1Iy4W9X zbnsgmv3EihW8PncP%_3(pl@!%_Z>LRP2XZ=fM%0j5)wulU?IJzyDOSD9v9T-LA{WM zSw*0cei9!dYRm_m4yQaYTe5T&DUYBDi@VKKsWCtU3J{iv*_gr|6HmDOOC~$Jd*Uo$ z$=akt#iF5s-rTEL@so>x7aTQ&^Txik|Dbi54SakKDM-FWaV4oVEQ5bKlyv|GT1(dg z66e3!7)fHRtd4Lj!C22k&3_mngMh;;1-x`O&5N5f!Ne^S{O}UQ#R)1Gk#0}8tRevK z_aTp)j(Y*2;~3061Qvb3SaVgxPNmRP?M(z*DKnb}uHF^kvtP)OhLPZx66I379YR&u`QfZTqxhfU$%x2;4K%F<6 z?=>UlUJJpMQC(HAU{QQQ&TGCs@#1^-Rnew>z$U8B4g>_`H}d)683Gd_8zFsfdI-@j zJa+f!@S_ByQb^E$n|((140y=FBc|8Ujy#!f4(d`~^+u$cC@x~*sRwS`g0naDsch?! zRv;^WNF$@9UzHt!76JP8@SQeHaImhP_LtaRA`uEL6pQsfwTg24zpIGCM%x!*7J~Pp z(Yj>cw?BCI*enalkKu`m*Jb>E{B0N`#~!-om6IZ~6b@B?2f<&v84@M#j^&Oi$l$05 z2LGrC4}!1OTM>ks_Yv_YhhylRQU5wqrDSyvZv!=zUM;)K+jtUBk`>0UgVWs)#3{9z zVhSVtBY{J5*7In7e}Sa5UjS+cDRb2TPt#s+kh3z!&vd7Vq6XKyGQ1a=Day?~0QqYp zj0MTV9NUk7umRsJB6Y*2kB-~J`j{X#~=3$s8RVkCBZN_jM7 zR>6#N0c;74wQcoVqs~@NI8^Hb2o) zF)V>LZQ4VZOYqdw8`I&ab(|KP6vun(}!H{ zWrD#81=;Ze7awN+k9yxs#2RaY0ziv6M2v za_p;rsgpXha}pf7jCDHMk>F9Sh_~IyIjt1PlQ`LbX)^2x_gBXkMbLW#x*vsrjew7u ziLh94HCypkTrOQ1A+Ic|gW`J$CE;ZX-{+-re{dt@cR0gUxcJwa-)$H!WEtDFQSJ}l z>4j>;)c_w9s>5>njOEuY<5rnHT;iv%X?eJRZ+20)Y+Y-EcuW%rJ7&o#*Ysu9e}P=a zVrwNqOC3F!og6mcMc!2}i$rAt5C78xgd;7ldpKS-Ttx76GTd|`InrduVcriNZ*8}EmI z9ksk*XsbXzJOzRWCgkLElbOlJr*eLf_z$_ptAUpeS)1%vKM*p$Sl*6_614uPx8V)H zJSxJOTCXRnufx^Jn#~G3rrjTM7sKeYU&t#J*(utMWrD85Nr4AyeN9@1zGFIbU`txK zIS2vK1Z&NmpQy@3`Ian0^J129(!L6R@*hl4{c2A#7#aL_%PSaTh9x(ljLFUJiW{H= zy#Y~s+dapz_X=tgek80q027J9EP>RK<7Eg6S|47(I-EBh4>CnJ(EiDkm*Eb}WAe*y zuJ^YZ(MZg@x1%)$F{p7)jsB<1Gcq4nz1Y=0^r!*zv-zv@IPbN9hvD23IF0pxJfX!$ zPwX_s2^kSD2&OrR%TSvy>i2AIHk(MZj9$~WKZnc;&_wise95vg(j7Z z1Gwq-E85)MtXOGAWiQe0{!EQSyLfsRa_Meu%HsLSUs0cnbZ*J$A|w3ZQ2lMZ#9u=0 z$|`5&xc~s9Z9g+dA%@^MoP>RUCWv?Tt~YqBJ?}}l-9rF|6Wh}q;*ma2Z*jgP$uBde zaBC#6N0Es1+>RWLpE8{OGIYgS93_jDkKWop3JM!q#oD8+#JX<@vq0W9i zfeZPa&4|FnqaKb`_qAjLPMc?3ajOExS`b`NYGJGK z>{UYY_Dk}oC3o;>W9!q#GKIk7fblQ%n{;nx9(OoJOv(S0k3JlM@-GHsbCrn<;DiLa z;fv}M;9OuY0EQRC4SqX+ZsR+=Aol1q)Tq;;Y&Iv+#`(4b+Tmt-Fk80de04;sp?H7#cpuKL&m z#CX;YY$E4$oFT{Mw+|0XKz@7N$hN)&Rt}1yIogKJ zBEoKGh;SOahle2jgtX6iNs`6{5(-=^!Lb7RkL@VFE#;$qs`914aP9SxA=XFn9VegK z6&QCLENc?2bAwQS)vuJ{=d_FTf$_8`-|#!t+W=8qN%74@x%d<@^3aDUNnxDUIR?;| z{e=@>d@AKN)6`ZJfK;nU`Jm{%P>*909R^{U+y@Rt#NFoF{=hh5Azs!UDq7{$>v*CD!p=tph1+z#j`Z&n@uN0k#1 zMlg#HdYAV_V9Ob@6-SMaGWtB>TpxURs5b?1cjZ0UPYN=v6rSz4Z`qyyB!ik(ti^>{ zY1_|{VxU)_{IlrP_37|TrznteW%6gZci>=6L? zK!ogned|#aMeFbdKwg`~D)RW_9yWu{r-!n?Q#y5r9@dM7R`r z4>vYG<2dxh0=}8d^CSqst8o+p7a9OH-OL~Xy(v1-lLsh1EI&CuaRTW^ufW_Qq_q^% zxieViyvk>OOE17j`Dc$Jt7)d=OsJi;`ff3c-Wk^4we|cx7xw4U`R(L41R)x0k=t#5 zSV8a!CoDR6`;3L7c2`skVlz0JTJH3i@gtxErJfOnv7r#nI$pT{A#z*4EomUe()+)D zkH&pd;DM&XMxRbcGmBTeb!=UVKJ$Eee63B+?!a@D1~Hb*Xm3o38{IpJ?u;XqVWMgC z4bpX7|EqBma+q+%J9&7s`6Ceiaz=Z9NQm(rS99jPNuGiZvKAg!jNd=2eu<%@GjP+o z)E=H$YHN0Gq$k7r;nfN7Tl}PJEqnV`wwOQpxf7IANbSPFXphynPktgzK_pnWVCod( z?+#cgSSv8$kFL^sC0adV!=hI7J%~iSK$bqpdfgzdg0R_|WF?_RT;)@aFj`1|&cLl* z;(nA)F|7k-{{z*F!DKioe#Z3#-Q)7rRs57|0RfgT>YNXvlj_w8M@poIn|INMxSc<8 z=u!-@e=-sz^$yO9Sw2G&QQR9Xm>(t&3sX9Te>c~R8*K0T#P*2I|A`xkf71UdZUQ&K zZ}(?eO_i=X%OK<3KsJ`3#DxrhZ?P`D*Vm7W#giEn91oowScGZzF}h_#I>X)i&?9>% zAXhp)so@R!J9g(+_gHL)wU9&14#dlv+b#ygQ-6nlFAS9QCJ8RHfLd;n7 zIFJK^os1|s{a!i=fuL><5Y?dp8TA8m45wB2007KMwEPs{<3{z-SI|$<$nEigWBJ*A}hZ8 z+A7!IUCuMU{;(@LJS7zX%T0att~{e`)93tK2sz^M5TtxGG)yh#olm<;wGRB0x(%a* zZsVRQ5eIr!UJ6D^JX>W(Rlo;I#MEB`;uIS)!!Ox>_WI?;o z6uxFo_jtK25Z;D=5agJsgS0gszFZm0>Or_-^^TCg##p;|8NH3wr8z0td(qvP;4%>{S2>cEOe|pYd8M0 znNBZGV1Vb?Cqc|Dd}JMzL0=db(nF_ocySybhl5FwPT|LYcSIetkZFX1@;~gKNK-JX zrJ!5Q_w+e*S^Bn`W`kJN;jfo*m9TXL_4a594w|})Es{s1qTfGO6F{$s^|{JW)CHpSyqx7Q8s5vW>$>Ic_G4=mFTk6Tj$~GWyvip?Ex* zzVT;wf05%qHL3$TiA7qTs}MjQArxW}9Wwgmq6mS1jp`Y2FR{F>vH+i}i)f)V4;zYM z-Tf9UG|DM{z!KId6fK@On6p_Fp=cNk&sqYb7b+!m0czS?bNz&1wWYA&JjH>6 z5D9sIQGFxpfP$RFlcFTu>$3iN9>d#z%#}vPRj*s8^sC4PK+XNih>MkM#|3xVU3Kn4 znG8~|Ym@`g*;2AIR|}EmDh;tn9Td$JO0~;PB{TKhlHs<-uU*T}hje6%CZeLnJOA=9 zI&9W|ox6w#?2?tHFwWz1$VhTMC)5yTimt$acS`Vx-$Tj%Ryau#|5&)xdKEUOo+NR{ zp`Ei0G{+DGz+B#L-1VdL)j=`NIroYDh*G#|*+AbFdk#A7kYvPo7t5M(8tk2O%P(ML z6HkI6B@{g=K`An4vWpZ}^dHBC9@<$2t1++nl+*C9r%f1R#@PClFwf~L+%wA;A zb51}H%|PYQR}WGo$X%u~_X=c5GWQ@WRw6Xu0PrxxHGG2C_snLsoK7;nTNLs-Je4=8 z3d+l`{z_umo?xFURm86EIg@VvejZ|fI9CTw(k7B|?P&q@O3KQFIpK=01v#uY?!^hW z&+?_>!eNhZoxd^DDFH{dIc-p(qc_5Cxm==-; z@0r|^k6Gwr@OelDl+l)B@Vlk7@tG!J3w(-vKA>-o@sKm`#qSVpxUXDtaLYPHwV=q) z>nyw#$ZRxAhyc*r=Rh*+B~7D$p(Ybz`)y*RfjF`#hNoV^eK}YL+|y#a;Q1*xK3*SD zR;HO>vo|`3Fe(-TM``_)!bbi9M1U>JAFO`g4I)ARYz7F0<1J~ca$k}X!~U;F=-7gq z1=$A(_Q;>cWmb6Cvw}!o9@~WJw_BiclkU1407u4LG6@X5EK)(rpk&D{Lw9R9P zd=nL+zN-?h#E&uJc?68!9SHSrsrJ744KwOGHd52s>*>Xes;BNv=bM+7*P$TFGnckv z&_CgeXc5XT&1z{mEaBB!OL<+&zf3^jH~a}5sjqH09;p4O&9l^OM?W%cSo}brNjWVB zaCo?n$OpGB(o{TmINw@-^<5AABH1>l{dFSr#Bw5H`JZ^;07vC|q}aZ0(gYUF2@(R6 zN(s<7C=W%mbg101wRvpg_&}pOkrl@A>ewQ4MRc-@ zbY~7A3{^UDc1O7c;aq8dzgqjA566c5oZVM5 zSIk{u<03d2EoiT8j$}{b%8tpe?|Ng6!Zq#blt}y!wFbVko0;qe*5pppR^s$xGSPrh zLP60eQAPro|05k|1e%`oVapDP{)`Pb7Yk!3t7CQwMgH?}rTGL$bkkqS`nqHq*kHm%QDu zva1Wz!jG;MCcFZAFKaa2DvUptG?dTrSdba`Jyq})U*nR0DnS^9aeaiB?eK zu8Z>P( zu}3WFUD*m_nZxD4#rbud40XXU5f32SgzR*<;dyB(ym@F**a9B6?gL;{Z0eaS<$hmC z;sz{#45&pzHImNpy|qAGD(H0s)5SL^ZWSYi(pi&({miglb+=DfK7+pA{%D+YZD$n64#>s-JzaV*{UGs`a zYy2cQ1+7(mjEl3^TLaIz-^x_RY&)Jcci(f~xaA~`f9S3HjfQ_%nh5P2HVS_r{)~4- zEK_|YV?Hh_(2OkhQQMkri%R0mi|Kx(Z>i&LX3XW<8yDiiCT}4uP+Z!waQEI;A^4%& zmwLfE@s~jmapz{RR?}m+HOY-56^PzFhNB^k^3_ijUZtywlk^jmVZ5TRsR}dzi6n9* zPZFfJe=dyVpBZB!$Ktx(1xQ+GEjc>^=8ZcQc-hsFFwGdE^0%(NeKC0Ixja>i-V3a< zQg6XsW*DxRAt)VRPqQCOA+|1+GMTZDAlvUS8XlcpPulM^sgU{N>9fdb4gN-qP#vz# zlqJ8Xztf#3w+$0P`*#0ra+W!MlV=e#ta2Wye??Bq$Bu6&Q4jQ*P|J?mKs`Jd@Kd!z zd=l6!W+F|b=$_>&B#A$hm;J1#Ko>`3F3Rs9iRAAme*C_=`Zi9G0L=pnI~WTIccHNf zPO<+z5od1F9A&2n4SmD`N^;rx1uAhR_1G?m2$?GrB_{5uY^TIyv{_$^T8!h;*w9f1 zf36Qi_ooiCm8G1$tMC;p?*k;VoBe4i6DiuU1VxyiJ?|bNrxZLIUT*b9fmZ`Px*+Z{ zu=ML@#S=RWk=S4zd<(eq*36u?z#U+a@Q&_c&n~h}9$+R&ncXhgq$^?wzN6s^{6B?& zU&`8$TYu>=AhpfYCU!4eHneOcc{83)fAN;?^6A|n>*ktCjvHK0QF*M>VWaz-MaXnh zkSH&;;|o9q)gXJ95~#x`Z2TqUc7xb6sBF&61x^(63Os_;q|bY|%R-GVJjI7PC(nt= zs?fX(Qfi(Ceh*Z5I-(a?ovO71t-V8E;U9j0>@=HFHOC+7Z%lpZDBWue;N!* zR>uqYK$Pze$J4LQ5r+pYX9^N8r`0BXU|zA5L&TX4o#J2)>0^tHR*uQU8k7E8OMEjw z6OF@SEHU*o#G$YnU_s&OsR#^o>3QInQCx+i1?qTCCoE}ao?;c?WTEv9XwyZ-!&u*I z@?9V-a0>HShL4$*~Q z?Lw7C01w3wsB&i%72>A@vE<2LvOvq;H&X;Eq!>dY6%F4bT?kl!4;xZ{+X4a05#vXY zEh_Vo!V*z}ihpOBQixOp=KdLC5h9oV+VD`JN55S{ah5X3Sghc|98&QAfBAR6y_yGt z=emr#0np^V%ydxu(Y?CY6Ub!K$#=JDC9|QLNpD$;C23(l1fT2JHD2!>YUUTYz@C#! zxJ&s>W4c+SgjBKtMH=Vy(P~UL+@=7$p#jdpB5 zuvGgy$+$oyGA0S7Eq2bP&dI>?iM3nBVO;%x;Dv^J?kY6jfh7)x4OEEsO<;0}2e^<<5G&KplctE^2KDeIWhi^Fa_O2lOtEc~`itGj**fetIjZ`)Nl>CEQs0&M%XuB2#(I(s5 zZJLk9CM4_G6KzgAA43L^o7Ek=e^}CSxh7F6=u+NrNyPPfsB}P3 zZP<1E-?(=f;qPNpYl}o7mol-5Z4P`!QzEy*P%-)Yh**G4Z`K2{O72ZN+37C_m|uEw zMPop(iA4>d&%v#)tOR5zQACS75j+=lT_Vv+2mOctcok+9ZYw*vu@^0_L{kN?izj>I zNAP5_e|goq?xF%ME?I0=sK2JrJx?B_MI`X3DxV3&?XTme5{SB*%xDv&RT=TLj;~?E z=oXrmsFzlRoj?dX)4>TNPgl-{_@jC9+q>~ylyFJXQfV9A3}Fu*-$JgXH-yi;W!dJ9 z_ITL7bdDuoeP*RVH3c)b3z#6#MH?j4B#6s8e;RmX z6@rK=SCS=G#he|nZOK|;#&$No5{iVkPE-E9(>DZYl~2ccA94fet05=;a8Bbtv#s5+ z5X(SUlxsV-S5fS!6(uddk&N8>2|nhWM!>zsejuk`6uRJ20y@-6L7i`Vp1eU@v=W_f ze`dQdcnmn~=H<~k6XC-9)w+=^w_O@w?=#FZvVMULzwDssnkKPs#G(T}G&5bSqMqlF z4>qLO(GV?W3qT-(ni^GCv9`P{{`dRpKRR!A5>=BdEz37U{0Ym^RCnJlhr1n2t|(P6w5FNH?MhWq~l}J`PTU8sciWpaTGFJL?h)ICoxCf2XJ& z+@%QD1+p06Rb%MVj6L{^eKE2={K>gac(s`{oPi9)Oamb%z``$N0)Y9@uW;v@T5{BQ z>PVu8!93m!t-GfD%9`F!$jZKEJ*dheD|8Z%21aTm1-CBR`9HwkOe;z-*X*)IFKcz~>X*%}~xdsAa)vQu zycB2sl9Oh#3q+w;GeML=T1l+Wd?7;Um@3porigmTFq^R_wlnzj3K8EEH>H9nLoV+& zeH!oNtT#U*Zd$CN5{U%d#v)kx0`D_%872e~Xlrh+3io z{HJK2L8d8DYWu%=#Foo$ju*C)JMy_8isa{nPNw6X88?db;I<59S$wo>$i?=8P(@LX$t(Qi=!_dAMw}_FTeZOA&W?dO z?-44aL&y%Zu>Q@d2E>~3O&9Nj6$2@Fp7fB_fMV&jN9(g4s557?rS>z%5SnXFNd!P? z=5eVO2X-dXwt7Z88j~vE&dsqnCGBCao!8>pIxZ?g1DL4u+_XNge|~(lC|!XY?Vu}t zK)$vDj2-2T^YXkHP>?i-hFaR?Wjj(W>-ttC>OVe~PfT-&kDM`7T%jgdYyoqK--&P{ zIsgp8_~cE z*(_8+>`HSsKKbtm>uC!${0~~IW2(JUR>E*^0w)0C4QV+`!(!Z!caey$r>i*h%}*aF zS2BR2!F8mLKTKo!%^M_1)QjRP8FFRUgEf?#jpse#8eI3te-O{Ummx+G5Legk(^3)A zx;{0^3VQc|w4%7;8~QrN(_g3?*EJ61Y!QagALs4+yjBD+4Sv;>Gq1;is`s$mk`NvR zMFRoS*xGviUyW$v5ED=o{Q6X;|9m!It$*jU!2ZzAk)b!FD@`077ahmF(Lmj%NA{@m zSnGDs@$D|xf0n)-+LwB;;V5WPkeid>>6B+)K_!M`xYnVr*Oz(^f1Ez@27ugsgPvExceYcW(8EigfK&s_Mn{~$jp#7Q49nI**i0ZTay?R4I2Pt~p6>|?-vo8j zWF#-uU(8szpI~;}$uww!rEb3Ea57~r{ZH0#qAkp?f2{6b?H>KYT;x;-pLHH)Py+B` zOBNGpG=p_M^8R$A#Nh`yn`}qRJa`dELWcN4?&LDydF;ck^hF7a+KL_3m&*^HjqeFEt#+_7YitPDfdLo7SsDV> zpBL2|2!M699i!Q0*}keM#rnILh$Y*iwQi~pY5=?;*W-_z666JtzLxtv(cH^bd=bz| z1)m)^^kpi57K>drKf7gTC-9rkxnFKzVB=zRifXcrQEoe@^C7wr8fo`xy8omZ*vsZ;=7DZW>ePvGt3dU0<099MHf*zIqFcG0Yb!p0b zPDuzKQWIJkV#F0T#~*CGJUB5+{9DfLanLJScbX!<_0yZ2`~Jt`(WJ=MVJl|t<3KKq zBQX%Mhv08jSrhXG3h+jMloofi=-O5Se?)ZLsOHNL{MKty{GJ98lqBVV_~7u0ta+glV^WE$iClr6XkQsxFc|qAsC55cL0F zEa^#h0=?RltOcE@faHGQ@*Be`uD*}EbHKc4*o;7{eX5se`IF4+ass>gRB~3de>a2U z*?2*wgGvc6)?r7S>b0GqU`5}!TOzgh@J6!JSDo-)5G1eT+jQVm3VrDSvM6{T<%yRs z-G)%9D;7@f*J0jIbWvl00LoC^7ZrW;k`XkHa9?t4{naKFH694z*GvnO@Q-Mi5Tf-g zTEI#2lpWi}tX&1qDTW6z5HkU8f0;0caa?r|^K+^XN?!-vKrmnMEKdYvqJOYN`x(d7 zVec`UT58oPbTjqMbf2vj+O8g(Jpht zmJ#ZP1uu;y+Z@HQ#uKt!v{XR%=?Ux^?xPH2Tf~;Vvo`_QYn}6k1m4csf5~n&=FnQS zMm{Nk0DY1e`^^H8@o^NMkl{;vSP#&uq&{w_n&Iu{j!5?)4uqf_+xvGCeTxrD=7A=ZMqhTSjsyffUP`tU+TLU?iL zDcM-vj>{H@v}hW>M+8apTfA^`%0743sNaq`vnTtZ@0G1o9!dX6WF4Wg>~@s$>SG#k zeVHn}IjmQ2NM7KXuk7_$4ld^42UP58+3Q7<u12}1Y?Jv#Bxofvwf|Q~GmDyF^e@#lZfLJ2?)gmN;)6dm_ zkDlRQlcS@f#{)mkHmh@P08NXUw?cN*Jz)Eg*<2s^AnBqp=Oh)oC45q|5`_x9m1NF3 znOQN-4UhWawnC@4e=qn%;SW?-Sx~+AN9GtE35+6+4JVzlyZJai?(o%>Yf`!&?AOK& z^-o*bZW)T?c@4*0k`rCL+*cyNHDBM4v|L%;5N(pXkAywa1qrdn3lgZwqw}&oRpEa0 z7cQYn-3TI`fGmw#?96tO(?jz%1-!03bgS7`WjPfC>wKj?e_zG%e{|#~H9%oK%xD~N zFvuOqcg3zgc~`wyk*U`Yco3<(3ABFvbs2Ox=y*G(1CLthv$kZkyq)p%++{4Nz}nNg zJh~TEKGu#nKs~ue30ds&tuIWjOl_W>w zq;XNjWGG^NDcb}>;tr{u&p2x&)k$G^cAmri@(>9Qm&N;ys@N^RZzqt)i1t!xA&V;a zSuuVVWkeY9a1|5k8MM8j_EWNk5T7}c)}YjrfZ&=+e=y3CbCXR5c_)f%uWcCGsfI-nAMM7>9?JX4 zkIG*$e{%pIETr!d(^3=%?n&WK#pQ%~)+lxrMnyc~+(u_40ik(`ucsHvRu&ybyQlmANTgHs>gZo6J) z?feWvLz^;o-s)?5ib+;Xwb+5Q@+jw3$_vwae;+^I8co_brzG6cb8@54$qwX{)4SE) zxe||{>sdrsdbcHTHNKRps~kGK|BmL$Pc=E4wRh}l7m81JMayRT9Vf}=U?+Dz|&LJj#nPAAKKHPtyo*iXjn;v_GK(B zfIMZm(m&9Cm!;AX6Z0K?jDG_Odz+*ae?g$C_y)H#_YEfA15X8p2d%q6(@UyjPJoWN zxrew!;LF=DVO+*-Zta|IgJ5`#iw55x4)65t9>Q4eb6|UH_PLTn6%Pe&<1!%QoTyw{ zKcOy`qXqylg~40P=YYXMixF7^s(mYZrNr%C?s57iUt*;+!>b{q2v_Fp-Qtv)e~H+U zIi%C~QaX^TQR7!dj|%&<)cx(jUtqf6aTl3}L?Lr$LhbJk`)pJgGBH8jNc zJCn0s{SrSVTSR{6pipS%L@k=Eylc&BKUk^vG_kjrL#IhXm&wm3vHYqYXb7r1&D+TI zD#*aT0!0Eb$c3C>HmR=daNmigf0$!=KSZE><)dNY@+5VR?~}{IDu>e*BG#tBp-$}b z&Wn_+w|4vMPhQZ~4i`=lh+-rwk)GpLb~Ql>;4!G$q-KWNxC#hY4qo`8PCG1fe0Uce*;nLH}I1q%R>RGcuvBM|;BK^UbPo(rp zxf5PE8^XqF7Ls@%vVlEX?le_f3Ly}cz&A;d-t(CJYe9~89)mV%R_p%4m!IQ5edP@} z7L0)D+GXft@N{ELtR*(We;K3mA;-4S*4<~;R>b`tfidwzv~WMoyFBoBmgAUgJp&cE zLyEkKreLEPl9nji`vxv#fS8fPKRsL1Q{0qw&bbSg7V#ErN~M6wq)TtM8;d$DDorQ} z&s&hpZ(Qm@89zTltrM&&|G6Ys$7IY)<;Qv$Cxe|9JUFIW3|mpSsC(`<8~jJWqv zo;g+gt0bt#vKumFHMRVh9Li@!>?umqlmHmHp{tWRuu{|d`baTwGv5PRGQG~obPrdH zoDn(= zU>lz;Zrg1me=Nr4T5#j^1y9~RyQ{EbP|Eg>rCLVE$DITPyQ$hc)Z2j)RuCL&$#%6R9g{n8X41v}z2Kf=Ae+Zh626IP#qaY=&VdD=kh$Tz% ze#&xmWZ%+3Px^4h17=_sL=3UJR><<9>>3jz%1V`c4$mg1&N7ICU1eTGXKdUn>BWKP zaNFQ)n22sTJZ1WM#xHNDF5@#KZ*7UA;P(+E{}JW@;rx@P7llBvO&Nw*4DY;5AZFcj z623V$f6=^ZGH`=E^&kfJh%j*Oj0F-#Tjx06}T;Os4JTb@;_LO(LPw;qg( z;*W8SnJ#dqVh3l&k+>Nvu#9MgCop=moj{-lgq5peyw|82h{G;8eYT1*E9`v0> zmDUIc-;l7bHWBs5_T@VMuX~tay+NnQO5XPT>19&^>P5X{_GHBn%Zl%K^p(=)-{B`r8`mN(G<#RZexw)(rt$o-Jc}lNKb@OQ!NuyLL95!X zf3Y+29@Rn}3N+S);CAN>C!Y9xzZDuymN zU26(`l%cPqhhHq1;B1Y(79~2KL|nAS1(v<*4U+11^=j$kY!<2%^ag_~FzF(?swKya<_s{y`?&KIiGA=mebML|jk3$ZYtiHMXp;8$uj5ff{3CzK4# z%9>HA2u(xTxPn?@DL)0#}%eE<0a5g)L=BCNNFZHp)oyRrh$~S1F4`R! zCLK#Y(Z_3U_I9z?fr>)CoLzViBy_YNtq*f;R@tB%JZDnJ8-*S@0@;%PX?yT zgG6M_V4Z~q4Ayu)a9%rqX<)Cki!GLTP&e&WO9?C6w?2o&GM(CIAu6Kt3KP76!3xa+ zG3b6-@PN1}x)HGm{Lx~Jc* z1o&;*6F!s&u8GN6&)TtVdtm|*2PAS6j(Q~BFhNq?Bc(5j^xSkR^?gbe!^}J2xYLVh zNCPfCO0;nVoektt_ANY&4@K6xbDw;5P+nLBkYC+ZnVS*1UvC6%I;ed&j%@$v z`*OPJwS&l2Fr=RyJ>7HQ>gOv0rXjo9HJ?3<4Jh0J>TwdM?t=_Nv%mQ3_HAL_d)1K0YH_t?kcn(`wpRD#dFvuc(~TT z-LVq`;GB>7t1QWT0=cm|y)6uYrDBzH+FH=q%kf=J&-fmb!)0?7)) z54KeD>_xp^Cb+D1vHKo&#|FGaFOzZ3bQfXsDFiryCL(`GMpke^>#PM>`pC<$26oHc9vX9{!RWo9T4D1g30p2SwjS4i(N#&dkT9OCP8Za#s{};Cx)(#{Dr$CJ@Bq1J6f51W`jtWE_Ho1}qBQP$L*&k!M4Ha2c z4S2QhJB49gPN4m!>X)XUzv}%I7AM)@fMr+cU56pXdNbegYkt zT=8ees0peq1G5Q#+NN=+`cufkjp4vJHNg)aPKjODm+JNaUcOT5@6)iaNNgOWs>ge& ze-v}Rg-$ymq?@8}B_LLsx39XxbZ4Sw0aq z>+lprv|KgdqWwcgC(tQDSb#h$I{Gkd3=?d6yHe_67Dec7;VlIlC)_0ED#ppvsi*-x zre(1Qzf0>{iE}NbMY+~`{1u;o8lViafBGc(tFsxG2;ztKnC|k1*yf;k<4`dJ-C*!M z4H)(5=ns_|$X;AtED#A>*WNLR$ragHY8sBkFtmUor*qS}%Re7RwQ>2lPiq(8@G<*# zkg9`C&`D`L;2X#d{P{6MY|fy8pH8|W3UNmI_86}t|C*&YV`t5SsH)og3;bkYe>$xL z0aeZAP0GWQ9wPKQ9KDBCd<6LGi6xLu-XEmBtY!p=SU}eig*^5`J%lGh+ahFAH-G^^@oG$%xw|y+J7goTRE_hl zY#r?*uNjbrff+Ygy`&AI8r<>9e{62%xw`oPe!TLTbtWQuYKD6Oli0@H#H%2>AkNw2 z1>`g@gsXM+d!a9{YTA06VH6(gtFT))aZr3nN^yk7`W==?f9mb{?}i&OeHTjVg+%P3 zn4!-}Mer05G%+PA2}%xUDa>AN#nev5GgBK}e{M8?*Xc)4 z4lk}O&o&o;ANc8SsKwTxRR{AEbwDEs03+AdC*A@TH-_YW8muQ&qAssTIH_)Jo_E=L=P(Wh%qlhznG7S$!{J++#!tn-Jz-z}e zl<8>te=b|g?u@Qqgi;rd%vFmpB>hc{3at8`W_;0brM*<70AdIx zS{Tu~l@@{2qJ7E?rv^n!yYJOFP)~Capqyb724PrY@}9IqJl5R^G}kV3Sz!zlia}Lc z#gz=P=YjQwFXEao1DdWuRBP>F_DQw68~7-pu2gjO3bt=$voN4Fe?8z60<=A}!Xa2C zmO?gQ?lPI^u?F@vuNx3wHMs>yj5y#XXZbRI3K$m$Xcp5g zdBnRPo#p_fBTs;re|MQM4B_vy+@doMNc_&3RAJqs*Unnz=hD*-*)TARVAHut*z3fF zwy;s{2Wr)M&166xzej1Ay^LZJevpogaI#0nXC557S+)irx&m$RO5Ci7PeGcq5mfTJ zOL$1zOgdw5a~1qA&0`S9z6yWMa$iXCldETbI8(Je8 z*3aDoSOBBbz8uu<;J_Ia_Ng+~%j8Vgn9vvo&FK~HV{m4yfK2&}sC?aq+MHo5e6@UqHXs1(|mUS>L1x?qLPG$zj^E$akt8y)oOHJ4ez1-pX*(aQg0Ee~Kyc&d=5jqrLZ@nF}evxUtVm zW)QjEa{mg^#9n+fE1XlldI}J^X;yhTP6j++MgOpcD}}hBgcywDvg+pJ_J1%#6g7~^ zPZBvQ`PZ-lY!aBk89bw$Ee z55e+b191(ofWZm3Op&=~6FA89XeLxgiWtP`y}y9_B&06H6L34EZc#eu9}B<)i6+6} zXu#vvPZbZg)>;fzK(}!9Fts_yQhn*C^Y@}cf3*&?!!I8ek{un=@tymBoPt57OVWKY zH4$F2D>XIwL~8>3doD{2N}ky~aHNZGfEby%b4*VF7XTnX{v_g3oEBE)dPu-U%J9Hv zClqy_M}#8bk?-;kVm>lj-h9H~avyWNACCg>aTrm;g$f3Wy@3Rw>E^G2s!Q<{X%y$t ze=mgN&lF^H0))2{>DWE%ln8rPm`$iS(X!{%7pyO;D4aZncVT_ER#GT>zWFk2pno9> zq+k0;r_|E+K#@8>Fk9~#c?LO&+^DMKIDI0`4Hh0Z~(Xs|%;l&%uP(})jH-Iz3th-a*U0Xb7OHaC=OAfHSINesK z-cIh_Pg3Yt@q0f@pGI!?o~p`HFsdk-)4{$Dh#>qJ#UWk)uH*8c>(Si)ft4d9txqhO_Gl{h zgUD$UH80E6$pXwgN$VYvDK5fBUJd88xT2 zFY4^=Q<(78@44#WCSk<-LTi+j5xY(44uj^`O#?2bN0>&!J^B3GmP2z{fn+g|=bBJ@ z9+pWJ@ddR%Dy&K3;J}~O$}aMjND1lb&WlOP?f~gwTe!+=?3!jgY)MhJB>h%{6u)JN zD{)f`1)@a#g%A@00mDAwfB35q6RJdw_Ou#WG-@LLDLYiZZXa^HBRpBG@+z}8DQrfc zHcA-@NUN#3o_wLNp?6w(w}ITGFHsfihBjWD%&BVcB$pC$n?gzhrWLfLZ$`Ru{9Z%` zQdhgsEw43U?-6i|HLQxcAu(Lp)#mUHP7SyfO!ub3J4cA*1b4Z4f3H5pvUytTo^)@) zd8IbJhvg5~LtB~vy(M^n1WC-Mn&r$A>NtWlkE_$wX%kBO>&x)Vd;39t-l%mw>Cx@# zTc<*WeIB-nV8(RNhgZt_G7hgofa?YE%&SF%$4P#-2h_qiH_A=gM7%HWYsM z>9lYAXyia3D&F*Le+`Q2s%k#Brn;j&*Po)C0vBir#DYYar)ktEpM%`BImzZ=8J~w( zB577X6{1TPwyqJy`-)GYfTI4|q?P{EL&Iahz#A^Rd3r4rgU`}(Tt4hlORVoU(9Hr_ zNK>#ie|(S~tp24w5QIR@@C^EddRSDx>2bVO>_-3mc#*ave=5Z|toirmh2{b0Fe9H= z@nGx}?^U!_B=t2HOj@>I=)1;*0?ME-%h4JrE{Rc)x#?jQV21nPhD%!;9qE&typbOd z8HNFnN@e~nnYED7z4ri5uD7QdxY`$XrsJLc_=y8emHM zDcvi`Cp1M+e__ouU|N&}NASGytZB31cpUDDbT|I1s-)nWviOmyR#<@}DBLZxJ%JFz zFJ-n8_CxN}=6*Wg3m;qiW>R5?4ps(HQeIm^@)Cqta0vi?_5VG8A2`AKju7Ccj}AeQ zRD=gaDM74x=-}#rJYutU`^4YWL|Xp;xaQaZv?-xGe@N#s&lj}+la$PD^_ir}c0t*$ zrx$Fmr!`q9LE~vEr;a z#Lp4%I25aeMEfY?jL<2S?M0g3xAl{}$Y_A>qjko23Vvqsoi{j7PaFe(C#4xOp+VW3 zRl2>3e;$4^$oft_$cjfCzfL4DWh@Kb)1VLVPMveXIgrGSjj-T*Wv2+>WnBMBe%%4F zLp(`^m=bw|sQtdcCSN!7E@^6(3DSZj@}D>gwdpiekToWg0e{K8kP=(X)nqx(%yM9K zVE(9ErMGf3Lve}Ce-IAcM{h7!n&BjeFO0!9N9?7g#= zS<|DhRs_u3l{)Y2Ya-sA1$yl=20{A;dL4g4ruN8{NNMseRSuz!M_E8Ed)l9PvcFv{ zMHDqziB7FVyOwQ9&V7M6Jot#+kur8@M&79)OYiZ$yY&yE>=@;FRYAKk{@FYZE$LQ} ze~=s=>g;v4UwxT*FPFZKkX{h3QTgqsq8*ab+j2sZ7J|`e+)5qmmlT0@Mz@TOdyOIP zVy0NRrCX(Sr%K5cj}2v3s!97=0Eqv0%?#m88C-~*pN@U5cLvNxmK^U5Ym7@T^0>Nf zgi^frBbD~EeghzbkWypG3%MKTRpih5fB5fY?63^A24X&sEB&OP@10*)S2nl$7J-6o zC`OSPCp15{b8*wp-nyy6;4Zdc1hI7%^k17Hls9 ztaKrzBh_YCKa5~b){vUqHHV$jhM0WN!ZqWbl~iMK34i+LRIQ}C7<9$xTU#YSe;~pg znrBA-3v#&xhvs84s)P4*8DuuA^!6cnCcC3FA~)gzS+qWm9^R00&mq}$#1{?kL4lnC zf8^c8^16n%%+h!ybhP}&j#|m;Dl`guZ2VH~w;>+Pl*KP0IhYZKLIXkc0Je=%CJjubXR0S|aYqkL&J$-h&=Ynv^W`hhLaptIBe zZ>_{-oFF7n#&Jqhz950kL$``Yn=pTiG^}=Onc0SoQs$10g1uvKDFL8UdPLgO!$AuQ zg=nhf9IJ>ZVn6?@)$@Nlb0NqymVJZ2R!EtC=u{74I&rz(C+rMCm~V2Fe_RAClv*!` z#t|xPh@OznVzc&C8MgCQ@$|u)gG=a%zQd-1d9J)G%Z+COhYev!KqQW#-jiD%9$#&zft$FiLd?KPuF-mjlRi$C>{sYl^qdSZ^Chr7zN=h3UK$x z*+2G}gBxo2&&V1mbL9KBf3)(0SPW;gM*lDsDK!%8=2;rADg1S2IJ&=^v(fbIiohtBe!mO zu+Rmy8ctdZdmRp?N}O2|?%00~ax^-iGngha_~}Xett+sYH&~Uje>i7kT;F>Gz^@lX_DPqxG!`W_(;V7%? z=mXfG`>LlM{QG@Wfi-2Q^h)CPLu0waoUp-VA0^}V>n)+?69a?s#WSsxQ470$t;uoY zl)?Ur`3i1YdFfn@e{8>flete?<&q9g7Z1w$=QU0Am1$j^#w^69`@Jud9ZTtKhQlyZ%K;b$zIfxdW zv`?a{=+aQW%6?WOv0ApP()CJMSA6OAk*$6jKvA=s39Z zIf+c%?&J)Of7%YaD5VGNLFJH~LJJ0&M^#)S) zklozQWswh9c{+GjY%s`GALL%L=crd(j;A z=%ESF5QbP9kVuFxW7E$rGHr!5b7&Puty(ei-}MElpVt)~_xYsjc2|p2(*+H? zH6bcof2=QAO3~1XHfzICq@ahYL~O)0O4VFtmH1`-tan+>RGk2S=A~n^{;f}R8d4xb zOk4-t29o4svqBnM5k?g>0|T@6o%oFZ(c9F98`wl9;`H-5>D}@Q2~_*=7gJbmQ-?e| z$PGaFF+~(gK7!=Gq>98-A6IBVe?Xw))`}P7e-cJnNMaIY)5z=~Ef*E|DSw^j5R%Ei zNPTa?0VWWW0hYo1>oJBdI7u3ANMDSfxQqrvN-nI17Dtd_Z)AAJ7ak|w`F6WrVwt=Z zMOu$8EVad*(tBoH-w&QCJlEifl}cnp3*=qsk^+N<~Sl9hlFSD!arzS#yK ze^!J!kGvXG!_KhM= z@=jbua1==Oc`TlM4#q>siPIsNXZ?}Ne{m^H8}7tB{tPkXC6wYaZpx@5I6^$Zy>l?w z-V?u*PC=oY7btF;*AxcngxlUSaOGhhoJi>u@;c;>xTJR@aiZ%n2BZ$@P+-~3{U*YJ zw&Ui)wlBX3(to!=EW4+iZ@m3mK>B9yeY`q`68>^#)xdl=53LjQa4;9Vou1}df2?bj z{?_98An#$N?{D7Q#KjY6)QqjEf&{$HW>?l2iz_+@F878t>Z;=3O{|3)Oe6viU;qqY zFCqLJI+q)Yrc7L^;&2|W^s#H0y+6?^O>C=<%*D3vxAp!@T0N9tPxASih@fr`bJ- z;6H*uIrgB$6HTJN^fB{sWQANm`?)s#7#XnozlVqaw`__L?=gV4m#hw{;u|Sf2L3ZwO;&Z z)a$y=wLdSpiL1;E=p8RLAm%qi&Ty-{r;%t^K7Sbu70>9zc2$3+3L(+%2o%BLYb&AY zE)t&}NU<(gE*w z;G-Kbu9T(viQ^Uv>6nsMi%0djWzi1Uw||RTQ3Z$GotOA8XFBO?V>zp%oOS&=V5RT? zCLE^@dxcu!KYi>Q|H;kMklo&GJ^t+IuBDmT%aO?CBb1U~opq!nIBn`4Z-Ggc&5k_+ z1wT+jP2N7l?%|5Ge<&b4EwG%Y+t7q1vbQ%PT_&Yha#CZAWdB}BXMY>^*IGDB2<$(} zk*2bfM}qNAp$o2D!5qIXf17CNB=VGZ?T2fZu?-e)F+B*t)@(?Ql(onl zYIMdKwk19lgNG(XtCZQY4gsen1QVt{ngb;jjp`jXdG~K$)y3Nm3?SukL!-DxfyKn z03Ixx)>dx?hWip#oh1lQ$G~!pQiKC0^o!w;q@%GNubZltI9rs>A*+pYEskOc!Gf5q zMp|nIe^;Hrjgec?oZH>$tY5k-H;W0FMJ!=2*cG2_!L{Esgk2vY4jAKA`yeEq`#+XE z<07Xv8xQVtb;9kaaN8=Te2}sXT+aM86aQfoYO6H&6(07d@xol`fTz9+;H8DL!qQjN z*EOa{O}@YQ>VFvtT#CIkZ#bL&n09r*Y31A-e>KB$r$ds`Qk)r~z-ez@>S}{#_PJPR zvZV)e*h+mm|C-ISQZP4&*|a#T?w=WVlxO%*8KD7T9a>YvmA97F_+@T-Kmxx8OL%oy z4OJmNkvY&K$Og^EraUdiqh3(Jy4SUEHG2JzBGil3%z0Ka9M@zlcz>zT+eQE)Hta#2 ze^~p}H(q8^+gkvLZ(W--bpaqI^&}J+q9dNzvo3zst22z%kCBc(fg*3Ti0ieUcyhdM z*B0a>1ice+QILM~!j4un9Lr#ACmFKOr62$eRi)~TISiN(T3vtInZSm)k0Y zPYseK+q1>Njo&JT>RYT@k~a$2j`mvX29?DKqT#40`0dSGzY_&gz(VDup12QPfA}-x zko{C$Gg9-2sk9nqaPB^Y^lt`XzD`I|_dWmhKV2>q>upg2{i{vn*8cL@%r=5PWVfsS zau0>1Y+8#;MJhZSoN96DPzLF&M<7S=7$&HqEIsHZ+5zOW)LVdaBG4p6s*OF!YX;9) zh10f$SQXr~rEmBZ);7R{lAhxxf5s%xTP9x6gcR$i@S~5sxdXO=R+k#{&y}8~Pfjg1 zo?}ZI+!9sH=(WadPqETP{?p=_n|93vp0EGPcuq$H6vKo_Eo-# zT9PV;PA?ASJ))RR(gAmEvM~Uh!Jglmp2UulRqR1SQvB?NkJoW6i2F=}RJ%7!{k>2e zn(KZ1c-KP*V*&dxEr&2Enb1~B6s#fX$W=y2YxJHc{r||NOKXB+f8mGt-OZO(ZQS=| zH9O^K=Sgmc_>h}=R?QH=k&-e3)xk`rjpF*H%ngr9pb)uc7T#x=w zI4USK&jTY)-#w#vR362J!J1WI;ATIg0Mp_&jE z)9W@G%9;olE!DtOe>M&y!9*I9l40^YUrArNpd81=>*=oSAWjJ*jYKe~@j~=t<~39H zX1E-b^7|e6PWA!$t@-(eT=A)q zPi44&G_s;1iX<@UC307-Lr-+94p{wg1~5?r?-iUqrpoOde?(gVD?rr0;+KUcnlTy* z#qDy&N0g*oo)PkOZR1mV2&-&*c2n{?le*qEFC8{oiqyY>73bF?< zCRQf1TVXJzk}yL?_i;I0ak?38IwzeacG6?ESWktg`#sHyLr+?89vVfvz%Ajx{0z3K z{R<=DTAvIGo__%XUueiSfuAy57#a8yqIU1Z;%&R*A=OyX% zIB$v-*7Nctr}6r{xUk>`Qea@ zp=Hg^$3EZL5+!~4Rtx^drJC0ojkjo--WcyfGq?lk)ql7x@9DK7g0}w^sL!ht2o^rM ze}xHm?lW}N@)`aK6K_&$S+Ayvk@i%AC@ik0WCQU!+ZO)=72!;uMft!vfLt@pirwQO ztIv0-oiv=Le1CkU{1fRJd?+UVUw?Fn#E~OJ>iN~m#=t`AIC!P)Qi--HM11INGa_e+ z?E?S>Q-2Mdt}}5~7%kpicH9)p!C~Mmzz7)RiIN^>lhPr^>+ z(-EI>Oz@RuzYopb(#6IEh=pToax0;`DMvJS>m*L+e$iSWwL8g%Yw1R-$P!mxmmhV0 z0WvEUD+l-}9)LEUfO^tE@l`J^|EzHc$JeC$NPkc>AHqIC|Cku`)k>$`J8@R~G{7)7 zISQgxK`3ONi?`I&vQ*4T7rvr9V*Z_OouHo#O1OdBv1QJxgpOgo9MJz;(|(~%ACNK1+Opv_JOcrCieJx1tPh>KTVvBo7*D0L09P4C zy$7p#ph32kQ94W>BTwkUs)vGa%Oz{vX0LG*9EQ*}2Bw5Cr0t-PLV^OHq%9~%4p+Hi z)Ls8PB`<|lu2uXL!WRM}!)OD*ea6a{9)CnutmPSEI@GP8s0~j}?C6aS$WuFxW2#aR zYCN&06S_tL_gb*7-j2}){B5B0p&_i-+~5Wh^3#+!2~sI63dee>NRA)Sb+7M=Y7g9{iSMX zZiny`)5g2N4=;AWl6}r-@*D_;T@QtHX$o_H(_PiS_3bY$Xvv?$;P#%Hv%|1oE`(^pTtDgTM6bZ7&|=^8_+J4Sn9+cxK`pt5m5DH5osjuo@||ZIt4d zb#1qVdNeK48~kHFR1c8(HGi%q`c1AGecoPtwV&F`H|_+734IeEQ38@s%g|#@bJZgl z-B4fDE!yP=wO+rnqZT9oR<}DN7O$B8rNIdroLUU_Ie79nU-~O%ZV6I=278rvjvtXb zwI^5uKU(RD+{L0zi>;)X?nuCGTC1fSt6ehH5za#YAId31>(h!RYJWEMp9jUGpAuNm3_zhLf}5k9{2yd}1(S5aH$#$w+Q6-}7|8YGCuDOw8bBv=aJs>pLa z7Nkt{SM-#%ITuNALIqchnsBg$1Qv=6P*#Zz$M8-YgIDKH!eGk}I?&i+uZ)|n@q0vX zY~O`!JDT6WXINWBc7IP%BjLv4Cu@xz1(G)}mpRFvA=D|31g6FXjv%a2t=adSShjQ% z{dN{aj0U8F95aDe8If)Aukfn2GRgGb$V;RuAcf)o==Sdb?t=~&#VlUg!mGBGJRIxg zE_{z9TviJEovXYVvqLgIQu3Nv_!PdPI0ISoM7P=EpSBiLUVl+wQ-W?5_&Q&*i3QYT zhVBSU{665-)-%(lg$8Dqd3NO1@7qlg80@{)Y`@!v`g~usmEb*gop41WFe0L9`FLWc zO?g)>eI)aN>+Xa8qQ7m{xeLOpWPkOn{QeQ59#h*@$e zfmYYI1FQ)h{<=#dORoR&jtX%H?~E8Iv$J%~1GH@ZmP+OiVAe5vor52AB8pOtcO?j`CyUPdsRZTX(0^wmClQI(x;g-;Fh8o9P#SV!p2 z^y4?5{eK)+>Q95gc1j{=%cFiS@uS*y*wV~s#sb*alNeu#ivysos+%5t3I>Ca{79;C zpA9$@WOU1T)4&co_^G!Plh0xUVVTAZn2gQ{<$*oJ%6IaLbyr;n&N?sQSBKq~inilR z0uhefD{+pUR#@x&!xZNgw2QlbNvWvrU2U!6aeqY{bgnV$6R@zjT1M8oE|+zGai7JM zrbSn}Hmcs`d>gk(f#wbJ$&T@xm;hmk4~G|wMjA*zu`}eg5WsYB`uaz>FA9q$FcwUa0U?Hn~C5kWls|C z#~NEVM{2tzc};A*U<>Ry&XPfh2`a8JZ-0V9#JL`uDn6^XJvYu`E5rC!K|_fHxY61K zYs9t;^_Uirrwj3n8jdNzAIS5ZWz*Y>t}LPYXiIBJEX-_Hx@pO19EIDEP^~h25P8dG zjm25z7)t%Ifuq_2xj-f}htd=0kJkb^F41D!kj%nV2jnGwvhr_J>SAtQVHu`c`+qTI zFSNR3oVbfE>B`MOM3uJ+hQ(F_GduR);vS!6FAmX`iuIjPtU%&$av~TXSLw{F4A1qb zc)$Sg2iMf3Q*9^YR4+pN$20V4R#eL4LlQx&Y5sO@d72ds{>X-$Iu~#TN-qGJ5X8nO z+JJEtm0KC>wXp-{1gMx&m^6R&Sowu`l7Wyjz z+yypDx_Gi{DDtc>736>|NPivI_eI~)tu8pBi{`i8c0V$k;d&iV6&r-6n}1_}$401K zyLDy~rWs{keIM%2l(FX-A>6P5M6&htloDZU%+FyTL}~7}A6SMs)fsI@OubT`6<$!!A;I=uyQ|7NM<8j&^uTxmzF0Y>KYyJR0{(Kv@x&&J z7`;n=WHIM}t54}te=|+PNVNEs?-NvW|39j_dk!cA)*@hpu-tSY?$7?tgw~+T5%C5^yBLC%RQZUz^K#81a|lVa$J97(EFXw&2W$$pP7t z?(kvAgU3d}Uod^U^d?i{A|rD;?J99q(Rx2$%fld zCxPoLv*=#cDt`uzNr7as1>9mrskYJltT9{Dq7j+?SQ21$OJ4?LSH)H&$jduTd#zuB z!$}QtGo(y9s?A*eP4Wb1;4{`Nk?P$M8*7MTqT{-eLzjdI;(>oEaY=eSOv#yU5%0|Re(;-t%}_EBOPfgA z!R0^YpnvwY2!rL>C?pR$9|>V}!%%tl?~Qp>G)C6=puCN!Ro1a=45?7bAsrz$YRM9< z515(3*x-_{y(f^1`^v5q*SWb{GyH|hWtvT1OXKtKE=_$jnB~{$b7AN(l>tQ=oZk>w zY3Q1R*#5B*`P~OVo8_M7$e)=tKFe{Iu*&4o)PLn7)ll?_%D{!$+MWD+#sKqkBdn&$ z1F1o0^zg&Ht9R2zYgr+1P}2_gCI_NtM&1c*ldWem{QV+^&dODok1Pq_dV>XXA~`U2 zOc51~$TrBoq_s;1$Xc_DMHkorolV6)kr2vveVt9YE zP=CkxRSK0wHfJr-!~rHS(9Z*KudcCmwUOV>{6Uwo=xTjogPcws7h}&Ub=$f!Q@KS( zM9F1`s5JR%L+KQgIPaNpg>N}1wc~^cnAu#Eus76nl?o&p+^w2KrT|y)Q2CuCdmLSP!dC88-ME$>k4lq=1q^fg>F8X8Y=V`da{;2)*Yu2 zQYgFr*Rk;ler0f}>EU6K{$K(sUYitU6kF18S1>DsY|(400>+F&?>1iifDh(Cii>WvsDr40v5k(KudZG~t_+zeA z^HloSH;J;z)^AOX412Ds$`%srW^zuP9_#&(zQw4MSf4)L*Ppo3VobnbV{B7)3orhv zf-Uq4N2&*Fli}!_xS%72n%snpY05)t7^nIY4*vl1ngh>wbo!rb+6uXfzP=MGCMEwY#OTTqv6T9lsZZ|$hZV#_VE(yq zQAlWpd1J9+X312ho*8ite3GKip~t9BT)Tu6_36;!Ma@ONT)TGe9^n&Rtt5gg3j|*v z&N}nQGybu1<~p2`pWP$5Cx3(2ih;HO$@YhNtSDjNMQ0~w-oUbkEdsLmh9W7e5veX- z7w5>kux?&X3QS2E^?rMpC3wg=TvF97hmWeT;uaP>kcU4&m-H2V9fiLlf{l#<@#x$I z7&1NNf>Bz9s;j9*My0tn`7;q&&1XOJiX&82fpW4jMe`JWmWw=mb${^3XY7*92mA2< zqM2W4*O2#uxP2vo#;%~x1~Rq3c*B$$BdmhhpWr@%i74OO&KuYj9w3UNKU}k-&YeR# zKi-21q`&!;_+)gm5s%jTpbTK7j$Fbl71n>)I47!RZLZ4@6CQ?C6Sp)l%?Tlv$aBd9z08VFGsOef zDn$<`x`4dy2~iM4SqJdP;yn&EK$PFgTbay8A&X)*rW_4(*VgfS2y`R{^Iv10C^~eU z#bo6d{|F9+{p`2mxC6JHzA|PPA>UjN-D{93pR^nzZUH@QQKQ#3hiiNh1&VTBa(!QA zP0^4unsHA~cz^aiKEKgQ+wIH8xnD)azwK>bY_dzLH;2-Wg0~UVO!Izdy7CEotiVG2 z?f}|quB}qT%t=PFy$OEbB|RKtnT`u7Dr5z4$R;&6-&1@YsE19(?B2(L<=N-FeT4>i zI7j(-LmkZ~SdLK(cu@wo4Repf4Zdgth$~rY_4Eng_J8EG-JR1%Ms|i*7duCtARF3Q z8vRYmQ^^G^2w~)S8kfe4b9+0(N6k>17Q)5lm`POdmNo0M^iYPF_G6;jvARUql7q!Tn=4+7} zhWy}d+%v2m>Q>SqApzOX@nXhw+_CZp$@+osCw~w*E!S!zzv=kBQWnmqx{=xXtT^4Q zMu?S4?YRxmXJ{hpN`nW5+ru{$Q!MzGbkMAz5q(ISlh01D&L7#WXDwn^@1V&HZD@&Y zU0})avsoEvi)T~drn{gG9dEpZ-4~;tV z^M8PnlSj@ShE62dVYmB`vKUFRLOFE#Aer(iirz=r9-Aw96G#o5lc_dHr%IObM_#XD zh-zaEb*6Qa#iZPFmA8xTZXUFiD>96BEjnJ4&Wel7DF+IrZ^SB@iHP zzOLY@gGUm@{b%m-fI*PGd6MH!U9`@JCw*CJ5`y#NIsDJ9< zUg82)LFv+LaN}8w#2xKH{DG`J6#|tcQuO~FMCB3gv?PtP`}9 zqgpA89Bo^(%s4@;*rePL@z=0kdLfe0%}n%={oSjQ_iA~uOCTEX z_M->tK%55uoTzh6cW0=9k1a=?3aOI~u0|43No^Q9L9BvU>Cnk|&8Y~H?dF|fh6hZ- zoVFQCYToH;mesX7ahmG!q?Za@H#8MT6$h4iKyz7mqW*OdW3b)ha2w}!6 zZ7WEb!k*=lWV+g9Z5%;mK7Tb7OapXRETE0N3n{Y{>_u>)0|(p`tyfoTnJ=^;mYu8B zpkHh22)I}$5B~~u-=-T*J|(FV?GW8#10cu*ROnJF;Ls?)wt8N4iZj0G@jED_IUb}oPWCg1TCC@(Yuz= zJ1{FI3kAt#;T_=mmhIQ>?*u-CYh{)?f*UvmbAo64!C{D#Abo-gP+N@pl=dE(l5|Cb zhjuNF=^~DNfnDMeQCENe%7}M%w5UO%82t~Iv60?`iVP4Qa3z3aZF8V>b)-&ct$6KK zT}VPe&{#WIwlf6(b${XLn68hXG7Y|ZaGkbi$>xlInmU2W&^MF~>>gVXp-qVl19s2- zG~Pg-dM2xf!aP$CCaJGJ?=I#aOntr30sQ9Mmitz9qoC77)C@V){-8uo@m~|+BgX5| zLyP?C{SlTNX52BmDr@Zpy{J!;iWf+J6ZYV$3Nv+?wII2IJ=* zi3dmowuj-wNSxsNcw&1GQpB*=@PsbBc15m@hLyu}OmFdep2WdxD#FmVeMt=zlQ&lY zp2@w4n!(1-rkuHTL=mq5yo5*2J+YRd%eI zVAM^IS)Z*VkbjntV5i4+$O0ikI&Upflz>1w`w^=RKj`d-Kj_f=A9bbYS}77cx)#=ZoCWS#ZvDH-_J?M-K`>#k ziJ1CmvB6HxCDm3g<^$0-GWXpBZe+H3bu~|ikjHS-^{dez+F&MY!KDiv_Z@>(>X+m`8;!hbyHNN0QA3y*#4!>N^Aw0U<{oofFK z1QN~n39Qv{8UC&3h2hLonJhheyToIPeWXNG{h;VRhovO_zVVJc%qJZPtW4efB7d%7 z9lq&p$>;$<$t{)h1wgBB2BK(Q_(Np$G`cv1zbXZU7{>oJ5w}fqb2H?d#dUSl7xOq7 z-+zqwTx7`$?&#*qcvnYjm+yA8B*YqeI4*n*f3whh`Td-;NNEjcBl}o){$MxV@3#)} zGm&&lcd@LCD18Qdbem#QfvF83FF8r> zx2TjaB{JdWt^G&8qu~kZ`c3__B0oN1wSQ4oj|kvsv@rE=H-(Tf;8bQR`TL)#U$ikT zEVs+d!L!$#DSqrTU75sT3E7|%)S{Kll;ddR`b9bczvC)X0&TC1E!Fsp9&MBh7_5y^ z^h7j?Po&(eF5oDSS>Dx7><>^ep|h&RiPE`37e3jNV3>u>l$1ApaCu+aiG=D>`EZ$gaQ-S>ksxTg#c$j2o4dI3YtnMX}o=^gSNX=_)GK0gYjqJvPm zKK#tiqo7!Uc}dHFfLdXq_UxL6>t)HGNozO4cQJ-HepOrF*ZKyfagQ)(;+k zOVr=2WgHb_iL^_glAi?LZ!&{#hJS>`{(b+XhAyN~OPh^O!W0>p5q-~G6*G#VkbI=z zH5Q)+*>l;gkl@WoZ?b`rG7u@@W55Q!n7uv+UBWHJpG#0QX3vrs5}nkzBayAYHStd@ z0$x0stKBO0;pGZXOv*!b@3CNdrY#N`Gu{`1!&hXh66skOxVSa&)9hAI+{Rak1h_i)HNzouh?v_C0 z)9uH56pT8JrHOKExKdMw_e-Nnn&KvdG!MnrCtXjZvwGTGrFB+$4}Xr##2SAN;2(Z9 zWIQpOZ;?k};2n%2;Ke2$r)CBbwZ1`+Y*&MFQH#p%yNk^~!BBPk?x5kL0be18?S#Kn zs@|-~`m?w&`S=NCpoTc{ieSoOjV2*WYYtHu3({~8C%4=c4Y0TB^{3jZH2IZq?V__k5GO<5y_@ySmwUP`p zixWh%JP25M5D~}+ywCT)of8a6|F7p?6=5N$$_Rx`RTVoCfhI<46{@EF?cNxA>7^;r zzcOAIvAj+QYE^@&v=u>H9HODjf60d~HJfJ^Uy%4~XCJSkrVgfO_?+J*$X|vA|)5j_Ht7@U4-c(nvq1_J7l*SYI=k-9(&RFca zHd|rjE+{4Q&wm}Ci|F%3nn#qhHad|qargf?M4?4c9trZ@={U=hRZm?Rs;ut(2w(bi ztA#-^a6gdWbrPYtoW*&Xwo4s?QcT`-?0D8L9cpLhuCKjR1%HkrBYG7SP{VN)-M>!8Fz`Gv zVpoVZ#>nePAaK$JQxD(&xW5-Od@wli71%8Ns{N%VrZyi9c3Hh%H6{awnPi|s$Z*#7 zPHARAms|HhSTOPHBf_k|9BmAm@3lB_(?}V3R5o`j&qAeb zE5gQ@;D4}Vx>T>Yzn)<^+#IK5Ub0?N;<$X$mSE#NT=nya&OO8B zu8fIesb=g`r+$JF6q*~sUvYmZKQ{c;!|1%-|R=sO@SWQgeK-rPu z{!!YW(O?o96OI6&!zN6u!Cui<1~{o{$M#?O5c*JNJ{9+`o<4P9z3!bobnJjxbeB_~ zF3a=a8_k4&Whz z)XesJWbcDLx4Co&!@RWXJ{b-|YlOSNCdP7bdgbVK} zYVJ6DnFmrz(7eNtur}n<5a2(>M*iY<)2XZd38sXuE=Bv&y?&51_>eTy_z(;o`$^>+ zpR^?9KTplJ6-+A-BkiPK1lu~1Y4rBvsKJOzkwH=48Jk5Sq-Jtdp`j}rgMT(IFf1iw z@wLT$WEMgTTV`+EX((WQz&~BtMU?WpzMrN7f!TG2o``ZxdN7x=TP|r-=Z}HQ??R-r zN2M7VG6Fe5XCxq#wR$ZOvOWnB<|+j$8EsFbhijG@3ePFgEhloPYwE*zL zvF(p*=frc~X$&iE(HNR0IDd!zrdv0l*wRW>HA6}cW&H`L?=ws;^gwZXK_xadyHlm= zRL{FrHc%RV9SABGoT1J4<#3%jeI+V!;7Njlc9KT{SGa>OW8o3? zMrIY3Le+q}<+dtxfqzhEtqIv}?M9okbyL!Lhe&B50-Hw(kQRSg^o$?3uhv!gSFPrs zSKxs!V8tcY*8(>~T1fR!$*EjVWnX?d7I;HhG{VYlw)H&0!JuHl6UPV6k{Ail*QkBb zTOXpX;{K$B0kc$g3tB3t+`|XoHE?iWYhugO-Fog>t}EV9lz+{^d^NpCrNW1fN`IA4MkoM5&mHHN*ACF=N0^LiaMDw$sPN2XKV=>%aFSOm0fS?V54Q>k zpbvvI_o5ddm*|A|9jGpgsfXz-YsU4&#Sl{mVl|F7av|JbHrNtz7v)B7sFyT1yf4Q{ z#JH=VV(NK$rDcS}H~0^8d zS`lnO)%IW@rO!Eq5xPizE1x5Xro(A`Uau%m(!TK-DqIbA?Qh~oqwVw5T>+1G&sE!8_j)+ zfPWzXj^J2_xxaibaxz3P#f`J#$3Jz7jmEhPlWX?OacvuO6INqr@(rqX5=4Jf23jp6 zJDrpY1IfUiNvWi~2;$d=B4G6=mjQjfzp+Qj>3846Rd?)G!prsP7~L{S^8Hn9Ppl&P zV{xi|)^;xTXPZ}z(!80`Rd9Gd;=6>{Z+~A-k|}41s&ev|+RGrmFTv@`;Z@?$lmGZB zG;uNqL#9K`nXZtNROC;z*aaKFN4GVq?HyPqVvDfekZwFb;Sz1T{CMoX%;$&q!Ti=z z$C4Zn9uRCzuqJ@s!E4jkmWP^gC5Q@lRd97ucO$sQUrR@`!~(!J#4o$OZz zBH<4)CJ@%cJHfr91Y?sjKLr|o2!(~kf`mIh_ia0)fczmo5F2^RvQ{AtUM>$5WGbT-=0iZg>SuvqwSQs;;EXn8J%TKkqg5Nx z<{p-2V}q6J)6OOS1u$`Rlc^~Z_;hU;2QK-^#ZHh<~98+}n8zx^EdzD4vT~_~`0)A)E>^TNgq>kIVhK-ipx2nr$h) za@l1RjYci?oh_$Dg@cUjaod;AEIay(As~Kp>&||0fboiR8$k?j4qP1Q(rK7OeRsK4`g= zRQc=Y=j!6XMey{FwWPK>e`D5vb-R{dv}R++6@s8*?Q)6k81IQoV)Ox`Rl%*^xw5Sb7v#k+dI{4 zrHXgdQe7V$_HYm3NrE3#c^*%C)G@~ZrAOwpUx*}SIio$e4V?L_n~$c zI<)Z)NH-T30j2Paa5OItD@Z59rcbKuhr0y5eSLqpz(^!&Bfm9CyIdxE&qM|&RNWLJ zcf(V3X@7z^MqR!<-Oz9r`JDIoc|$0ERN$+a?l58*fo9ewo){cj9cmb!elAqRFlX}a zV^4;USh{BTdgjR8z(`(xAZ_wulaCZCX871OwRik|Z1ZDc3~SacOK? z7KmBZeybtRI&Iz0-Sxa*?SSwQ5tZ3Tb9gZngF18dpq%a+^}e?6GMLJR^sL9Q94$*u zF}Gu*lp7HKaUft4M-!=1=x0=xw#M}(Ldeypy*x!725xOM=;a?U3VL0bnf%le^Ly$9 zqJO$rPYN^poBp1=IrK0ib!_>jeP0dPr-#Kw%e>#1e-GFiQ>*-&(+KV`bV}d3EBtG_ zYJC-5&VN)kTE@BoYM91}-m`GiBw2U0SR$9-YJ4Df87M`S-;BIK{3b8`+ID!S24GOR z|F}ed{D%Ac7sOl4FTo&uT_Gu2z#Z^)LVplnGV!?2tRfRExTd@W95#3I&M@CN<-6gz z-#V}+imhb3+#jtP)=vhjbE+Nb9ND*)SLYME(<;bG7SBA9#tb$SI_I(6QS9!Gb8 zF_vLV2piO$&j!-6GS1m=F;2Y_A7bE)hA|)!;&;_m!=7PzHxPEw(f=9AA`Y%_t$+Jp z&!G5w*!ZS-gK7WB*1=aL8{VnwQ3>O(4CX&h$sKD%q_zVep1ndU?)p1sxcSnZZz62H zk%Y0Nr8kx-3`XfQ^HN;AR6d>+IAJf!&!_g-Z(|7Tc9Rkbzx1ld-s8SIV2t0e{UCJA zf4Dfw7xaIWI|>}0v`?l}cv%cTLx0c0`DCqN?A`=FjuoTf_Hl%+8G&7iGz!aZ|CL@L zUsHD4#I_U3$7}k>#JwEi+9pNA8~v8VF<0&sl`$$?=3-b6C0 z*jODE@}d@l7E~AwL|p=KQ3O8w?t3PlSBe$tHV;M*?6Fb>!IXzr@$+*pXn!IiUAPkc zxMq*Wr2V28fubCaP$hSYbUnC%dNE658+|9_2&9cADOs2*{7GJbFV>emN9YnvD-A(4 zOdnr=xm}v1vnV$Y6~GW$fUY~)E6EAqr<_^mY9;0#LF=}h^;1CAn z3;u&6@$AC>a9QdGJVF#Iy@NX%7bwGim{*E0 zD}Bi4B#3SoI_D^%rmYw4aQa_+uG9pIql381DOx3P?lNQx9D=1lJ%F0a_E#zPwtUUY zP%BG`hi(~QZ=!v4rPp*8GESxB16P{ch#ms1nZum(n5pP+2)J@bHTEaMN4Md%=1(V* zamaO|G0w=n*Vv3){eP_M$SO4=b=biEQHLrrO3`i(p2GOFXy;GLGKz>~YO#s=HHjkO zM~6`xv;w(L@eF5Oy0a4{9Lu0 tq*t$T*Wgoa zuAP<6wjKJyOnbr*OAR#9i$pI4;xm6g+2~BD{-{xdaqVsGx<-XdkRSn z^E{eU+g5{q1soUz+8+qUF&l?aUad*1{RYBxYqx`pVt>}8&$I&LeLsruu{7Z=fl_K7d@{r)ylfgVyKxgMVR8VWLs$tRgs#D1~+h<6WmW z^azcVd=oV#;q1O0*V+)3Ju2s$ouc<{c=p-*?cznT0kdpGYM}|bBoQZ6C%qDLLFtTn z+ZvdvH*7x47IWNLthcCUgutswMHq@u=szD0QtC{ec;3Z+!0Fcfu_?3JBNElJVViX; z84Sb#n1AT$0ebr*=~-Eid4SFGppGT2&9UT}-p&98eAEV3l_m$PwE%e4M5x)~4wXmh zHP3~d6zVC4c4;040!%PJiyuo>+WI)$VRmh7AE&S~Gq;SxySUVo*7$CLzuSCJ%16U)g2<3si0+x5_% znIQU0y=T20+I=PVd;48{1|*AewElGuEe@!t&5T?o=#I_9wR*Z5i>;8uK4pJ89qmPDkP4gF@av$eL-1fl79T|JX%tkk;>CD{lG#O-7Q zsed)f<1M4K4B_Q9e2)P0gR^!rebQvm;4n{!_jQc4fKU71iW8Qb)x04+A^4-N5j^6@ z0jKfVh_rg>SJ?gAq(Gvbjh3opDKkwjz>ju<`CqLt?l+CRZ+sgZJ?!sA$Q8{Oz87cQHGY(j(-PUi$qvzRt~rvFl&btTRb)xHZl#6IMy9a ziFDr|7yl+kTp~c=aM54cs~uK8ML(yVEB39dZ|)szpab8eX?=(AFHfHu#Y01;v!@%wpWo0S)!=; zxIm^T56sZ5YdkCDhSkfVs&V;jvJgPXgvi+W7VJg1UxDRs7Va2VUdHk{ddF8Cuh#Q9 z5R~kZ*Yc^bEsV2o%V@M+N-Kz@6o1`_2ZeWagA@lYV>BU7{z`cqAR`>h09^p~Zi7jg zx=n3?OEQe4673gK42#~1-h@v=t^-Ngz$Zd}7z?CZv5(Q`dmn~h(oi(bq!xId|BP9e z#bHV`RQ|3$=(%ih@I*}gbmNB*0%}=wDyPGrq!{^PPb9~2O(_Lx#2k%nM}GwX-QD>h z6)~Rj-isM!szt?aYbZ=~Fl@3_mOaSRdi0yulVUQjDv7P+F`$pF0i|bHnWeN)j2m>n zi-nmzGBJ~vca-}QF5>$3QVP)MgXkd~m^uUf+Z5I8f|t4}T5vk2F=kV4~x2Wban` zL@X4?4?$TdCCuLICP=KK2lWNE_6ixcQ{z&BE<(z>1iojl++a9-pQ{l6hq5pmD%0G^ zR9yFI%P0(@SSVYRR%UUIA9-5<1Y}F>!}sbB{xuwl?lPgm;|mik)ypDK z0;iBEIQlT)2^#ktLa!G|yQZBQ>!#lPzNHkBK@Ts|D}VVR9jKWF25F&`Y8l!0Da#fY zN#&uDl!9NaHdTV6M#Tz%!ARnpUICtR^Bv;Z>QqvWJk^PwOP6<%uKxL(17$g&B>53W zBi69iIu0!{;kbuFDDdMe-Y5jyB5Tg9wZjsT2-b_>;SvWQWW*RMP2SZiibl5M3t+!i zky&``y?=$2BS2Obv-+-&HDn*lU0XM`I@N?i#j@U_+9fZZMUPU{6m(vBIpLc7snb<=ZG34u4*|aL+LRPR5|ge-El|W4iXm6-dku z!uTnHuBko};$V_ji|X_Z*4YBpAgHWt@AQzW!oQ!UykVZH1q(A+onLs#i$2X1vua_a zpR!a7D4t3zb{czf&;9K<<+R10$B11g^17fen3(Xj<6qLuetO;ky987rk#%x0m2Cab zy?+`AL2t)0&li{djky~g)UMkHP=M+Mjx(^I3Ojue^!V?lFx!APtnKKs^OI=9Kes@D zz>Bd+=$2p&9&qzP5?KaG`Qk5kZwD^fomExMXSfi3{tJJE@G?MzZy3h_Pai{0BC?gTPQ5%}?`|^6!wG_kfZ0m$RWteb(gDkteNMR8B+|BC$Kqb+W zkVQ9Ert`H`ZdSF~h+7nR@zi;4ba^%Vn)|YBOPk+?R zEgdD(Wa7^u3k%|Ph5mJ*L^mv;hA*0G5m5>Y zs*N8^XH4u{%=PCmZNGP{XB)nB`t4y`KoK2KI#I2#&=00*Envn&hLl4yh0n>ZuBg-q zKKFJjw+y}ZAX+7)FL`J1%XV zP3L68KC>j8FL5YEVeU>$ok-HPMbhST@S>P@af9iiL!{@bE zgv{$yxVTiaYjU^XqTS7de9CrXsqZA!9t=;>rGBBmGs;cD$(Icj&Nc$F6o?o@Any9? zA3R?IzA_Z7t6~%~0-K19I7!=@f7aR3t-^prplG-ar>Q|A+p_-hPoC-LPWP-+WS&Zd zVP6Q0!V=1DgYV!O^`4}Z;sAe}zzvtJ<-M`eNv$mRC|b!f1PdNiovrypz25AaKq{(Vl0@s_sz>~>U0Ht!t6ZpW&$R;r z;40j?CAIXyv{ZvtoSw;_^e`HFZ~OEZCcBs2)A9t57;2RZd_rHTf)nYQ9`C!@IJV$? z!i|?JtHX9761-AKG4kr1M-s8C7T8nsz#yh&txEa80GVs`SvK!uc=4V${P|CanXoL? zWpPe6x#}XCG@P(CY-xWWe;5=*y{*Nz)-m|t9yLsNbOuL9u1;!?gL-X}n9kJMO|=}L z7{60e*oP`oK9?&b@OpD<9_91KmEeC(3J$O8!)}3}*t!PW(QIfzPpa%?S=n}?v-o8oiaNfAoO z#^f~&g4?D0++iV{?Jwg!<~bY?2rKu&b)3;yAIHr*XQez?DbNG%lN9sBHHh}B&LAjf z{tnDR!Ek@eE5iYkRAyZ}<3G`_6Xk5m-aZ(Hww2Y1c{la=xqCGd0>?4iu2v23+h!{9 zh2223xjgED6?_YA1TyfB4U3d=yw%Br_RYMA4axltH}W($c9MX{pW~?6kR+l>;)VdpG{5!t{VQ-TFS;-+a5bn^(`9*9#NJaFe z)MFJY*ovuTV`(+iPMB()Hrs8>E)XlBOPY8|36JMpd*yGy5wXUhoxow4qFRoDWV)%DPf)GQ2p}mRWLAoH;8hVcZhVxm67<*8oU0jYhLUy(EywD+I-H+)s_8?VOPCak zf88;>6DZ{&D2@FTSzrshwE&zk(KI=m5!Vp@87ulLN4!pP*96=DdCO$}@8&rtQF+k` zBywsT%xwW~fN9jb#8ynemgtRb*2kKrkuHDyrx<7o9cUq}@&a$>KA1w(@BtArJYQ<0 z+=;lK?X$OCHz@dn4x$o3j(ec^ z%#>Z0rGYao5WEVKFogyb-anw)-7D460u$t+)x3|@Icbxl+N28H%Y8*z=Z@1)Rkg0z2kY(Tzb ziz`BNi3fz=&amtI8St^dsXnn!LqIL`W-@BK*CWaFu)FgsNET?V-@KxAsL#%An*K6k zwxAlo{4=puTh+R>(+j@{YHuFePED2Ob95nBh%~L(8NBmHzXaJ#`S*S?ae5($EyA~j z3FUmTWY3f$${@+NV@%DrPgs8zqPVLMhTh++C1-Uv*fNP>#J8n$)~~`mX!aT?3^N)y zrR)awD!BIF;M+mHE~4>&j5_>ZC%J-=CR79{-H1N$?f5y2^{29ARX1+7HR4x4-5T=x zzIi&bHWjTc`Gh|y+|emK0g>a%wkCz)ea+*-c&hu+OGrGvmwovB#ixI`C-_FNdb?og z{?v+eZk>%ey_{20??G97s`yxzcs^|9UIg|o?|5J-;=b?YKWA^GXyCx|T9XP}z>#Dn z%in0AE+i6TVz)aBo{X-J$AIkL_K9X|j46aM@;E~nqVW#^?(AP161Tjksr~NxVNixJ z1Nc`IcOJ!TJ65-ow2^<;7k)1&Jt*pB^#3}Pyn3uiThgqI^-vk!g9awJsQ&7@@)5FG z>-kk(cpv8qMMJN!eD$3qIg5zC)vrTBNa;hiFaKz2__7UPlCyds7A z+8qB5Q2@7d$RLpTk!_6aB0{E)ODgm49wKC#^_OE@OEcFifmwevpQ}7gcd2a>93c+u z1NUwh?;iAjslj)v_d<@0nfO~#ehN}7bDkYv$Sy&kk$5E$;d{*|qlEnw0oTNSw~^mH}-{ovhy0n1SH+n?;X zHfs3xF|<>pk64&X&V(uUV2{FulS(WvfSqtip{@>=L6R!%YEy3Ou7SNQKbx zr4w>5(G0SotNe#7}l`Ne~fZ`mR!_PWp zz(u`jbBlBwMBa}y?wc$4)>nlQv^Pf!OSamjV^Swj)>mqYfPG@r+b+f3@qtaID*xF2t~PZ?_F=@s2{S|0M3|A*aU>=AA&vLM6eIrns7TWREj*>AX*A2m4} ze7SBi$uZj9Ig39}cL;ssC8)mSkYz24QDI@oH;l4Eo7&@ok2Y-g90(x9piO8M?r*ZV z1do3Trf@b>y8xP|_8AMMl)kAoq~f=w`otCS$&TCP3Tk~iOT}P3irVRgKPaAWX*OdU zD+64$Cz6C4zQUDiv+j=#J@K=+XfKb3d2*39Ke-q=kbMEPe`Cj8U}yUD3`lGqB4b?pglP{;#k9xmMV7ibf}uS z(3i&}hjNtfzSKLstF}H@_nnMDk;)qoK*6yeaH{Fe!b$Yx1#`E58?Ey~;>%LN%6osj zUO{Qa`Nqz-t5xUk9Q3!JR_J&u89f~pPM4^4Ac%>Vdd1bRy0cj%L?3mCI$;YV&-Gz; z5Epbb0Ssh@)zfJz%B0<_!=;^f&>tC=#b4`F=Og0RhGBny#C4k6 zDfuGu+l=>6z!(}}p?0d4fYrW6TFRC&g`1o30-1#3&lluEdAgmS)G9T-SiHA`$0Bo} zyH%2x*1Y0KaGvc6XI)_j9H`%FFJ%0y3%Njxhe0)>g!=_hm=yaCpMXzMIe!>Oo_-#J z>$3Kv=JQuh9QQtHBB-hpd%k~IMs6yeK)WO_X;e%y?A=d}3efwcgw5K>7Lp4CF!pbZ zUFgbHskIQ1$Jdgc0h7TgeD1#!3BzsvJ_FRM&b7$>=5J~rJE&7DDND%9UNjrG9lp$pq?T28cZ(pZ`p;Cyb(y+;u0d8Ba?FDj@zbG`p z&ofe6%IfTL`$-TKY=0NN3mnl!$;=azgvg>I3mZ!?AJc+zN{mZ!fS)(reB5B_usk(H z=I2LB*!fxj&oE!woZEjQIh80RI;%#SUR9hatm(L+HoIW?$2@&eMlzQ?$kU7_loA6C z+iRsQWX_b4(_eXhZoYjZn?kGy{)|EcAWbB$lI;c$r|HVw3x@ZD4F6nP(F&n(F#e^w z{|si!R!#tQ#6kxLM@cJXtK+3qhBSGZPkpa&qO_?4$@5U%NuYnHUm+`08_MW`@dBE- zuQs9E-Q7OPYCW{Y%zM7)PtPsW#o#X~#N4DcPn%F^6(aAQDy5F`0b>kS7ub{aL?D;k zhT3?-$&UtJx40Y%IjovV;Qc_YhSSL8(gyDDwznt0$Ehx3#EO(T)5k37u3OwTeV9d~ z;>sJCPxkB3plJN%yM5OKY($zKPt*s2*46g0X70>2B zr!xRM?^d;Km_Z*F)6;@fy!c8EOhduP^k-BF{TYk+*s@(J6z(}~?O#XR82v80SzS_i zhr%d+wy>whV3i;Ht#St!$_0Dgik@sTa(X%VH-!B60NbCVE;%`P0Fu4cR!u#^%CSi4 z*J|&}Dhz*T$cBXVyyaY+dO^cXOi8q7|sbY=%X$HRYvNof?q`z5!rLe8zM$S4lWhm+{2tj?f! z((0A{rtUN1vV76oSv4ao%`EfJWB4RcrAK62()53rPA8v2ii(iMs*^CS^}u?O`KW|@ zv%ITTn;V0Qrr7o$=qAD$Vy+!HW4#u1FuzGsX@&cU)OIDP?F_0p>77Yz^P7`6J7hiI>Jn@~pj8rzDngV!l-o6VmXD()WO1dNi^oLZJYY00*gqs|7E9Ch3g0#xxqs5Up$sLcB9C6ee!(!veevQc z%s`A4v-08)33pR7^u3TebuYLVsJBWL@l5Z zS>-{E-v>Np5VY{6YS|Pc#ned5$z_Fn4!(aa@%72Ch3vZNpl;$HG+{*iQq17@o+jR) zIY5NC26R6919cn0sWWLY<8hcTIen)@}L>ezm6phuLkiQTqP1J&~HISq;A2PNvejy4Kt4xJO&y zRpK&eWmcsZql3jeP*=0cRhgypE!`GqBSK%6n$d2ypg=brfy?g?&1d$F5q*D~k_294 z+b$?((a9jQ>nK>KV)a1+lWG)w1&wztTLgq(vk1(O37&q(xv^za06?lmgf>$*XueFA zcr0X;u~QAU=F-1(`tTImv^x=)XSE;G}H@AT$N{^}|SPcirw%q|RBtU-0@m%nu- z@+^p}3Na!ABG?M1M_-INgLYbT#X~cn)|^Bvk2MKD2E16p-sK_fqo;q0D?lT){p#pg zLjf_DN9AN|bU6mY49)ZiDj0-`n2;yIS^(cMn>|~{j|0WJIAG`LLjy)C%u^G?=t2i} zAHirQrEf0nJwS+bQ>j>WoB)zIp9d{szB-n z$b9Lzl1x{+tx79(;lv5+i--CPbykcf&BqlW^Wcp8p7U&HO}~F9DTTD596ClWu8LZM zD&B(PdqP^=XmIs%sI=DqD=5|hD{63Z>yOC!N9@&Im|D(QzX)J&@0dTeAPijoZpY9F z)^c0q!lePB0gcr=j&n2bq6$W?hoUx~4PO!;ZNCzo7a#{qlM2M49fy6}6JWQMc!A#XK7Te1%-Z zarA|0pCMEazRRB^p=Hl5zd$41^v5n&Z>-9aJ;og%*AmiK#?OkfPWTeq!cE7*6-ZJFTC;}8S8}zPvDyAdAAOeA55^wV+HcczPmg~7G@GJ5k@#(WXzll&F zf5pgokK=zdA3r8(n5{ZI5C>R8WDA!ndmw<`RoM?a3D3?YkU##%AebJuAU*VH1&5!< z$0fFIn1-uDlH6g3Bf6cvHjJiQ~^D6}TZc@ZEVew@L64>-7& zAtUwW$D(6#q63IrPe_v3lb+^|VWPaiz=s-Ezn_0BB{#~pbgX=s;BF%_l{H>IEqcD= z9#T0pLbN4V@xGjJ)-^pPkQACyZroqhmM|#~QA~r6H`J^PpJ1%iHnAS|<=W zbs)Vt2aRIsOd#fAe*vZOSCR96Y8=VWc?j?pv$KyO`(`TUhQ^uq`bU0p2N@5{XCKwD zpl5#;T-UdDw_!sn`_zy{xk8awdR4$;ipSGD$c_Ocwcc-^niE~>AcBO5yMebqb>i>T*QU+Nj8O257|CwSGqE-l-DcI#(+{4)6 zw%SSNQ?BhDMC=*IqG18{N5of^Fm3fMJx1|+*Ad!zePLSAAHEjm*?Q7VWhUP|95IH{ z<=HBj89wp<#@4c!zv#ls;0d5(X**{$U6v~@be|Lk!CP~kqbG=g#=~%UL70DLXv2TD zTL($^Z6LjVrUD1(8{EQDsOo%~vpP+CP4wl)bex`XLo4rDFrIWB!dlofQytwkVog8; zbLix6e>kFk_K_BUnHrq3@_dLi%2I2LHh;B}|49 zL2eHH`@Cm4z<&h5mFt6d)vB_^g2$2-NmbVVA3eDj|mgav;8AOR00tL`(8*Tk|3a)1#>VT^bzM!aae&JL{z zxTuve-Kcp6^c$9yj_I3erVwDc9fv+!7HRq?T$AqCNXBd?zoW;@>8-e0`Tl>*)Akfg z4ZIA$k$k|_8(f%YBrlR-1sZNO$Xs8+YL%rP2-eq}p;$tXv`&gZs{Z8U&)Vx^+zYP5tTi!qfBe%G<5Ycix6NR_!+(Wes zQkN2)XI}txQm`Iu`}v9tE{A{8R<$4mTzz@Y|5DDo#=7g9>BbI8p^9|sx9cUq<&N=2 zc0EiNJ(kTWw|L5BMezIv6*q7f@fP`vsPI?iVkb~uc>|L<;G=jlyUV~}@%RGh0MUr~ zF5b4A+es~;4{+^9_IcF^Fmwiy425QS(fI7pkjia?D}$y$N>MpszQup^k(UH*5?5V^ zb8BYpJqV3H@F@JQqi*|P$>W#IjDt!#s65!c;)Xg+_-OLIOj&fUFczqGD+Y{n+RLMg03#qSQXm`yRsvmPkU*#wW5 zKOhf1&pGrPZ=|X)Oy@)&qs1KOQxG)kM#aA9A2H2kdG(hg73lAk$|9)-b(UT0i!=^h zY@uM}Cd9JdcN-6ukgv~|DtWd=M=YYgFmal_SOI`TF3o^szB+%?2L50asiD<0y@V7v z+Z&2$dfT~Ivwg`;m+)tVRn^Mnmfc{Mj#^K)-m}k%aS>V1qsg(M${qtRNMUmOpbJnX zgz*=0PYO)Q3@wm`-#AR|RXLE4E$048hGfp! z9Z`C#pi@z;V)=iIx4A+Hi#Zh}Y75)FvxWyDoMPCFTneAzH4TI7++bJZSj{akM>3xT zrV)uZFy?8y=}^}w>+U3O*i~<(#!Qw|#^u3DF;*YdlBoohV_~XG{3p62MH4?c{#wO+sZMOs?HC* zQ_=T%tNQTPr;%*3#vH(jAC`(P0{yzkT-eve@=iDt<+aj2*%2EckFWYyB=*ni zKw6M8Hz^C@-Xf!*%0g2`b_vHZ{t?wE#}UzlAqaosmJU?kIW9CPl_5Y95?+%TegV(< zfh_OvAv}uNR1=7v%dyzd{3^qa3BB=a8Qdk{{6Xer6S8r}$~3Y`^tKPw+7T)xtG7$A z2t&1!qR;4=r$_eQuDW82%?<;4_KaM<;fGzJUXpc<<)ou2q`wFRdk)HC(sI8~H0&wu z;n;u6s(L)r02}swdI}_54@Y!2$7|6w>$q-h5|NtCZ7&=`y$p}O1u8F=Q$3&-e2Ws5 z>g>)$xtB*r#r%FngKwHddB^wTF~Q*wkvvIgLYcOVD>}{+vBI`d5HZs*znJi%^|o#XmO04wjM- z>SiqIgLIZ~sryX$%vDypQ;-413eyQ|2}4arSXOW);h*W&8`r;+l?b25L;`|VB6`)X0?L1BlJZ&95xoS5MMLs%eI2659r_Cn zf>$`lxNN(~h-tDQ&mhksCbHP4UYoPdDHpnEm`T(+&OJH8{^RPQ4o6?GX{?#)OCN164~BP z3GUUJ)DYw>;Fgteg1XAPi!%{#W|G61U=ISHt@gnf=6Bc9VmzN|cb9A1kJRXtEFfbT z_i||Bh;6}+CztY}5kK#etW(5HAE%`n$1>)**Mf2$NmMLBKZJoo^V`a*2+S`AX?0&E z>FZD_-1tZl@K^1QZ9jpSX+VDzk8SUZFd{~-j}--gI8r2G2Bp{f+nh8M2?%GK!h><* zYgU9}#r0%-XsN1fs+a*|^ie*JYaF16v+zL|Oj)zpVsNrL5>d$X6*1dtw8#df{0aKa z?@cxiEAb=b4D=}X-zb@e+?e&%b6K(Q8`kGIcO9Pl@kmVwN3CO2-;sYG@Yf2atxdFk zgk;RRd;V%oW~hFwKydNr)*QOFt+E)3<`OC1Arx)bxGKa4pAv?Nss4EpgpslRDr$PO zaodlln1L{n_##3yxI`|?je^8e znP93X)>6K;l*BHYRlCDMa5Qe*L*m#_*>f90MQfcbG4Yyv%bR}{`BtVedE06rNZNB} zMbK<=dM5;?Xn^ zc~)YXMg0-^o*Z%pd+3OsB|w}iMJR`m!(V4!q63uV?I}Gs8Zcr)ok8$Y?%}*jEcgZ9 z_)0QpmOxbkU2A{S*qJ_g59N124HpOA(i$!>vq8=(Q z>5ktaS?x$m6;duQ!et$T-76PwC0|bN!8TL>DazsqY;DpEk!pTtcznWV20JX9sFXY1 z@TT%UxyB`oI7hS|#YWKMe#xBrEd$G*C)G4edk+@JpIm>GZ&1RJ*2j`xB9$C_fiAFT zyeSpXz+I~>JdH=lqu8%?$9Add5!_worxt?Bp|+T~Svl$wJHIC+f0njrnR1 zz{Cb6QP1LOGHXN&(OWH5%?`^g!Luag-U z+f7wvoWOqE` z79ZcpXBUY5?l-gvKBz+)zbX{L5~kjyo4C?Ta_eND#m*?U!Nf=L&y=4n8^UT#;%^Aj*=IORE5vL-9bI%WD8wDsE+#@+C4FgDo)DX^R?jKUqQjcw zP<2eyAZYeUaLuyhB~7GQ0TkfMR(YiuE6Ao<=yTEIRWUaJ!U;}^t zqp6U&$+L<9zcaEVb(}hiR+=ZFv@ih==}nUNUC6U6;Qs?)rSONQ<@8J#GRjm!}vQV z-!9Iu9j;su%D-mBf6zfB^un9CF+WjSLMhlG#40FVyhl|HU>4goQiq3-L<{f+BPfgU z4=Uvr`SWO&p5!kmuW@B=Suz=!4=&L?4E4+z!A0S%?)`IyHU;AqI{2!oWWIk%ZrY?% zeL=T0BNj#jNl%M;?q3Itma-w8CPd>Y7tI9fyK6p@ytVp&`Kd?oGEuFXuZZb%MC1+jUoBc!f zp`}1?C1!jGD6)H2c~Cor(^A!=k9GJ<+K1zdaQ|Zgh<+;;=eB>s7;b3UVy|GjNZy4f zA!FDsgow#7T%-V?kR7`Rlo8#@h+IDG-Xr9osDAHH>AcktWykIuaX_y))?#qELDqb^ z&5aQI4jxd|Xe1j&q@<`}0t0M?masP|O3HrQG-MXpJjp<|6|0kBVqqk2Hn}_xkm^AV zaiW+IvcZJ#kJ5jsj<5xhwe~ll{ZK(DtHYRHro_ZH!ftVdGI6!ip=TyGkaxV=4jwAs&G)o61MrqFz}40%7n-;6v?}Y%Z4WR zy9eM*WNy)54QcSYV-oT|1_d=y%Vwj!i3+4c(C{ad6lM@BOX{}6RHm9hTHA0<_x+uq>gvx_{r2 zB&|Y6fueHlOtA<;U;F<^B=XBJ%+q$FqOG9^BJ>*pm2v8zcaEaqiESV>q{N z(O8^~6j;=ACb@;C*Q%>D2wey0Eh~cb3@oj@tLHPUqsg;C|RTqHGM}#WSgB z5ohUZ%X+u(Q^AD)b~*d|0eT_K(7Gn&hhme;jg6sMk22l-BtxLb7Yjzv6NIlK`-8E< z$jWelTF>ZHJ-MZ|hJdd!Xt}CyaV8U*LCSx=)=KVc4-3um7Si%g4^jBbPxyRnr9!&E+L<#yxsK>Gre z9(jZ@WIwYFDy&;FxOaS`VrSYQ-nHkS&KFu%Zz{EKJ(aE zL518EnLbgT7SvVB{eBpU^RuKlhwkby$M`bhNI$+1h+`Z{U`xstzx;|){oH|Y=5K`A zOPQj(rchDR@mIoYBoEfwvg=q6-|7rB>2?%yyow;UGb&+vDYrrs5VQGT{%|6BopsA4 zdi%K6eGE3KxLzh2edv(y!5M$e7mcX)v|uP5ez$dqyO*+_!W~Zz>e_m|DcA?A#W&I9 zm)9ix4`Zh?7{B|*Qm}v!2;j}1@egLywfhCQ+w-`{Wdwml-X1F|;|Q_rmX8-JSC#z! z(`A1DbBoK|GDA|fkSEILbM>TG!Ht5KTp%-Q!#v{ORiFEn!qN9;S=N87Ma7Q!|JER{ zFPZ<0Ju56<$I%|bCNkEkurS!go}Rfa!b{h!e@=kwH&yjJI-a{Pbo`379B*MHzAdg&47Sj03B($b3)uZY4Gd%L< z(pN063d4L7Qe&`?4VzYaVD~moU~P4}g%Ouwyri_PPTv2?>EEqJ{f}d$`8A1uzFW;L zu5sh{#2OmSaczwu-Ghd7uq@;kk*HQWPH2DnVC2}JnF^{noI!s=C^zv+*La$f$))%q za$tgxT+$g?#k%ug`C@@9^M!jGo92l~K#)tGno@Ek>qUXS9TGW;{*e6@H6F-d*fHG9i97v=jj_veO`(Z~ymF656U>YvRA-Ba%R20iN@ z?`|AD0KOL5^Kh%TPPpnoCQ(;d1EwC3 zf4Qoz_Cb8r_aD4@nqtCD>bB_LEyoMuac)2t$KW_XaMm{Migs;2xMCv|yvsv7t>+(J0d5FF1e^hy3tR2f7psa2tZz=0!j^#E$m^ zH~3FiKKz_Epl`tru73*wy@cCHAl8L-=-v_oj!^A>^b}lSzKJ##Mm+^#*~H0pemy8! zCy0NR{6ss2iF zs$px$L#4E1<6jSv4NT>bZpIm;JKkwDx_|6pVw(v&?nJ$uz7i zH!8Mpg$L6pD?b=e{!wlSpj}an4`kj+_D8W>&fh_Los*U#UUEC-B9`bdq&;^k-nM^+ zWcFsCh0x>7)cgyNj9ga3paH`Aj>PgoIHYSRH0UtA#FACC2&&!&r)EfLHuv3B&w?J*oyHT2kH2C+5yTSGK`yu zNnbFoh)`MtWmGKbpAtId(Z9$Vy} zkGHwGNStc{+#fx1wcxdr40rE_8-|&_Fxjr(?nR*G`bt^mRnhQyfxx*B)TVzb#~>&X zo^vp(I4)?PeqfGp90U$rADx7cRxb}u!*IqF9cww~;}y^#Gr2LkcoG^z9Fbd%jWq@rb*Ic3o*xW2pY^ZNd(l!B@8c~$oXvlz=*Y@7Wosj! zf)^geag-J}F$$MgpPl3EMn9Pp0^Ky=53Sn&QyzbbVQlrDN5ZVw6BL=dQfP%cNdVPY z+YTZbO{#9{LI>U14q&67fjNnygBIX0orQDGpBo zJZtBHf%>oDa4p(8rk>DUheswZ!dHAje+sqJz+aFWsJVRCie%y)GhhTX32JVxy1yu$ zL8@i+xM|6r7-KMkX4~orN(#{ATI6x1PF6Gm;hP4;i9YLdKA<` zil*`OMZrGHyl{VLTH+;j-B^0kncJ2yJ}GlPP{CG+x$Tk;b#{wftR&Z$v69t+fZiLY zI#1Ep_Hg8%z}{?8sDY-~40Lz{WV$BBL;ADj+YVchnx{(5<})ly9^an2Op#mW7&noy zQiWw7wk)x4=O$c!;9mUrRis3kw|TdM6EDK;;MKzabfAC9;c1trcH$E!ClX}vjrYQG zb+>l7^B-EoGBS1V3P}$=cg@RSKuq z$iiGGgPH}j(?fWWY;-q+HjS>&u*8i0I*JZ2KVJHo#d~AeE3cT9DI<@Qq@JJs>Tuxz z?uMn~&aJ%psj&Z=RsIa#SXrdv^Zr}&+}UHEm#lvk^-=DtEF#cUhLQnRAo1BpUrEAx z2(%)U)z0oQ;k*_fqbk64-&u>^ql0#s&_*f_VCX^Di1UacX74Pc{KA@rDnL+CFYDVA zoSTQV9&*>YT35B<7#t0byzGyDX;d`61{sA&)UiercV`>?2fqvqs;fXUbjaW~e4vD(OPE*qS>U9YnvT-{R+=YE`pxVQ!zgfw>bNtX1~pGK^b9}k65 zYv?JA2?^BXeHmR-BhKIR^G+RFs-Z!#e-VE-J}onfc{m*I(8fG+|5`h76NCp@qELX7 zsOeO;EU`?7+EB0hEi=UyZ)JX&yeaYa7Va4{9dJcV^i^3)(`ateH zj_?G$8mCJz#0YlsT~#_SVJlwvhzQ2n;t^u|YY+3Gss<>n1KCdv0TNdM7OTP^JRg53 z=St>seq@O#c7U$ETsC3fI%UC7f00xd*cA{RQD9d5Wt1uFkor%rcG<>CK99tXl0WFa z+({ADK1o^WY-X4AuU6HeVMI!IfWC24L4F`BS}r`!Fdt^zP9r}xcGQYFDw6+mjGyyz zcuW?-xy%KCq0n;j+zluX2?%%^2D*Pjh_fSX1NBKjR_)h+7-{~v<(?c62Y!(lC;%99 zN-OgoMSzM-sw_+9n1n9(j|VoX3wz$c3D&IY0pL}V6%==D}qe~*pLh{#$T$feQS`$XrXVoCJDXMJw~xX zt%>_;*mj^yzI6m9;`xxaIT)I0GdoW(mgpVlnE?x`W%Cil#?^w{M|1Kwc&Ou~bQLkS z-F|IZ;-tMrmH*vI%G-Y+A*CbS+!KMFTiyU@PQvin_)TFq_D zHbGut4D3c~S?)f25w_WNNWk}jascVo)$j7Do;T$i*8*4#D^*(s8&CIH?$0)o3eACV z%^C=HZ!-J~TA6>qJEhjEXOc3YGy0q!!gx~6+7u$UH)yOw{f^KcdqFUb0 zaC1Qv=wxW?c1LNbfS%ebKmN-zt1A&q;4ilO$7ImgMCQv$T%PCINAfq?R7##VG=2zq zww|Jbts>^KZ)O^mHP^gjY+BY0KJCJI zI)7Zjk(__9V|0Orkn!a zZk)b*1Yj=DZu0H9(%?Sk}8Aj-!cI5&15EDyqQYMClm*Afa z#C`cSMpWftgn3zi8mM7!K-BF>V2vH3?U{qwF>8N3BdNcD5(x9575)pgd@*c`&@Ma? z8|mn<)MPHd3hI#|pOusso(_3R<^*gc$BGwo&*Qfgh--6zP9p;~3=LTP99tve8_65w z)v3sQrCh;#eMKR!WerP+kc%v)UemRU#NOf2-B-kZS&9g*QyX`vKeU`Q*O|oy_%@*> z!6AQQ9-RO%*d89FsPAF}TY4aqQfC>8QV#KZoZb@s;fww|q+qXgAIC>zMdB*=z3SuZ zA!$r~Pl>=Nd;MbbuIsmMTZ-~g=?RJh>1%G=L~Oi}LRo)UdzbY~7WUw@xT{~$9V|j9 z0ZUS7PPbcnF$}pqIsi97$iL=%9@>Qr(om^}?@xb!&Iy9F`Gg!>S_I#Ao;9-6$szI4 zVF*}w3}RJ_@!UMZ%RgZcD1r*-^R_|#Nd(GnDRVyYIjDMn+{<$1TWgO?xCbx;>Xw|! z=&%KqO&)?7khXh2Y$DgZtbeP7%Xw!hKdFDUw8QLm4wVFpc#aP$3gG} zOFuOoM$)+kbzaMC8O8;t#3HkTl!QvF)rPxZcfYXAE|#l9#~NCvSNhWg0rR330ZU2) zx;83n7|zlQh-bN&%3;`AkRwMR7!d^j$uKm=>VB;~Z#b?RN*kaYASd`|{gorttjmY9n)p$zgYfchQN-y`qU) zuMTfA%_!>dPCezOxR46GkQLGFA7Cnics;%lcPALXy6OW$3AbSe9N63wUQl8Itw*w4 z*>yVw2*OJd+%B6eWGjTYT_pDW605-_qVl8|=TYN!cDdczGDUZc;w=q)7D|MF^)|Tn zJWv9$8KRWK8Q$PYiunIXy6B9$c%nnq-Z?A+8g^nM;Ta$4M z?oZoXe+Xj3MhA5qwpQPf%KRVa4zwur&0a4D>~;mcA0hPhZ$XwEVdNhliOQH=a$!i? z&Vr$@C5$K0zJncV;K21AhMJ06h6I$yr5^E=%W|NxlYesxL~fG`hE+3vxOGq$8|UF0 zNCT$uiy3Y_%YEjdRhLLRMG||LjBIw-^R*IED3xB}+c)iQiP$y&3eYVwcXj;jfv;1g zvAq2J*?O~6lwz=CplN%C<%m#%MqV?uOPe3T6p+X{_54RDIa?!XhiQ}1tShf%K%7R~ z*hYyqwT_>9rSUBf4iQd&IkiD*IW|yts58;vF&8rBce+pQB1rcn64XjlY*dQJrRYHbsX8kzf-^YZ z!#ImN2zS%*!lKxJ*77>R&(l`{|QjeQ&qF`d6>THFg`yHUdqFHne4N z?;0olZEq!(ka;`CJY*_Czs(r9hPEK{zrh_MK)}%}TP!`?N&%-Cb%yDC5Q1S_(Axp6 z&ckyR-e;QUY0afa@nsaK2LMTo_X^$?yb(YXV&;!HPY=F9(bctK{8+7n<|C|(a;N~7QJQu_bMWdl*VV4~;qVksO zJOQtLDZM^_g%z1Fq=e<=!^}qOlrx|7&&8L28ZrGGOEqV6b~2zR~F#wf0e zImvzcF;-5DM2ja5@FM`&Cc(bA^$$gF@?+{$`k~2xSQ(XQ^Dg?*KSjk;{ZG`jHh9&+ zy?s_m;6UV>AxIL=pNnMDo4SV6cf^N*ZjhV0oc;GsNg$GMOcU}RlX`2S8XWEG>ITPE)TU4W^ zO|#2?GB!S2ponnJVUIhoJ1%dH97{rZe30DmBRUbn{x_Y#F!G^2@Rq%YxtIIbr>rhp zetOdy;8qfccs$gfTuA$MF$;rubQWHQ5|esSZW+m?^1-_5FwMP8lCQ~XpqoRC^pMZ! zUc3w8ny#)3vN`HBE+TIz*F=SA44y8V2L@Vy;^orFl4=g!^4d?`^~|Z;E{=@}HTLa4 z3mb(8iGmu6#1$LWf4>j9&P`D&cF{1209!(3E3lxIfcpOwk<9l`bMtd?uN&Lt!qp@j zh@_wT&T@|W8#&V`5h?XT6#L(YRoFP~P6c6HZ^r z6H`?TxZkz&?EfNT`u6Le2ocUL$nIDbDYHJ3M|Vwz5pi5o&3~;Q(JNO^PM!Lz65P8g z`WQSIS0ry(G4b*ueUX@BHHH$*%&y0OH>SqDG(@6~Q^pSf3|c6OUq(NAr_7&aH>QuMJ`dydO6) zS=`ZIuyE?@2wI76c93!SXo&f-5-HBivgmO@5|k%T`3i=|3GT$Eu=%wORD2|V1Y>cP zu8=&!T1Hn#L_?0SSYcILq94(BfExzODlcqA7EgnUbQ_h)7VSq1USu{!N}PpC4qEId z>smK1;pbr7c>K_J&tE*jE=1)pVnvdLJeRd&Kb59B9Dd<@`p-$Fnq+guJSku3m%Sd7 zW!C}8e*+#H?;_8;%WB&m3sQK0izsTTjz*6|6rWY@TtF`eoHJV7Z5;1lDbr^1Q;1D_ zBjx7f`grR{Ly624aDrEMGK;S&%3MJ@=-Bj*pKw$!_tr#AwqegB3vTJ*AXl*dTz_>> zh+3#A1H%g(;2~8Y?$c;BwAgg>Y^8Ks@w)>D^h^d zfrZe!KGO651g{X=Acn8k(##vr^9E!Pk%M2YtJgn|Ic6{qRXR)iPQt@gce{@SWI`gv z`MR9g)U06gvXK;j)O;AsmG_eGscI_{%P}j=q%GGSG9&#yl&scx^4EFriu)5#BjfK! z7zVIFaUDYkvDYu`3kMN_n_%~YZ!9E6cJqs0`(yz&iEauyLOQyB2;MGhiD5;g$1hY- zdMIHB!*t!iR$Q(TQ8cvaTK<3^O@KE$V)3;z^bC!uVWusAafgM)b<4LTEQnU5P&^HH zMdz2}9TV{#B82#~)ariaoCp%M|0ABsmTY&2iY^D}H9`{&_)I?r>IXo0@o}pic6!d5 zpxcegCB>XsumSRI_9Xjh)0}Fs$**BdSAlevex$@U0iD!BV%1Lq)Fq>Tf&J9vUTeH_ zmt<7Q0y=7cMTt3_CnLzOjx4qt>Z?15dr|Tv*j4IA7okjrQ$EFYannndqnx)u?F66L zH?LI%#5Ai-1gZH!k~&L!6Ik@xlQ4aO16!*10~pHzrQq5CEM zZS7XYhG`YPc@t8;60Pe&akiPq+xO7eXO;W>$AL|MB9<>8jL}z;2Kb;_1|p&?GBvkB zChY<{T!2Ma`L&+Y)y}`x6u{g?=x*sNdSS&sU2-nA!wRHCb2xr74DOj}|8J+uBsnHt z(Y5!#E{jJoMa-F99HSiLd9Mc1BRT2pS1%cT^+t54HMm0R=2Lw#!VFAqcQ}so_?~a2 zK#p{OxYAj1F+8Fy!YZZ@I8~3ZM^S;|79hRg;|kf^T*CU*C)!fuxE4$*ndE%3DPc>U zb_7@-KAB!`-kBt_f|jZHQGuz(Wz0rg<41bTrQ{TXAKf!XE{cjxcT2M(&5At;O zFG=G^yMM%(oxx#4J6jj1`OjEA*swb%MWt&c8fwJAJ{DQ*!xAP>*ZIkG;XE><^5^M) z7gs@r{`vg9NZSEN7n+Ar4rn+eIu z0eHfTF~92G)zS2=4oo_B_)=nHlWR?=;9Nb~iWjXs>LNPN?QTOH7FF-U2IuJSwg@(3 z`Q7kdbg=BfFNRie(&xi*cvJovqsR= zhoK{?CJjisrt(Ky${nAD_lHykNBS0CCk4g+>B~;1cGO9iY-6r50o=fvbL`(^&G@qg zUOueR3Rr}m3xoaaL6W#42tBud(LTA>K2@T@H^qHxA3@6#%#@GC{&KCkR9mNZL)Cp}m0fB4oCHHcUAiU?gBcJDN+8`FwMU9iER<+;!6fygCK2k| z)F!!Eg1ZZsqM_M#Y7+WzwxAP%G3ukY8Ax!{3!=~kXxJ_FzpS`t%2bwrAp8R5u{zfL z!RhpVU7A5oy}>kCPx{}wr%8Bd`P{!-r*D5k>qh@zlrWc{_D9U6$g^1jRT0xdj5r3I zg{v>Q54Cr^B&McQX}Ch22XLPMv}%}(UrQiY+z)BC2jAf*i2V`E6i9Cdk0h+d)cy5n zk@y(5L$G`ud>3lHZ&(U{7m&81Pxl0+F~GaMVwu``T|z}btdVJwBA-hd2A~sWBH%ju z&qaGu7a%3*A&0u|caWP>Shh)lwx;eIf^K72b$&&wy_$Y2(;QRX9IyQ6(j7lDE0%3Z z*|v5uSF%L27sGNaH#=P=IMW7Ii2-xR{(y08Z0PyXt&2Is`!{} zRXSrAJ|@I5C{ro5auBkiS}4@ILtyraq^D9PJVainw_*1Otx{gPp>XK;8kQfQ-p3Ad zPn?=VMxMGN!w_JMP5vk%gP+-@H)+W_-=7PUkb3SU4MUA~C7*9Ea?BAmDo> zjBbu((({bw_C<<+lCDHP=0WsWb|T}a8bEtMtd_I||9djH{Gz!yIdzWm3d7hRc9#TQ zEmy|Zbe78shn1AS@}MNZm-9xyC?R`$ji!;5kHRWt1MD|9Ip-)Si3dl&CLR?o!_R(r zh-$tYJd3=2+F%25KbZk2K>Y=hVr(=CKS!&sVnX_hne#7EM%m4s|j(Z>10G|%`uL*IqwSe*R$ z5XJ4R!%^_Dx&6{L)H(Fj>|dDU6hCD0#x(Sg=14?)$-Ku^go=&sv#^f7207CK4Z@1^ zv%)Am#4dGzst;plCXdM?S@pYY1Xn<#k9N1S*LqB)-5>m3zrj9Z9(*}R*<}0Oj=6sc zIArr>QmrdpZWAYoyX-%^@xcq(&6A|$Au?&%x_nff>~CyaAU+Uy6tjeea7X|Jdz;tAN+f7;kJ}9#dh>$UR8aM2Q=Cs1za^YfRHoj&5PCPh733Uha zVZdpWtyTz1>kX%NjS>e;_?TkG6jSr0@Nm<*K^{u7+o!Wl zphJHHE@UREp1`|pz_N5d3rZO2!LQI3|z95)yzBC;7$F7Ox1MRwb&`EZ8O%Hk=faJMfeeltL zPpSLlz6n9;24*H~`w(W%5JYgh(x9qgVY>|D?_Fxy7`aZtVqHi%0!Gfe$StOj^S_+~ zki}U{Ixivh8VS=L&H95a#7AWq#9w2A8;yL9LpjXTy+$n{ z#8tE}yaEp6-avUZhE(Bb(##m=obzsfqkVyu3nh?{P&%2dvMdSBCjuga)*NguvRl-f zlUG+tO#SQD+k}zeHVMoZ%|_;Jh@(Q{N2HK>gj&D$`A`9|B=09KD)zw=(nruW9X&yX zLE!Kp10+u;|83ZY{Xvpj(5x+_pL;6t@*HIiNxSJcR6g)%~CO5 zdi0EvJqq6imY)F+FbJHEWGvHiXiICHN6PR(9h1?4L1kumc6WvadV?eF+$6MWv{fZzdzKY<6eUL^Ad_KgLLrEH4%$<1%87pU6F)WHzkxPU`p#GLUtG8aG22*=gQ)2 zD4DiqVr3T5{NUs(C7#rV0a$BHq|kS={P0+6JKM)QweSSx9jRP;^*aJXV`t^sX}2+P z7`s8-!`8$ln36txh86OEXzY3j%vyC(%tov3_lebFlhOxk9%6ELL7C?sYj2kUg^)tS zX&TOJX9JJxZfnt3-p4wFOu4$mj|>%gbmq3mWSo7N@mXF%^pdIpW=P@Gdb7}N75}fT zYOWjKU;^P*^>Q-lYVlE~@PNgeROU?5iYy&d@n9wFuzVi2aVo2SNKjRwF4nQ&BwYZA zJ^$ees}6ZK#i;xTro%X_0)384tP#V}g~u>VN8SHx-7GntQN`UQ94o!H07qlJ`4iL} zgSratYPr-X-IT-S^#!{vCA|h>kY z!s%j^}0WERUW<|iYKy{#;Vc#1M^G6ITHk#JSL0x9R&x78XXl_J{ zTEnJi2L?S}Qx0d=awxvyyA?316~X#&xYjOjsGEX(^zSst$|~C1%LB*Zp}MnGS0yq1 z|08HtQ$R0&0{e8N_|hPKvZoFZ0kFr=-=Y?-Z$}KvXERm@8nDMWd~-abu%xU<--?so zO6c~?0^*a3Gqruf0nOB;4!pSikN~MyFFgh}D)*$=n51mWu7SC=vsQo3<1urElS^lG z?P|&kpK!xOwl5y0|=hsLGmX6QrB-$u%Rl#G=)yY0dz;5fs}q&OInJNy3^=YD10i;xNmgzJ2PkUMgC%q~uO~qm1l7 zgs#3I+5LX&&z#W4r}E@C=0b4)Gze%4HzVtnFQOyL<_Zn^Ew05Oj?A(i1CdhI6i$U{ z;JePco@^CTvX0hw+K$hZj6y>wNnRff|L}Zy zwI&v66d~h6TINC=bq>eWOuLn@BBIZl&_2FyhP%ax7X7pa?|X*_6Kr{9Tb;Kg>JbGt zGvLDsyL0?z&SAsq54GCuoglAkL_FJ%IVgybtV&ddo@2#SOP*#f!+*un`Y!LD(ex01 z;#MEOl@W=`IEns*o*ixe`zUZ0Vt) zATiBV1NbPm;2)|c;|8K3^-$|XgXHml$6|A_xG+Ai0gZs1z?4O~{sxu&sy?yIg z_7;sKExgi5e8}9r=ifJSNw@@m=mAq-sEWGz&GvE^R&%eFLSkUvx)>13l(t3)`)SYX zL+aqNsEDsqyyqOp5F2myv-k{o>sxp3v!^|4=lpD$4v2Ds4a%e-**5vpL8;nTVv_=2 zf{DpAAP{-)O-fwf;|yE72s}pbXhJR*Py-}iEu>=q8g6-keDcxjrc+~oepwdG$jOyO7PatHu77rUUkgwdegShXJ-NTk8)ZPaGLf4nM9{MU?*A@q6|t9#qt2=w zV5&&UQ761P10V1~mFIbqmj$QFlXgFgDD0lObtQT&(y@p1oUVV(bJar4ppMLwasMXM zB2Z*x%90e|MEqMEu_+&afW)|DnHnSs#v&F6-BjraYc1i(!U^qYH6W z7FiL)2!dTpGs}gyfOH(YcpBXO5RC&!q~6*Mwcd&!6RJih|6JaGx|n1Ez!BdxybnYR zOqay>o)ZzWwf68<`-ij+IzjegIG&>!tKz|+`vq42o3jt~5ah8)Ori`b>YN$(wuu^; zK-y;ZBE<7!LO}%Pais~FY3!KH)h7^B+^@eeXJilwTuw%1ZI5k){89dUZ+BDr6XEt4 zg@(Hm{xuo8hIn1tFMY~y17H;O2|#L)4XbxdVWm^Vc8n-V=oim{u0AG(h5 zudz?-#1g+#q%ll4FxWxW(h~fp>a9^v5I!6&35{dJ{68#zqoR_vMljvCRc#Gold3)} z*VU8n#Q5C61WUY~{9*#@3?X?^1BN1e_xW(eEOur}HMli-BW3xQum7b^2uU@IH zQ+X3E0E=G8FZ%>|{3eWH#pA%MOof$&Lo(+d?wP-@ky+cV1mxj}-ee3Ky}={_$Ut;t z0!?gX3XDL1^NfE60%MO9t~@$P2wCiqFaQyN?tc|K7x0OPyvGR(GDx5b!t$dF%Uw37|cX@ zH9%Qf{&@OH#o<4OK#o?4#Z^1p9GIaDyjQA6>#4_ou*(rJX+~&21@2qh!T)81_YY%j z2)(r*0n8w?y@hl7PfbsPED<{rtLXoFN9 z{9ElATvYDAPsS9dA?21ryhGd2$Z(WgJBDvuOPh&{KOS5}%6EZckZ?19m#i&;o}g9GZx4cbb$-6aUinK#5iCDsAW)U6p$q zvkQFUL?h9>mYA9TmMGzPu=j58+Da1WEp~4PURnGe8)Fa=%g8Y+39}-u=h~T^(DO3ru#i-SVfPJ!$!k^zN<~~hit|;aTju>p@=ZI>E6NjGX$t5 zK=9J!DaVck-h0u^Txec7f8zNF6}-txlSD2OG`Z#(t~Y%RB14?g8mRqSCP=#v(H_(+~EWrDlA~O8>9w_QshX55eJEO9su?r9^2})=GkV z0lklL{LcHv9Z>0gt?*}AWDw6gbUBAC?Vx6pbEUumW6Q$5m(~ugL+_`(QgG@oTyJ2p zqqn`?CKb#nDut`G9}sNh_K3{JsWF#-S}||2skJm^bN-qzEuxyUFXnI=4l9EhJm&(a zQa)pE#2hP+5PKL%Lz8k_qjB8~_h99s&Zow+hMRxcIC4QA+#70e5(broDMP6PmO!Y? zdG8$AXD?`CanJQPHEix(8Ut@_vE{U|vIfqz)}gKt|O0{qb9R|RpwbE z=mZyG^O3n}7Gb^GCGHQx4OKRvAsa%oHc;ozt)!dP5U{&&xqs2|J48M;R>=^N1)oJU z++6j%jd+!bD5GG~ zqnnGOC>FMQ3=N`2Jy%)eN|&~QfR_pH(TinWf)eqE7i8aamgi7LG|dix3~4HxiJ%$a z%v9{A0E_B{@V+>4&fjiBx>?>4*}ieb%!?uC51FkuwxuzL=Hv#Cu?dKO5@T6{n_%Ah z-`6S4BwNx$H<5Sly_whQbynm4zjahxTur@$T;Z|gmGXLq>kNUzkZb5#Hx;^T{w7>? zldTAk0V^8H86o-`f(eT8*1{xUW4ia0C4f=7Rx$i53y2q zICZS^eo0TsX5zK{S@9KuUS%#Q*LzL!i|v&6?WIdVF6z?$z?;EJnS&Rw`I(ZXNHX(8 zBDI)>?P1?vnva^2MA1rO)f3I;MWR!lyHsX2YncO5Gi~8RR{;%w)&1|j-UT~ql0w%u zQMOXsk5V~xydvM0VG@=0yNB|)zg#r!PB{j{$&#?_&8>|p(}+)uN_|Gccq0IFq62z1 z`7W|kw=-Bqq@fR-&~o)Mc}1ymU>HRomoKK{Lxp<#0G1c8`+o7AFccQ&@^FK2oFKF> zrc6v74pT2cWH1bW#sZKZH&mZ29{k70Ky5;>%*wvsjccyNh{d|sbi`a#B(`Mr@CvVb zNz$SZqQ)YptmE>ct?7LA2>i>|{@!#ox3XkX5vNL_a#{W0{iH6cEGn+ZEi7{u=gUI$ zqcaF>{*aiXrWzTF$z`XOLmM-;FRmgBP}uzJTK%w2xU#l?>=9{eGUGO{y=)wsps7)F zAMNK|9`f}iTu)ohVKrB8S62R2^hN<5>t3sG!j}Tg0!@nxECVT3S|g?&nDwTkR}{F+ zTl2tPtA#EUh+O}Z95fS#vu%vSViK4u1) zsC>}Nn?L!5l&yF1pTWAWo{2J#<&G;8PPb8#gOTOioe=A3{(D+Y=t zT}>8uuIJ32^AySwgTJp-Q)MtuLf8fzTP-;4xpN61SK&R^3R%A|GOw`;t)FZvGte`6 z4CI}K2Vk6#SF^SnF#z&t%>CDJvxa$p@|Z>=;RlnW&^{GDF1$q^;-1te3s0MAa~iST#FglsIqFDsEYvHAe*6rp1u0pE zQ_ZvxJ8d=vJ?SW*RG8jryo9ulGaP<|K?~J%Xo6E26S3Q;1cQv{6NpBGAJpYH90sW; zv4{!p6uwnRtbil5lm-jdlbVN09_*uAFt{0irab_jTcE&KmW(SzK1_)?Y~%#@nnzg2 zNIE6}g@*@_rgExs&6Ere5ih?9meE{^0)ipcqbVkq`B?~vS_swe)U)AQ zwTg-1tg1rfJ%eDcBdF@;e_ja3ODzAll)2KlJ-{AGH3C&GiiB@kxCA}`BKtaX_gFyB zPj7I>CWr2o2CV{ye1x6`uLh;dVaMiwk!OB39U{(p;)CpF-qA^TN5BLX6s0!CqKc)v z--^|;d-S@TRyQwuQ#wE2XIGx<@>0&zDp!Gd<|vmw#WWuwyDcQq&in}eGr5g=%zS>{PZNS_5O8zVvzwu-gXNcev z*YlfdmdlwAB-*CZHR3|YU0UvgI#uvHs(;}JUAG93dzcYoLd1Z02o^|KtJAP6ZC^5V6O#!ZfC1z|b%>>D7Rkz7N?#m|gZ z1?tEGWj{qNf&7e^p0|9*^|u)D;v#msJy3U`*d6q8IUx6E!$`imc8)_XEc z$77X8IVGbnwd&i6d5ocuA{Sl|no4`14B{1JsH{*b;~Uw$@R!iVqmnn)M?#%^XIwZc zNUMv}in=Fus}8_O%R`PrDRH7NBJEbCy$k^(F@O)^gBf570vIC6wS399aSXX?e6n7?LmYTk*P$$|!dY+ol|aVEpQtCnZCl?E zgiJEDD7Db6cES?1{E78t;1O!HqR>;>`ofPd>9dDsv03CkQW@rd|8ah1+J59D0U5-~ z&oz-bB9s#r68dJNP;Q5@U0E-6k0{v4Qd zBAD!5QMGUR3q&$5Yegvq-hOa(;-K{tBU9prSQY5Ne#bf0b#x{}alPFWO5NYn(;Iso zIPosND18B4znG1G{`0_gowjNY0H6m?B#73|)PVqiC1q;X6 ziubpf5Qst)atZq68p>GZL>9QgUMj*-LK~n>&jY}7SW)<%4Uf_k^E)Tl4=BQ#Lr!&O zuUQ58vSmY=ykTs`7oo17-)~=grV(qn<5opGI3Z1gyHX~9QfykqUtwJ$3}RN#NSn!l z)WfWRN=$weJxHAw-d})9-LeC3WBqS;hgPhV+mwGyWSlE?>u(MZOi|?WiYTmz|8yrJ z;&it2L4xx?-@Jzxh6k~yuv(R~kng8^#LLpynW?1h_D6t85Ur{sk*?b(y+rBh#`~o%=;=Q0;A# z_sQI6s3s9b_hWI|Y1Ah5g@&V&*ePQh2ie@Cc!P(3H{V>)?*tCe?VY%z9)dep@tl9Y zk4E-9Hlg^ATUG&jXBy5iLW{|WO3L*v*G5*ylDjN3v#uAwH%JTc)SIDyKlKe zF{Rax<`Jh(gT(2xB9sav@W=$B*UkIw1!m0(>Y!p?EcP3btxJ=v>b)<+sA`}b#vUKI z@AaC0{{DyFm)nZ_DzB!FpyS@Wy3PkZ%cM-VG&NvuADEAQsQCwe+9e_*=y36o+QkSE z`!)3iPZdtK6B>ux0IK%g_FevSlj^Awra#jvh>b4($zMGsU0oMB)<}5-IUwzc4hCxg zWDj)-*Hw}t1k(O>+TaNPLH)G-9PC#GS8p?a(FK$!eZ3z*cw0rF)jFnCd|0~n>2p(E zL`bGdq-+*i_)&LrRmI-oPLy#pu5G^k<&h*jf;x(K;x%=uT>3rRSy>$Ta#;bXKix*| zG{J2E=P!69COG(7m@FU|*~XzA=M8-y&fC&QaHz}?N9DaY{4CSkRBL>Kqm+m6_qfD= zy<9dcyTo#+Q_EDVDJfL8+0Q3l)aVfa!U;Hvx6{w@0h2Yl$^HnDmi<1Q%wnu&&Pc!O z7B-RFdBYz>8>0|a?2Ph1@FGkT9&puklJT<2Fl3TZZuQ!znV!w%m8N4ALHx${$g3H; z4VBd==_P#gy0>y1RwXh$OUyk%q?OTs4#G?JJY0{u0Mn*Fj-XEP(@w9*Ef>mBFohGX z#gV6lf%Z$zhH1!*RdEf?Y*Jhq0Gt=VU)$BQq#`DcPw@qN0#g5FTYo#&QrN#s9JJG! z{WXI_BT1Fp$H!y9l4tWPe9nvym?PYt>6MZw2`EX`smi_ud3f+aGQ|ULQxigezVXlO zV|7RUh^TNM2JOP5DZn1tk#9CJ;AX$da<3G21*N&6*nQRBwdP$AI1%(JTcx?z9gr@j z{k|Q&`rA)o7CE$k(r>c!7w2~{(_M$`(jULKfZAj$*c_AlrB1uSd2fiHHc)FL7H1Cp zs#jJ~@CbWzf^482>)DEb+-!IABUA;>9A6VyH9pIw9d~a_^uisHj{0NbB;T z{gC%Lsu`$Zra*>7K?|7z98r9vvNMB`H!1FWm58A`xY4In$(YHEvdKP*PJ7e}-BRhV zL&eQ?$<4Z+I-`IdaCeg^uXJK?LaAj-w$cf@kuSUJP7Eq|&IdlAo^< zl|EO@#ztt_)IxEuNL!hezICO2Ddym;7Y{9WLti6Khf&`8ahUGUnu?D~b?kc_lY=`n z%~(|amHWCJ;^;JV*QNA-lY$pK{5-h92Lwo5-E0CAbGPa#&RIJ}&~?Iy9Ts{vLa-8p zn`8+{=A{7en&WI2uyN~*QezEVkJjsBRYM}||hUdP$gB=}9?v@3ZXQu2X31qMp`5rOTLuM>>TEeJZ&GqmoRTz$497y zkm#Re7)dnGhJ{Byd-E<%Z4o9_Y0s0u;aRxMRaKSXoy*3%O`jCLhgruP0q^CJqcO?8mz4G7wNM;`D8Zs&0dKL zJR&4-?}sE01vT@Z^EKwn1u>l{SzKAUb2xQ#ICm;H(_b9DyuWcJ5O19D(?SS|fGN*e z-JxFVqB#?Pw&Z_`(4+gL=bEsd503Ba>fzb!x2;_ICfEriLbQR}U$a$oPkazLq=BSHUFdp>kH ziGffYd^(8weKYFDw9C`mfI4<36(*^3#?aS5jN40BQ3M{m${JMURLbyZQ&y>1yS%S_ zT$x*c(l1GMS~oi-T`BbP-m_*X-_6tiXWBB5tp*I4z1eLORq%UJXW=f$j{)lo-z{xN z%V;mj2n{W4LRV*1XV{EG$@*@Ho7fB3!3&sEK}W6(1g<2XRzC4B$8T&hOEY)6VNGvT z#L9i`1UC?_KSn2s6J@}=hf*Xcs(M-1qLLPW)3DlhUA>yb0uvn9XY+i$8B3&iRM z%HkIATv#bvXPxS!5f}ZFVFuKdK*QvdetES+bazLo;(_ng6r_7Lx}NgzJcNEgBZZjm z=gTBmo8^yDEoS2h*@YL&U#+)b)mXBB>b4GO(p>wsGUSJuzivpvbC#EP6jHp)l$v=W z)flvY7llbSm{g41A$yuE`eEXFGQl;drLg_VXoow0BTTmt zqym9oDBK(3biZ~`EF3hbj#w;nCrE>T;HawHjz6T`?m5qsVs46BLl|ep>kgvO4lGsC zCQ_X`Nc_@WpeRUi!yu|8(N`Js~~&Jf{1%o|2(AoCl))i|b~?HirC^CBL4w8)FJ zu)2P2G#=8JZZp;G<=AK$4;hlY{*#R+w;y)ra)im+tr3=7bYM}z>U+l|5>y_TcUGZ_ z+ep=;o)RrLl*g(i3Q#|wK#uV;H3WeSqPq8xjE6BFPK5o|8H2s za8jY1CC}cWKZQ>SSJc+vr54F>^K0RB@Az%{} z|Ex+wwcV0JJrt;h(No^2?d2VfCR60-D0T!Jxo#FgtG-hA|G>rrKl$}*2-yIwYO>?I zCF!9#u!vYFSK)Pkc{)zip>nH-S9}TTA89cpYST}Q-70l|d_4pusVx+L9?S?*N-)OV zt5Qji(EOO2l^fj`t~Sdx+WmxQ_9%h#cdCE54PT=&jr1gzJx*5tk^A5ue$fU3h|&X3 zlOs>+&`UTpG7UYKLaKnbu)x!yMT-9npPp$o9xK9$JA2q%0a2b~1g2?KNnsYG_K=E8 z+*Q|2V}vw+vLwv(AyLLTAOAV?3O|T40o|8^&>!SglD(QX=Ek8ekn*J{Ld2Bx~m7iVx&D^WrbfijQrwescucU~bMRJE_0V_z_;cKqpeFMB)*kpJzY z54x0?Uf@Av{C#h!u<&72$I`FQhZd@^A5a!Z74Q6i>j1+@FRN@Jh%>se9T0)KyM<83 z@Ltq<3wN0OGubCGtZld2=_~~)cq!XOKbvF?5;HA(KzvrCh@^<>BjbI-??=lNZ+6YR z3^m~(zOpN2x3_m0;_T`;#I0Gk0@7UrtYZoSIKWRh{`m&W1M(ZubDU z=x07ZelPC>e@eocmeFA34D#dgg{@pcc?ko5W*YV!%145a@R`7(f(xq}FDr?6_Z@5uVUPJ3cK^tUiHczGe;*;ORE2jO)gTB-fJ9jAU;F@zzo)P~Q?2(9ME~00}5T1sdoAqLU zs$~2jcWG`HLNA3Yoah_6#-8UEY>GmUg&tGil^LX4kq&NcMP8^Olb2n2g&zmMgu4g) zao2fVG`=+{=(9|Nn5 zZEuVC$WJg6J~!h*aSFz93zsN72hP|~w~v2{-53l4+LV83zcA6MlP^WK;moW0ecfoy zeGp$5n}G6DK#0Xe4D|#!!U!BW0!@`F>(5?|6bK&cUiM~t=DXPY<96ylhsq3p@)CeJ z*6|j^1duCJ+v_ zpF{=6w-+ooj=)|VJL`MtN`R?gn^`19{I8Iw1kB8ie2H)6119dLKK@MU&}AgZu}jk; zITF6vgf>eOzgMsz2SED35JQ=N<|6hhCkn*b9-uN%&>Ah3p|Cba%~PeN@<7^DKekw{ zDBw&H?xU+$x)GL8aX{y_v(+}XrK^@@pL3x#80aD~R_I|47&s~UsKh&c1lzv-ZMFQg zTEISEmf&Q|p@|h#kRL<}Eykex9X z0y{q=E|kltaas{jPHX|dW6K)sb4#Oo6Gkj93pw3!c`N`a>TxqpB2xZ$GwN;^212B` zN&tBdG-*gNba0$$oJ-p zw2CGm-a`;P=^&`YLGas)7or05fsvVy##18!;S+!ogbYf5;u7W!F^Nz zEdRuinfdci$VJ4uVgK==piG=X-9u(+EHZbg4}^kzUFP{HS_cnw5=@bjwU8B&66EPk zF~-~<1W{FMzM;K|uR(2}6R;yi>ye&OqBYKRf(d;`vn4b5eW!k%Hq;`?+W#UQxu&3JlIu@@I${Ez_#`05q!b`sq608zq(ob+?Y}-@LK1|YdSYvB5umG!I_T1z z&Oo^P7)@z<|8rEMPK=EGcU#^k6e@$BX+f{4%yQNg23Tal* zDNW{#M^FI5UlE4tsnF3gGu&cHfR25okip18lu3gJtss(1sV@wn9 z8HtWbD{3wyfBE1sm{O3+BUBK@L=bTahnC(b{eimo|dt0>f!<3c7 zhq^W5#A=6rFjoFan{I!+!wE_EK`xRj`H4Q$D{>im><2ekk9M99#(Z1~TJUNbN(tgX zs+ggo*LwfXC+0CF?Ib}~46A|z861ysDBJA&mWhoyf3Sb;$g3bvk`z_0EEtR-7o_x* z$?}c*c2>kQ@5Ep^%HNWxpwG?>Q*jyy#OTCG(OR(-HWeIVmvsmgsY2oaM+xZqYd18* zTUU#)Wbws}R&tK{nqk8z{Z4J4EB$j%dk)VFi|9G9XZqV0hS2_q>I_DdB9KHap%H2} zd|@>2f69-Y_QxKleV|tpPFZojXRJW>n7vWv$|xC*p@&hwt-dbH;4}%Gr5pd^WK%1D zcn2my6(Xk+Le5aafZw|f*MS{w1d2U*#FJ;H-nGb>k(%0(vjc2E$4oDbo1z;mXY&=u%hespSp}+(gHq5GEGO zc;sesoPqtZ{uk!tqgf&(mIcAg-SHy1L=Jj)qFDn<14%BlF?B5`<5EOWv3q)JNFc5XL}j&sIk!OF(+Nbf;Zq z^7Ai*RGx=$gz=V6k6i84ZsLz`BvqD<%fI~RxJI-dix3;;( zf5ZHPBWYL`m9RU43@-uUgK=>o3MUNa5mqg?8z|-l3V;rKT4wJPhkoK}1o0nse?k@{ zy~$-pB~09v65_(piEAJ0(hUB;E42@ZkUC->?Cphi>|R= zcgECqb6QBP#9CmLusf5z`V)~RRVC=`gQxapnI>NW zrA{IybFwPy6cgkWrquG*$tf9^J)Q57p^C3^9q zQuhC>*Y*s|q^G$n^!5|FKum}s*#vw%YTVe3Wf74wpe02YAbWeStY7fBPT3L8$1j~_ z!P#%6Wx^u&L93$j-J-aa2ak_hwG9|W(HvR271*`+rsG6UyUVWN4fMI$atUXGxC+jY zF#hpQ%#s2jPJ0YHf0{kWd4fH7)VHwCJ*|-N!ywu!o3A9+0@*94t&!~tPyWeHHU=`A zYq`UF;G2UVuZfjqAuUuWg{&p2`%-0bipO9@9BsDs8aM6{8hlp|G9!T;&NIj8)Nnn| z!@u;zrQ;g)wYwLZFSg8le?Th$OaWvx7}TDWVccR#(tB=SfA9wuF-sN7%o#S%@~l$Z31Bik5<)v@3|I(^dikgscJ7$wVegXl4|E4A zLhITnTB9_#fBOmcE99+Xrl^1!MLUXo{}p4ZwTiawb%-j5%!O`8BDnYz6kujnk4)sp z*K^w*UTx3r8b@ex@b6Bql&{hbX7U>H&;C~uu@9xR*g<5i0}!VI=a0s*ua53zjZ_Dd zZVyJp`M9!*5{Ro3qhIefT0cIz$t8|PJZPlVii)QTf8|1T<_Y{K{W{lQVF}6nr!YE3 zmv}V3CjVCUYjLe5r?xyft! zstFpd%!+>;;y2DA)8x`B{uuo#p7KmQ7LRdHY%YISbK>Fld~#&I(q}hLZg|f7WfjSb zM_^Xxe?XiLWc*6oTC3+TSOx_UUt1CRAy6hdAu;087!~fl&31t~v%hhXhZPnE0uHBh z)Oz!i5#L~QzN@Vanw<8v9e-ZJExEI*sCa`PDf|!YLuKr{mza0iFJawapL80u5z4+y z9K{qIAC!nn%D6g$`hmXkocRlEyfvvdf-Dm|f0)KPOwh=dG}ak&IS#03Bj8$GqqtkJ zx^0^;zA<*`mHw&KPaGC+&PV-9s3H{=5&X09WML?Ve#Ze7M0UfdQvxsP!Bk~_2x^sQ z^#<_|`d(iXZ2(YY+3Z0i6a;BuWz8$|9HPRN;j1$8>WFp5n6Xk%G9)>^=F8cpdY0uG ze@?oyZ(E`-9Sq~lnqAWTO_|0~%+K#lik#>~Cnc$oxq?!g`)zg55QK%V+Wj7(^4oMW zA42%T0BtYC0<4ZpS_af{Na03tZcyYM$3OkLSV*PBhlv7B5$+}8dWM@Wvu z!Q8CH$(r;f)0^@XICU^9H4>|OIb57#e=`)e24H7ICd&CWdl2T}u6>Q9X{6GuhaI9Y zF-Md;*+gA}rHL+@*!RWk>B{SK>BpxhvNCdyN||VbE$9_)o#Lg|x$!J>(pQSpdiIPy zfm>JgE2=50ls?Yfp!pGwjsFh2;xAWoEUY)P0Zx<*DDLPGk~RSrC}cIfIz@^de=9i7 zJSJolr78lr1wI`^Ja7rfE-TBU?0s{;-1|g{XhTM0rploNne%tXtv0xEUO%s#BxeJv zfg+yHwGEqU_b@Ifp@Z+k5CuV@p2-}hs!Ir8i%w4;=WG;qFP>%{x;RsD0&PA-{gIJX z_-%ulI*FO73WXsFQ0lHM6oci%fBW3|P(Qf~H#pCP@>N-zS&_vLGFdJ>n+5`aXy$ng zox1dTC9#h6l^ds;lfY7{9h}OGEc{dPcXbRX`>t;`*s*2PwA3&i_t?FDoK9puB^(|r zb8Mgn0acZzqkI`Pja!5s8ty0k@aO48dt*bU1mIIHFN(xA5Tw9WVGJ0+e^F4h`rSue z8vawPI#n5F0hRX&y{HKdD~khi9~j1Uw&eH-Mqc3klf#3l1s(iS#q+na7$m2{eIK=m z;$OC}QLh;<@Z7j_^DStl1l3RrX@-I$PHNHOO@i8lwITH`p><%j^D6#G9bxW;131DA zYhO7D9TgZ_rQjk)1`1cqe;|gPd9Q>>MH)x2e6N^dLc9?rObNo<(9{u4sz!&OUvR6y zVI$*qUmq~qCw;)lCO*VejU4QiqQg~ou3s{)Jv(~O#t?M%-Z}%oeP&^h<*BtXYDQD| z-!lQZ*8D8#1r`PQVZRCWwl%`^(@{Vx&AX$VM~{*`y4$NH3tKk@(45!)?;V&BGfc_ zr#1`GV8jGaxTorgXF-{OzW6O?!x?WM2IDz(KEcSSr5G9Vl#s!COTlCgO>+=kGVKw8RpQe z-iXkg*_gJ1e^1^{D6FkE8@<|d>I8LEbXnZ+Rec)$)0=^IB$ zc?Fil+&@Iyzqp$uBUXxm`^;huurp@E^KJcczWLt~86t;$Di#A3b71rPY_+)#0f#^f zEiWNwwNi-_40Wg6%kt$@Im0|L^hB*yQPNY@GPv&$*T==8F7+c?Ty!Tt&1c@|;1=8l zD)&k?f2zk|xjFAcYL*R)Ha2-BBY=eGZ)3NQ1LoR@bKWPYFq{KjJ)B>WD3nL0)ioM% zxJY*Ss{Z_9q7oP_D?fPN0F}HJ3%mrY__a_KoUopj1_ftwB5QE6XaatQgV`H!+%9ei zCO7b|iI}W<0&Hi8dtAfAl2>q7kylE0KWuldf8pSoo{dC#mRaXG(!K%>Qa!6;=YCL2&k7=-js?Bx(xZMQj|jJ$HAazphhV(q zto_a$re&%i`f%I zJsR?R%(U&V-qt%_!aB~;8#$@(K;bO~f2)00sRtA`u=&b0Mt&ANTt%HF&`|mMB_Rx z%p6|6G}PO5igbD&-;L7SSh2v6oYl9^1o;Z60b#Zi-%GSa?& zjF2k*4Q;AB$sq9p;86@*Vzo70e{9yZb1ZqHbzc`v2f_g4GHWdTTZe?f2lh@Zl1s@aVOUVlxCZd2hgJr3}&fS z1m9@_but6Hs;zX1E@}XXjXe5h;F>v~^>8;_D=8s;FQs?ZpiM99A(7$gf5bX8F_-I@ zN+G$m)?0X(9WGR@e6r~Dkv9bc&3=PyH{LQ@t?TBp6ak92f^1>D7uYp$qsMBxBr)ey zfcznlY0|B1i_GrV8OHOwT5pdIV)nGs1yNe&inFM=f;vcljk&iG=OVx_XwL_cJON`P zo5!jS-3<^Bg$s`V9sia#e_ElM953y-2CofJhbvrOq(w)gwR$94ADgq3(WvM?hW^c8Aj4}y?}Px^ z>m{;aQ2h~7&aRW-?R{^nFnyiwSPcHmyNqfsvhB#me#)7~M5=W0e|4Q(=(c-xbU~WF$g*>!b z1~kmAbpMWEy&0&el4gL1;#UD;e0A6dGb*hfB3;>58s3+KeB4l7|n}2+1 zR6?5|1(HZ#jpE!$EIY!6#gOE{rHoU%o>9?1vwI~s(maI>R}_;luZE)Ur-y2)c|K@ZRhH~F4%k6Uxdx3Uz!%|0Oe<9_X{iY zEc`bE%Oa=in5LsXA&c||3A}vRjB6~JV_TlIhL|nv4{5-c3)^C*%ubF>z{fjrDI5B% zEdN*4>a6Ony;045V38D6s3{V08~cz+3;qP}e`&H|?-m5E69KFB?a7%L8Qrd#N~=J5 z?2`#5NuD$QflerRy^<~(A&7fiA>#3`8UcNS%^%S;I?&bOd!J$oPhPW4c`*CoCr;){ z`m!IIPnXMk3lE)P_8LpKHX^F#XWAJq6fd-_wpshvWHVjWk4Rm6Ff!5y4RKp6CiM) z|0&N{5Udhv?R5Y9SJ|pdiD@#aHx3p@ErI5c)tPbq@zenz1PK#4BL~BomiCsC4}&#U z;HjmbPSUdHg+w27Sd(=jW_-EccBH%E6ruF+9y8E&y@kJA1XySs$`@keG&gZ_f2%)N zHi`4^=PQ6AvnnPDDFL8v#|Gj(ME0t~>@y;^NJZVEZapYI+RG<|uhyN6qjMlV_=SU7 z0o);Fa{MHHxl2_Fdv4}=|k^|+OLlsV?;!}Ki0CGgW8R!1NQW+1{RoE zLSDnRu9_>aK0>5PUEiL#uzh#YFcb%*SK_M`lUhrj7HzJ~5rJT=w@PSw#Ai<-7@bCuqhe6b4CTcRHOe#Mi6KNuuHhouH^4&~MIym~XDcy9f zUV9kp_5-FS%tYg8(WCo63?DG)b-3_+-lRE((Nd|RLl_$gJER5vtqCJQ64f22rLa(N zo+8SNg@!d-#6a*s3w_3T39-EUHrmkUv}Z-D%R=qG((0m)QsDbCe-Yvc5MgKS{~lY- z*lZFlQ`@CMnItUr3|)aP>(9m2%Pp)QTa|1=+*e2^)6=uFA-;Y#0+|A z6e>qgsuPuLi+EdPfAbYfo{Uz~c)~wJV#hQ=4j%Z_$QW=%;#1kk!$pl9C-_+<$e}jx z#Js`swjN0*l*u3lxr?Kw&=5r->FTVJk< z%gQ$F*%3i>OFwNu^UEMI{o2&rLb!sss2&>jy2FUfJ2ZyTe}W~_0bYMOA5!&W%D4Rr zpm@fiZLQY66o7xby|SLg{^2_Kg^I@x2F*|J!t&)B4N<&e7e4Sq=oxQ7 z`3UGAj9Y7zkmL(Rj!lf!nk>fxR5rp-SL1}pbuYL8kp4*dhPtNP=4wAg+KA57YoKU@Q zhMxc!r>A%WAb@-5MH0K>8fqI=)QC9}Ksm|%$<_Mye{J}p&v>McYuJnLWy%qKOA+>< z(%ep)r>=u)28t~GO=b?@P@GltIaA-kAo3S ze_8dbK5XMFD`W^%ko2!%vgImM4N0!kW7IILU=ox8msPjBU$mIM9yy#haq808syHsz zF@8ZTe`@gp(!aG03)?3NX0=mAaCO}nRF@Lo^EC;xG+6Cot9Bw+>?{k)1#PxZZXxHu zGws9G!6S<@(=Yx-D-VMOty_Q-<5q^0T?qW|?Bvw|0nSMxw#gg32RU9%$fP4(@ zmJCtyrGTS=omUX#`VIqLQ4?cSP&%czYkYABI=yTO;9p05AND3t9(`T<#bGTpi~!ZN zf9uVNH`t{ni0DTJJMy)hq#6F$f!(8 zfyxhdcytv&+yPO*B;mwN~~8)LI^a0h(pCG z+qQ*P?c-Ne+Rqtpe|?ZnKHRUtf7WR=?0`}?T&cTnwup!f(nR7&nREjaWg6iJyA~L# z_Z^x*aKa~V4)4?lGOjfiko+i(36^)(Vsi@5W0n>mJCubka^A-%{s)2u;e2!xi7(l} zL9KKJsW=nI{M5!XnTQPcJ;al;$Y%quU%3VuiBJX2q?M6UKxQ65?vUBdW(;y581*SxePbxJxb-$=6>csZ zNno*b0MIqMp+i}{i#fnTrdAxx@8pX-9dLYbJRX%5{&;>~)Kxo54X&lxRtksf-T@h6uH3{`7CEM?-Q z*-;y0Do6IR{V|l%!kD*P_}$L&ae>GVN5etc&Hq$SrOV9d6WXSp61XfX0~idfwm{>? z2O0)p)EV*e0x?-=J3DH7 zAcg9?qeEl@4|hq3nL8o^f^Svj`rucZ(Olqh>>Ut7;uN+3g=nBrE4sI<4v>@gU@LQO zU;Q^xmCGD)atWrtc7zaU!jO}?x)&mx7K5)FPQRyCT|sIQK`%%l<&LDNtZ z@(N{VZeQaIe{gFJGu$CY#pNN9=p(TU=M5nirc#QM#Zxw-S$$`HL_fj0N^z>cbe^`-t(^khdf-Crf42;z%fA&0<%SZ=r=ktMOg413HNtnyshEfb<{O!fZcE6#j@}@!#PE*$-dgB3 z2+lGKYLsRFZ1ra0LCH)cKWh$-CO*m9c0X z$(V(m&+L-`^G{;_!L)?3_6{f!d~+sXN6Qx^n*5{|z^^I>l~3)(h^KS7u_rwoGH6h2 zf00~ExdV)!6l*!)J6JtC(~tpjeCug*J?5;yvHz!@plM;14*LFD+I`8yNwyu5p!F+Q zmKrlierxPo6snCferTGB=U0}jp``wnzk?tNc}yEox=Wcw%VGSaf37z-xMKCe1O{Bw zxIFzVemQ&KH8)euICj=vDXl}gz{jzOe`LSH@O=##mqsoC!NEsLgB4n@i)8Dh-powe0!YYENgnC5dBK7nq&p`9_cgX=>T_vJ>N(NI_yTf5EUd zH)8RsDPpL5m#8v;BzH5TELd|hp$(_snJbn78smr_GwYXg*J9^d~k+*>^<|wQ;c;3L6 zL5dHq-PqQg2VqFf7^dAot(9| zF~<4HtM-{^ArOq}yfzJSE!<8#+a>Fn`jsiG-{-EiQ(FiWBMk^Bir=ZfK@Wv*p3eif zzAq1TaJjRaXLH}leyhZOe3cqrj?)Im%VRCbe=}Z97Fe*f7y)+r6{pamQ&BRdQgg(nC;C&llAo`1D;(KG~V zYt@KV(A-9^e2i>uGPA2jXUq2lQo)&YJ>^e15BN?1+^!Do}~?c*8k3dy}hP(9Ad~yijmTf5h>EO91BpGX8$4 z)c+3HCmiox_2~6wQn7yR+$HQ~>%?>9t9D1LH^-j9rHD_+Kxd-uL3KjO$-uUeJ!0sT z>wen&u8o4a$HNz-%AC#PoaWt%yL=erG|%SZhu~tLm1*`NbzIX9!%> zhPu-pv2s@gT6;Dtf2S#Vby5fli+l?Iem_X1L>#Z0#l*V3yFs$$H81Bu*8;C4j~TNm z7OiaG()h^-`(5V#PYATpE&x-+@U+Lw4sRzK#W#<4$Ey80&>G_lYF^3jJ9V&e{+XZ- zev5f6D})y(!JG1WyI(<>iPtxqNDdtYD5Sx?(+1HPhMtt=e`OSJ#<}d4H-NDE5szsD zO%Akj!}RD-T^Noz%MdptIA8=Sr@xNG`Gr4KA887c$K{mFpqlx09a~~85#j4)D61K) zb74)!)&Xi*=Ia#Oj&i}8Qxl9VDtT70dgK6C(?*J6DPSnI!))w>Zsr0Srp9$&D*+96 z9>(g^IHPV7f5h9u^D*@s%rrC|r{7xXx2Ymdp5|Q99^1avCpl-giWbbY?qAbms>h;R z==6x=OP)z3p)FOAYIT-IZpEzl2O(R^zNu8|RU7w{UyZ23(__9B6aNx8loZ(9c#rQ+ zVi^vm5qNl~z$0cbDL@}mV`d4Cn#$aia^xcMsW%T8_q&2Kh>+h(0x@vx6}RRx5owf6;{?71_mA?wyziJms>`P$MI zHOd-<;X+`+zw!dM;Z3f{pg(kga%(c;7>W2S(zW?vBf{n#6mIXCU}z1GpY8B~Rw)5k ztmtZXe`Xvo8;qWaIt*b%E}gC_(?yi4h>Wh-5FCk9ec(e7Ybe$gtHn)ca{WSzv-Mb0 zem&U-1@tHwqpG~SvI_-iGcSU>Zsjsn!Ewqli2fgSpyU~^CVJAy(0uR0^a1pm3-{e= z>-2u(wI{U$g|BTlq=XKcT0l@hMO6MHxdjK{e{7iWOxg*4l3X!fJm42{QQl1_pMoEu zdzq|Jx@uE{)|GlustYCL18HXNiTRCuSID(R#${v{vpJ6Ecd%WAgUcu#*W-p;Ok6uK z6tDd*GKz<%3+1hi9UvFi3r>$3K#YH9pgsAc^V;@^$gpE?6qjKWKa@S*Z!=yNie5Y8 zfAbPC8a*&+c|gTs53zQyZ%%g`D9VF(6bI#W`+XCfAwX5-i;4p4W}NQjXH0m@D1@25kzF#) zqZxs-^v#?>37oBXkd)bPFXyqjPG)y_vt&Z` zx0Mq3o!=+o54JT4W9IJU#VSc1yC!AmzT>@5_}$5?YVK$307SS*F)hk8`$D{GX}a`< zDW6D&+1~*%=I;AZ%#6yuuo|V_O1E>Z-$<>9soi4Kh%7Bb@Ae~L&hvjNTI zJrx-1`G)TF)L4LIphT9?-h_2fVdpxHCEKSlWsM$NDh^N0R^3uKwrVYUx3H~!!*-9| z5a(*`=y#}^O)SbKE&n0A;1Dx|SM>>(7~H!vvM&E}2R{rIDAxu_uOAGK_+*(oReSPL z<17JFkzT2`C1*f=8wS4tU;`}=pzw}9SASbhs5=}4) z#c5HKu~vJE%6NS!X`U82lZQe;wU_s6ax*_0M+fbMlxag$y^`%>HsLYSB!_aTv*$Ee z@W#Y7I`Ck2xwx9KW^5EHR2KT4VS^S90c>~ld;*s_DWQuXr@ROHf7mXhSN>fx2RlUK zg&<(6Z^cKoXQPc53S@$CYLw-6#>zEywDX5ubt?#rUCo6yZ2wdfSt-1{B0jasB*bl% zVy1beAnbOQzfpY8me`S_`yjG+Pf7>e%-;Dz#KliPC9g?e`Kywa#Z){to;QqH1%`)& zkFiG)&sGC+Lve+Le~ZM?1=*ypr%q^R(~%667O#vD;S z)~B~#U1A(C#H6vWD4c&4iCahb;mCWL^Nx)dlDtm<&I?T{dZt#Zc-)O4u14rno0YoJ z$1`OZx1ti!Q3~%Ic6#*nQC~pFZAqMXr20wo~Kk;YWbS!lo6}Y6KsTs5fp?>vz zJ@@%B=$@c7sYG!h)3vdFE7oM^Zz5S*R(dp0E(;ahF{bvz< zqY#yoArm{d&l&>En3tSkad6hE_`)YoU!;67$PY+Hk?XyA5^9D!w0MaH~=Yr^*>T&T@3 zxOJ?ZBLJ_pxFD_9Xt`Y%LJp1@LF4`{zsf?Brd5dW$W&utvdZpsxsg(vN_l&@_r1OT z+ovD|f1lhaXIMI58|-mR!gsjGi(|miQK|LLg*MQJey7>6$q=oK<2bJR;VrZp6x&a*55eX&*cXm1Da^pnc;$eOwi13aC+PoI46#))GscXfsR;9bwA-#&2Tu}t_Hwlwh~uR62>cE&;NOyvIyaw^;2$S}3KYFnM9YaVYV>AJf890- z%kbiP`eRbBDR2unh@<;t1Js5%$he7`Dc;gVa4?~1^dAbYLLHLiqJ7poae-&Jwk4W0 z^n$Jh$=TaEywe6mqCu7}fpUARMWU)PgH=#$SB&VJ#QFCK_ z?HG?8Vci#u9YZ`^e$Dc1|FjabO1sugyFg$hBHd3TVY zD)L^idj3%sC%)DCsX_f(cjoTJVoYIiSPl_^%LxRxp;L=5*xL6e)$*F)f3Ri|gIdP1 zDodmp;yUDhjZ-=4J|H5WHtd)z)M& z)+awmENSv$n?h`w@rc9;&BCFM=M&&4BfnA=^c|7o43NR$E!Fe}vvVpI?D4juYKjR` z=~oj<;cP->8>6zP_~3R=f8z`(Q_f|~CZyG?e^HOlGO^9bY%#ViMZIEv+|~?m%l6*haE*ZV^Y5Tb{^r<`fVs*H-{C{^f&#N=*IA( zGgiqnhGlIIR>S%rPr4E0WPlT)0%NHZ(g*-+tT8i`BxGQO)#*U^`vey_2>uRRC53gp zn6c{2f9y%eHhFzle+BFJ)w?s=xd;tD@ja0kNq!EXBo`i113R4BL-1tNh42&t%9k%j zIsf*gp4~+!2xe0t;6O^uAnWBSJE)*}T)UnSo(q7~4IY-o8(AX^ZRVi1eDX8ajJI(o z71(w5oC&s_<@g%YEt(@`&q0_?>g-SqDy=`7WFw3a8bLM4e`L|ddFC8@{W_NQ4cSi#74^swB3=5G7tTAWR6wXvL0{0wTjkeivfD(90BnDX>6PVb@=(^_*g z2_lPpgAbqAry9zZw&4GX>W7^upalLNn*aYN2w-FDaOXh_6#yydjaFy~kl+rzrJ2@Z zh+npOFp1Bee;!}5Y&`y3t!wWTMaNgF$4K>F0P3caTn`mu^0SBfH7Usrz7n1R6g@ZW zmN@1I0eKU@`CFGt(^YJ`!fVEvUBbyH%&+ZoF8f=HPI_S%k2q5Pa?)fC_MNuA z27;(n0qX#%zY%FGU2dckW1ku_kptn|dP$Kl9RH-)9uXHeG7p8=Ex*9DTN=+zrvZkCR8Bj;ozakRk++W%8`XmI z?#f73d*lh&glaR9Y2GRL!HXPL1n>~tha z8lOiJ1=<83Bjra@kT!m_$~>#O0Q)(^^ zf3!s%*|q&lWE(|x9XRqvSWUqR%J711m;UVqf)q5Yw}d_4Lo|7uvpkZ|0PK2uLZ_M| ze6G`dltZgQT4;ySxow+sQKFy%{Dx=TfT}6BxWr{~qMF>cEB$<^KoIM9^nUJ4F77@k zc0S&~?hDh#&<6dQbe|#!ijePTO0cDnf3B4$1)cG8^O^o^zA7NGe-}6;4AIu_;2=J; zTZ(cy%;TK&$Sivhi5C24nP8IM$ST|il8eM9#7Ou{5e`o$Cbv>;sF4(PQQ|!^?ioqe z54gZPCuhX8=(*Q8xg_uihGD008{(~1aF+4R0??*Q*@f3a8E zJ$hB4!C1(XDr;S~YiRcjG0`DOB1*SZupATZ=mRX8(i|`nV-_hs_xqm>)X|N*>R8MF z%GopzXp8zo{wBB1scTc_w#KafTxo9o9v^!{votrK&~#M#19hy)H0DH^Tj9opP?4wc zk5cTzG1`M!9_xCIWrOqKN#-h8f9+AqUH}W`Md@@HId6G(b&3v_TuQVXNtfvJS4lm< zTc<1JUnq9H80z{e2B+J+c}Y+iOPBQ5$u~jJuNumJ^)#ZWy0ap=8cZCE95oF3yKsEp zUlp56Al|-CtV}IsHz2vNMMDzeYXm!*Z_ZwgR(o?vA~SPKquAw0=DuVEv@$K(D4kWsWrCNi zoe112eK3q^V0wi5C8F%vr#;9tN45ut&29>HG`o6}#^3ae=Jf5rQK%NlP$oOP=S%1EmsFaF9OPZac#wGa5?*;5Q`c>nTV z4SAb%u44===SOe(d>74C4d`&Fp=vo%BDD1`*vhzX5kOV3-IDks`jAK25v9VR8WvEm zomy=}ok?9bGD-4^15u(BcM!+|#6tiL@Q6{AxM&FIbWayQq=bFve_e$AO(;I7_NA?8 z=M3hW2yL-+Q9+teDY8zOc|Xg42cxSmkR$h z2;0>*>q0I7jU{pLNkWn2JQW_ph~B47JgI#oVFWcaI^I7UJFygP)ynHI$~tA-*jMn~ z4CE#zjZfa1DG~~r$0x^%zRuTYWd8Y8nj{vaTz`r-uh}z=e;?e8(Z^;V$X>syBg5ib zok#pa*t@qLAfcOYW?MJ%Feo~(00aa>n5PW_B)-}QWKE*$lV-P6&R3mRLk^*BZ=q5Q z%~rgb|7pR5#61fsyo8Nuei6~0Hj$ktEE1vO7u@CM8+U|W{4R(jkT0L2JccrjPSPDz zREJ#*j}a|1e**!x8O#4FNmCF%!Q$_frz5_%_|WseSv8zIS{doQ+=5*SEfi;#Hzy%u zb#kn$BO}k>I;hM>>behIHb2yJcgJb_17ZUgaop%-lq71x0&ZtnB?L4AZ7?icg%$aQ ze_qg)iDteZ5L5HccOo7?*Gn6|D4mq}> z^uN1^=eDofd~*}PJV66NFAPBYfg?!Jj>@~0RJMwnx!uqUMZU4Qd=GpqswR#F>#NaI zwqZPQjc6lBa+|C7EPi*#JRbXxTbisv@s1)GbkHrjaTnF8g3`8=J9nwrmSTOwfZ12^ ze>W9dWAV|j^k-2mp;*W1CJ(^~Fr+i!2YZ#?d}E2`t3U>Y!FQsf__{kjnhdS(qb{7z zQElJa1NriHoWh=oHK947Nw`D--J^dq4Npf07CDNUw&kO38#7Wsbu%r?Pa}`xsfNf- zhpK?_uB-CRkJO$U;mLq38VVcJ*{nF5e;-v)0nE~-J4k;v;`KQl$O8uw=Af*1l*5&< z*XLftdx~Kt4LM==pz2#@q4#pwJOw!RIm1U85jB;xZ?*yZ^J7bhJBvf<1IAY|E;m&kkB=Bate?&zu zgP*}5Q*m@L557AyH1T@Cp7dGXsvN(eJX=N;!+ptn%|}oLmmeHBul|Ic?)4>Tcv33p zXu^A+b51k)3Mq!P`X;eP5Z6u_10hiqmV^y4cM4axk7?3e*!Hq5RK6pf24xhHltV< zW8Jp39Rh3Y8pK5q9?i;(Mblw%WT*pltuc}ayI&D^MlEQ*4>GrX4la{O3AhJ3CRi2B z5Mu%A#bZlfJ9JqqTZVSY@F2bttidTnIXcl|a$=7?rxx&0bS?i`>H*d<$@E&p#Sz10 zLCe&ULx2gD1&Hz3@!N0R^Q-3@pus+Coub^ZQpqeX?goJ>!pXz9@DZpEmwqUj& zdidS$a<+dl%qMg#lW~ConYd95h`>GvPKuJa9fK=Q~D`VwrqS*Pz6RG&zsnUgO&6QQND*aAM8Hd~z=?nm`T<+I2Y-a@IG50|Ft8oFyX?O}&b(x5`bn1xI$m(Td&}sN7CE|G z!q09QgW5~^f*+SKawyx32)(!QFxc&q?d26iP!62J za@3TmBmkM~RQO54=#&b*YUSiT&S$&#Ee_OZ zBl4C7U!D%(co69}n%{q_PNyoHA{#SRTw54OhQbm+bgIIq1`w?D--QrQAYVraRokrU zV#Awee*e;R_qq>L^QB|sCFA)-FmGjsxU~6ogTs5hI)ph&>K~PzVFt9ql~!iP!YsEfrevulsl1TBo>PXy`w>E(bWw#ErJPv_ie9?r zfU^txyVby(41It!{0x_k)aQl;Wc11;mV~h)3{cetcEY;E)dxoUp;shH4i8jNJ1apy z8mDs@B?a2fHGi;7wPgn5u6{e*xMFtjoLz@E|lzW!)&YY!B{WHXUzycMV0Ft*6T zp}7%RYS3-Oce>}d8Y$Q4!oNtqwIbM*s(DL$BoFe#_|r8+jY>TzIy+VL@e{S2fs9)! z``G4O1TkH{gjL4Fvk@Gm>f9n=!d;vPEyQT7R0hu=oPT`VjZ6JZLO^k5#Q6X^`?#sy z`wU@-@WlA{PXvw`%inskZ7~t^;@0M9U-$Ixtyo=;E}z zqI2(-Gc=|4qeC+P;;my;h}qYk-bs)1_ib$AS^qP9&?h8&0*zJ|KB3g#KT%<<>SQSh z7-2=R4YdZEkOVfH&k8)CcY1vZndyp}UyG9-8-HN^W+ki>fQ%t4DLnK7_RUIRd-Cx5 zWUE*oxhe9G&Fb3`P~ZNSUDz^&#RqsUHwJwaO#Eg$KB~`83%^Z{w+!{y-PTI>MJ5Ds zq9T>IkT`T1Xy8dV$$#4k0r&V|{&SAu^z2qN(8zT9-pKj*yM-HXeA)!{)h^Wn?uvh>r6x(ejx7V9^%r#nvwiswIY^;H4xkYV%Ls>rI}naly1GGe(v$1d?lz