From 036f2d681ad8cfa3aad7b3fc54c641ed261a4b02 Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Mon, 6 May 2024 09:19:12 +0800 Subject: [PATCH 01/12] target/loongarch: Add TCG macro in structure CPUArchState In structure CPUArchState some struct elements are only used in TCG mode, and it is not used in KVM mode. Macro CONFIG_TCG is added to make it simpiler in KVM mode, also there is the same modification in c code when these structure elements are used. When VM runs in KVM mode, TLB entries are not used and do not need migrate. It is only useful when it runs in TCG mode. Signed-off-by: Bibo Mao Reviewed-by: Richard Henderson Message-Id: <20240506011912.2108842-1-maobibo@loongson.cn> Signed-off-by: Song Gao Signed-off-by: Xianglai Li --- target/loongarch/cpu.c | 7 +++++-- target/loongarch/cpu.h | 15 ++++++++++----- target/loongarch/cpu_helper.c | 9 +++++++++ target/loongarch/machine.c | 30 +++++++++++++++++++++++++----- 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 78f4a95cb9a..2a562afd623 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -527,7 +527,9 @@ static void loongarch_cpu_reset_hold(Object *obj) lacc->parent_phases.hold(obj); } +#ifdef CONFIG_TCG env->fcsr0_mask = FCSR0_M1 | FCSR0_M2 | FCSR0_M3; +#endif env->fcsr0 = 0x0; int n; @@ -586,7 +588,9 @@ static void loongarch_cpu_reset_hold(Object *obj) #ifndef CONFIG_USER_ONLY env->pc = 0x1c000000; +#ifdef CONFIG_TCG memset(env->tlb, 0, sizeof(env->tlb)); +#endif if (kvm_enabled()) { kvm_arch_reset_vcpu(cs); } @@ -776,8 +780,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) int i; qemu_fprintf(f, " PC=%016" PRIx64 " ", env->pc); - qemu_fprintf(f, " FCSR0 0x%08x fp_status 0x%02x\n", env->fcsr0, - get_float_exception_flags(&env->fp_status)); + qemu_fprintf(f, " FCSR0 0x%08x\n", env->fcsr0); /* gpr */ for (i = 0; i < 32; i++) { diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 4a3ae6fad54..9afa831e452 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -275,6 +275,7 @@ union fpr_t { VReg vreg; }; +#ifdef CONFIG_TCG struct LoongArchTLB { uint64_t tlb_misc; /* Fields corresponding to CSR_TLBELO0/1 */ @@ -282,6 +283,7 @@ struct LoongArchTLB { uint64_t tlb_entry1; }; typedef struct LoongArchTLB LoongArchTLB; +#endif enum loongarch_features { LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */ @@ -304,18 +306,13 @@ typedef struct CPUArchState { uint64_t pc; fpr_t fpr[32]; - float_status fp_status; bool cf[8]; uint32_t fcsr0; lbt_t lbt; - uint32_t fcsr0_mask; uint32_t cpucfg[21]; - uint64_t lladdr; /* LL virtual address compared against SC */ - uint64_t llval; - /* LoongArch CSRs */ uint64_t CSR_CRMD; uint64_t CSR_PRMD; @@ -375,8 +372,16 @@ typedef struct CPUArchState { uint64_t guest_addr; } stealtime; +#ifdef CONFIG_TCG + float_status fp_status; + uint32_t fcsr0_mask; + uint64_t lladdr; /* LL virtual address compared against SC */ + uint64_t llval; +#endif #ifndef CONFIG_USER_ONLY +#ifdef CONFIG_TCG LoongArchTLB tlb[LOONGARCH_TLB_MAX]; +#endif AddressSpace *address_space_iocsr; bool load_elf; diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c index f68d63f466e..39037eecb4b 100644 --- a/target/loongarch/cpu_helper.c +++ b/target/loongarch/cpu_helper.c @@ -11,6 +11,7 @@ #include "internals.h" #include "cpu-csr.h" +#ifdef CONFIG_TCG static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical, int *prot, target_ulong address, int access_type, int index, int mmu_idx) @@ -154,6 +155,14 @@ static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical, return TLBRET_NOMATCH; } +#else +static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical, + int *prot, target_ulong address, + MMUAccessType access_type, int mmu_idx) +{ + return TLBRET_NOMATCH; +} +#endif static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va, target_ulong dmw) diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c index dc768453583..818aa71a8b5 100644 --- a/target/loongarch/machine.c +++ b/target/loongarch/machine.c @@ -8,6 +8,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "migration/cpu.h" +#include "sysemu/tcg.h" #include "vec.h" static const VMStateDescription vmstate_fpu_reg = { @@ -133,9 +134,15 @@ static const VMStateDescription vmstate_lbt = { }; +#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY) +static bool tlb_needed(void *opaque) +{ + return tcg_enabled(); +} + /* TLB state */ -const VMStateDescription vmstate_tlb = { - .name = "cpu/tlb", +static const VMStateDescription vmstate_tlb_entry = { + .name = "cpu/tlb_entry", .version_id = 0, .minimum_version_id = 0, .fields = (VMStateField[]) { @@ -146,6 +153,19 @@ const VMStateDescription vmstate_tlb = { } }; +static const VMStateDescription vmstate_tlb = { + .name = "cpu/tlb", + .version_id = 0, + .minimum_version_id = 0, + .needed = tlb_needed, + .fields = (const VMStateField[]) { + VMSTATE_STRUCT_ARRAY(env.tlb, LoongArchCPU, LOONGARCH_TLB_MAX, + 0, vmstate_tlb_entry, LoongArchTLB), + VMSTATE_END_OF_LIST() + } +}; +#endif + /* LoongArch CPU state */ const VMStateDescription vmstate_loongarch_cpu = { .name = "cpu", @@ -211,9 +231,6 @@ const VMStateDescription vmstate_loongarch_cpu = { VMSTATE_UINT64(env.CSR_DBG, LoongArchCPU), VMSTATE_UINT64(env.CSR_DERA, LoongArchCPU), VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU), - /* TLB */ - VMSTATE_STRUCT_ARRAY(env.tlb, LoongArchCPU, LOONGARCH_TLB_MAX, - 0, vmstate_tlb, LoongArchTLB), VMSTATE_UINT64(kvm_state_counter, LoongArchCPU), /* PV steal time */ @@ -225,6 +242,9 @@ const VMStateDescription vmstate_loongarch_cpu = { &vmstate_fpu, &vmstate_lsx, &vmstate_lasx, +#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY) + &vmstate_tlb, +#endif &vmstate_lbt, NULL } -- Gitee From 075a7610239e1a8c46c6f479cbc4871620b5b62c Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Sun, 28 Apr 2024 11:16:51 +0800 Subject: [PATCH 02/12] target/loongarch: Put cpucfg operation before CSR register On Loongarch, cpucfg is register for cpu feature, some other registers depend on cpucfg feature such as perf CSR registers. Here put cpucfg read/write operations before CSR register, so that KVM knows how many perf CSR registers are valid from pre-set cpucfg feature information. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240428031651.1354587-1-maobibo@loongson.cn> Signed-off-by: Song Gao Signed-off-by: Xianglai Li --- target/loongarch/kvm/kvm.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 0ab1ee803d4..213cf6a8ce6 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -716,6 +716,11 @@ int kvm_arch_get_registers(CPUState *cs) return ret; } + ret = kvm_loongarch_get_cpucfg(cs); + if (ret) { + return ret; + } + ret = kvm_loongarch_get_csr(cs); if (ret) { return ret; @@ -737,11 +742,6 @@ int kvm_arch_get_registers(CPUState *cs) } ret = kvm_loongarch_get_mpstate(cs); - if (ret) { - return ret; - } - - ret = kvm_loongarch_get_cpucfg(cs); return ret; } @@ -754,6 +754,11 @@ int kvm_arch_put_registers(CPUState *cs, int level) return ret; } + ret = kvm_loongarch_put_cpucfg(cs); + if (ret) { + return ret; + } + ret = kvm_loongarch_put_csr(cs, level); if (ret) { return ret; @@ -781,11 +786,6 @@ int kvm_arch_put_registers(CPUState *cs, int level) } ret = kvm_loongarch_put_mpstate(cs); - if (ret) { - return ret; - } - - ret = kvm_loongarch_put_cpucfg(cs); return ret; } -- Gitee From 3154802985caaf4241cb59fac3abe63ada5a57ff Mon Sep 17 00:00:00 2001 From: Xianglai Li Date: Mon, 28 Oct 2024 20:19:01 +0800 Subject: [PATCH 03/12] target/loongarch: fixed a multi-core boot issue Fixed multiple cpu startup errors and reboot failure after cpu plug. Signed-off-by: Xianglai Li --- hw/loongarch/boot.c | 2 +- hw/loongarch/virt.c | 6 +++++- include/hw/loongarch/virt.h | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index cb668703bdd..fb9496dca4c 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -216,7 +216,7 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info) return kernel_entry; } -static void reset_load_elf(void *opaque) +void reset_load_elf(void *opaque) { LoongArchCPU *cpu = opaque; CPULoongArchState *env = &cpu->env; diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index c7492e565c2..556af5c6be7 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -875,6 +875,10 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) lacpu = LOONGARCH_CPU(cpu_state); env = &(lacpu->env); env->address_space_iocsr = &lvms->as_iocsr; + + /* connect ipi irq to cpu irq */ + qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI)); + env->ipistate = ipi; } lvms->ipi = ipi; @@ -1511,7 +1515,7 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev, env = &(cpu->env); env->address_space_iocsr = &lvms->as_iocsr; - + qemu_register_reset(reset_load_elf, LOONGARCH_CPU(qemu_get_cpu(cs->cpu_index))); env->ipistate = lvms->ipi; if (!(kvm_enabled() && kvm_irqchip_in_kernel())) { /* connect ipi irq to cpu irq, logic cpu index used here */ diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index dce7c502fa7..eb021e23381 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -84,4 +84,5 @@ struct LoongArchVirtMachineState { #define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt") OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState, LOONGARCH_VIRT_MACHINE) void loongarch_acpi_setup(LoongArchVirtMachineState *lvms); +void reset_load_elf(void *opaque); #endif -- Gitee From 21a0b23baabb2f3d7b8bcbf3945bd0a626399739 Mon Sep 17 00:00:00 2001 From: Xianglai Li Date: Tue, 29 Oct 2024 15:00:44 +0800 Subject: [PATCH 04/12] hw/loongarch/boot: Use warn_report when no kernel filename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we run “qemu-system-loongarch64 -qmp stdio -vnc none -S”, we get an error message “Need kernel filename” and then we can't use qmp cmd to query some information. So, we just throw a warning and then the cpus starts running from address VIRT_FLASH0_BASE. Signed-off-by: Song Gao Signed-off-by: Xianglai Li --- hw/loongarch/boot.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index fb9496dca4c..53dcefbb55a 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -278,7 +278,7 @@ static void init_boot_rom(struct loongarch_boot_info *info, void *p) static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) { void *p, *bp; - int64_t kernel_addr = 0; + int64_t kernel_addr = VIRT_FLASH0_BASE; LoongArchCPU *lacpu; CPUState *cs; @@ -286,8 +286,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) kernel_addr = load_kernel_info(info); } else { if(!qtest_enabled()) { - error_report("Need kernel filename\n"); - exit(1); + warn_report("No kernel provided, booting from flash drive."); } } -- Gitee From 8817f63ff4efca3ab18057cee236e3e27cd19257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Tue, 24 Sep 2024 15:49:47 +0400 Subject: [PATCH 05/12] target/loongarch: fix -Werror=maybe-uninitialized false-positive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ../target/loongarch/gdbstub.c:55:20: error: ‘val’ may be used uninitialized [-Werror=maybe-uninitialized] 55 | return gdb_get_reg32(mem_buf, val); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ ../target/loongarch/gdbstub.c:39:18: note: ‘val’ was declared here 39 | uint64_t val; Signed-off-by: Marc-André Lureau Reviewed-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Xianglai Li --- target/loongarch/gdbstub.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c index 5fc2f19e965..f8e3324bae7 100644 --- a/target/loongarch/gdbstub.c +++ b/target/loongarch/gdbstub.c @@ -33,28 +33,29 @@ void write_fcc(CPULoongArchState *env, uint64_t val) int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { - LoongArchCPU *cpu = LOONGARCH_CPU(cs); - CPULoongArchState *env = &cpu->env; - uint64_t val; - - if (0 <= n && n < 32) { - val = env->gpr[n]; - } else if (n == 32) { - /* orig_a0 */ - val = 0; - } else if (n == 33) { - val = env->pc; - } else if (n == 34) { - val = env->CSR_BADV; - } + CPULoongArchState *env = cpu_env(cs); if (0 <= n && n <= 34) { + uint64_t val; + + if (n < 32) { + val = env->gpr[n]; + } else if (n == 32) { + /* orig_a0 */ + val = 0; + } else if (n == 33) { + val = env->pc; + } else /* if (n == 34) */ { + val = env->CSR_BADV; + } + if (is_la64(env)) { return gdb_get_reg64(mem_buf, val); } else { return gdb_get_reg32(mem_buf, val); } } + return 0; } -- Gitee From 38205f31340519c705349682fadeea2b17f68cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 4 Oct 2024 11:59:56 +0200 Subject: [PATCH 06/12] target/loongarch: Use explicit little-endian LD/ST API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LoongArch architecture uses little endianness. Directly use the little-endian LD/ST API. Mechanical change using: $ end=le; \ for acc in uw w l q tul; do \ sed -i -e "s/ld${acc}_p(/ld${acc}_${end}_p(/" \ -e "s/st${acc}_p(/st${acc}_${end}_p(/" \ $(git grep -wlE '(ld|st)t?u?[wlq]_p' target/loongarch/); \ done Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20241004163042.85922-13-philmd@linaro.org> Signed-off-by: Xianglai Li --- target/loongarch/gdbstub.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c index f8e3324bae7..cc72680c38b 100644 --- a/target/loongarch/gdbstub.c +++ b/target/loongarch/gdbstub.c @@ -68,10 +68,10 @@ int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) int length = 0; if (is_la64(env)) { - tmp = ldq_p(mem_buf); + tmp = ldq_le_p(mem_buf); read_length = 8; } else { - tmp = ldl_p(mem_buf); + tmp = ldl_le_p(mem_buf); read_length = 4; } @@ -104,13 +104,13 @@ static int loongarch_gdb_set_fpu(CPULoongArchState *env, int length = 0; if (0 <= n && n < 32) { - env->fpr[n].vreg.D(0) = ldq_p(mem_buf); + env->fpr[n].vreg.D(0) = ldq_le_p(mem_buf); length = 8; } else if (32 <= n && n < 40) { env->cf[n - 32] = ldub_p(mem_buf); length = 1; } else if (n == 40) { - env->fcsr0 = ldl_p(mem_buf); + env->fcsr0 = ldl_le_p(mem_buf); length = 4; } return length; -- Gitee From 3e9ae64333b6b29e0fb862acbfd99c6daa432be1 Mon Sep 17 00:00:00 2001 From: Feiyang Chen Date: Fri, 28 Jun 2024 13:33:57 +1000 Subject: [PATCH 07/12] target/loongarch: Remove avail_64 in trans_srai_w() and simplify it Since srai.w is a valid instruction on la32, remove the avail_64 check and simplify trans_srai_w(). Fixes: c0c0461e3a06 ("target/loongarch: Add avail_64 to check la64-only instructions") Reviewed-by: Richard Henderson Signed-off-by: Feiyang Chen Message-Id: <20240628033357.50027-1-chris.chenfeiyang@gmail.com> Signed-off-by: Song Gao Signed-off-by: Xianglai Li --- target/loongarch/tcg/insn_trans/trans_shift.c.inc | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/target/loongarch/tcg/insn_trans/trans_shift.c.inc b/target/loongarch/tcg/insn_trans/trans_shift.c.inc index 2f4bd6ff288..377307785aa 100644 --- a/target/loongarch/tcg/insn_trans/trans_shift.c.inc +++ b/target/loongarch/tcg/insn_trans/trans_shift.c.inc @@ -67,19 +67,9 @@ static void gen_rotr_d(TCGv dest, TCGv src1, TCGv src2) tcg_gen_rotr_tl(dest, src1, t0); } -static bool trans_srai_w(DisasContext *ctx, arg_srai_w *a) +static void gen_sari_w(TCGv dest, TCGv src1, target_long imm) { - TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); - TCGv src1 = gpr_src(ctx, a->rj, EXT_ZERO); - - if (!avail_64(ctx)) { - return false; - } - - tcg_gen_sextract_tl(dest, src1, a->imm, 32 - a->imm); - gen_set_gpr(a->rd, dest, EXT_NONE); - - return true; + tcg_gen_sextract_tl(dest, src1, imm, 32 - imm); } TRANS(sll_w, ALL, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_sll_w) @@ -94,6 +84,7 @@ TRANS(slli_w, ALL, gen_rri_c, EXT_NONE, EXT_SIGN, tcg_gen_shli_tl) TRANS(slli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shli_tl) TRANS(srli_w, ALL, gen_rri_c, EXT_ZERO, EXT_SIGN, tcg_gen_shri_tl) TRANS(srli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shri_tl) +TRANS(srai_w, ALL, gen_rri_c, EXT_NONE, EXT_NONE, gen_sari_w) TRANS(srai_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_sari_tl) TRANS(rotri_w, 64, gen_rri_v, EXT_NONE, EXT_NONE, gen_rotr_w) TRANS(rotri_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_rotri_tl) -- Gitee From f2afd64d1f35e1bfbd2836c45d7d8d9871a55bc5 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Fri, 5 Jul 2024 10:18:38 +0800 Subject: [PATCH 08/12] target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values We set the value of register CSR_PRCFG3, but left out CSR_PRCFG1 and CSR_PRCFG2. Set CSR_PRCFG1 and CSR_PRCFG2 according to the default values of the physical machine. Signed-off-by: Song Gao Reviewed-by: Bibo Mao Message-Id: <20240705021839.1004374-1-gaosong@loongson.cn> Signed-off-by: Xianglai Li --- target/loongarch/cpu.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 2a562afd623..b80dde5ef96 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -463,6 +463,18 @@ static void loongarch_la464_initfn(Object *obj) env->cpucfg[20] = data; env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa); + + env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8); + env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 0x2f); + env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7); + + env->CSR_PRCFG2 = 0x3ffff000; + + env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2); + env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63); + env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7); + env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8); + loongarch_cpu_post_init(obj); } @@ -574,11 +586,6 @@ static void loongarch_cpu_reset_hold(Object *obj) env->CSR_TLBRENTRY = 0; env->CSR_MERRENTRY = 0; - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8); - for (n = 0; n < 4; n++) { env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0); env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV1, 0); -- Gitee From 4e2073adb37295cab18c97ed5101fafd8bb28872 Mon Sep 17 00:00:00 2001 From: Gao Jiazhen Date: Thu, 12 Sep 2024 11:27:12 +0800 Subject: [PATCH 09/12] target/loongarch: fix a wrong print in cpu dump cherry picked from commit 78f932ea1f7b3b9b0ac628dc2a91281318fe51fa description: loongarch_cpu_dump_state() want to dump all loongarch cpu state registers, but there is a tiny typographical error when printing "PRCFG2". Cc: qemu-stable@nongnu.org Signed-off-by: lanyanzhi Reviewed-by: Richard Henderson Reviewed-by: Song Gao Message-Id: <20240604073831.666690-1-lanyanzhi22b@ict.ac.cn> Signed-off-by: Song Gao Signed-off-by: Gao Jiazhen Signed-off-by: Xianglai Li --- target/loongarch/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index b80dde5ef96..bfc7df3044c 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -91,7 +91,7 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env, { CPUState *cs = env_cpu(env); - qemu_log_mask(CPU_LOG_INT, "%s: expection: %d (%s)\n", + qemu_log_mask(CPU_LOG_INT, "%s: exception: %d (%s)\n", __func__, exception, loongarch_exception_name(exception)); @@ -810,7 +810,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) qemu_fprintf(f, "EENTRY=%016" PRIx64 "\n", env->CSR_EENTRY); qemu_fprintf(f, "PRCFG1=%016" PRIx64 ", PRCFG2=%016" PRIx64 "," " PRCFG3=%016" PRIx64 "\n", - env->CSR_PRCFG1, env->CSR_PRCFG3, env->CSR_PRCFG3); + env->CSR_PRCFG1, env->CSR_PRCFG2, env->CSR_PRCFG3); qemu_fprintf(f, "TLBRENTRY=%016" PRIx64 "\n", env->CSR_TLBRENTRY); qemu_fprintf(f, "TLBRBADV=%016" PRIx64 "\n", env->CSR_TLBRBADV); qemu_fprintf(f, "TLBRERA=%016" PRIx64 "\n", env->CSR_TLBRERA); -- Gitee From 7b1de30924d4569bd64a52fd7b4499d2ab90ffe3 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 25 Jan 2024 13:36:37 +0100 Subject: [PATCH 10/12] loongarch: switch boards to "default y" Some targets use "default y" for boards to filter out those that require TCG. For consistency we are switching all other targets to do the same. Continue with Loongarch. No changes to generated config-devices.mak file. Signed-off-by: Paolo Bonzini Signed-off-by: Xianglai Li --- .gitlab-ci.d/buildtest.yml | 2 ++ configs/devices/loongarch64-softmmu/default.mak | 6 +++++- hw/loongarch/Kconfig | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml index 0a01746cea9..e39e3275512 100644 --- a/.gitlab-ci.d/buildtest.yml +++ b/.gitlab-ci.d/buildtest.yml @@ -579,6 +579,8 @@ build-tci: - make check-tcg # Check our reduced build configurations +# requires libfdt: aarch64, arm, i386, loongarch64, x86_64 +# does not build without boards: i386, loongarch64, x86_64 build-without-defaults: extends: .native_build_job_template needs: diff --git a/configs/devices/loongarch64-softmmu/default.mak b/configs/devices/loongarch64-softmmu/default.mak index 928bc117ef7..ffe705836fd 100644 --- a/configs/devices/loongarch64-softmmu/default.mak +++ b/configs/devices/loongarch64-softmmu/default.mak @@ -1,3 +1,7 @@ # Default configuration for loongarch64-softmmu -CONFIG_LOONGARCH_VIRT=y +# Uncomment the following lines to disable these optional devices: +# CONFIG_PCI_DEVICES=n + +# Boards are selected by default, uncomment to keep out of the build. +# CONFIG_LOONGARCH_VIRT=n diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig index 9b687b4cb47..16c854c0d59 100644 --- a/hw/loongarch/Kconfig +++ b/hw/loongarch/Kconfig @@ -1,5 +1,7 @@ config LOONGARCH_VIRT bool + default y + depends on LOONGARCH64 select PCI select PCI_EXPRESS_GENERIC_BRIDGE imply PCI_DEVICES -- Gitee From 6c733d918decbc5db37c1110ff96cde50d29d118 Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Tue, 28 May 2024 16:20:53 +0800 Subject: [PATCH 11/12] tests/libqos: Add loongarch virt machine node Add loongarch virt machine to the graph. It is a modified copy of the existing riscv virtmachine in riscv-virt-machine.c It contains a generic-pcihost controller, and an extra function loongarch_config_qpci_bus() to configure GPEX pci host controller information, such as ecam and pio_base addresses. Also hotplug handle checking about TYPE_VIRTIO_IOMMU_PCI device is added on loongarch virt machine, since virtio_mmu_pci device requires it. Signed-off-by: Bibo Mao Acked-by: Thomas Huth Message-Id: <20240528082053.938564-1-maobibo@loongson.cn> Signed-off-by: Song Gao Signed-off-by: Xianglai Li --- tests/qtest/libqos/loongarch-virt-machine.c | 114 ++++++++++++++++++++ tests/qtest/libqos/meson.build | 1 + 2 files changed, 115 insertions(+) create mode 100644 tests/qtest/libqos/loongarch-virt-machine.c diff --git a/tests/qtest/libqos/loongarch-virt-machine.c b/tests/qtest/libqos/loongarch-virt-machine.c new file mode 100644 index 00000000000..c12089c015d --- /dev/null +++ b/tests/qtest/libqos/loongarch-virt-machine.c @@ -0,0 +1,114 @@ +/* + * libqos driver framework + * + * Copyright (c) 2018 Emanuele Giuseppe Esposito + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. + * + * 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 "../libqtest.h" +#include "qemu/module.h" +#include "libqos-malloc.h" +#include "qgraph.h" +#include "virtio-mmio.h" +#include "generic-pcihost.h" +#include "hw/pci/pci_regs.h" + +#define LOONGARCH_PAGE_SIZE 0x1000 +#define LOONGARCH_VIRT_RAM_ADDR 0x100000 +#define LOONGARCH_VIRT_RAM_SIZE 0xFF00000 + +#define LOONGARCH_VIRT_PIO_BASE 0x18000000 +#define LOONGARCH_VIRT_PCIE_PIO_OFFSET 0x4000 +#define LOONGARCH_VIRT_PCIE_PIO_LIMIT 0x10000 +#define LOONGARCH_VIRT_PCIE_ECAM_BASE 0x20000000 +#define LOONGARCH_VIRT_PCIE_MMIO32_BASE 0x40000000 +#define LOONGARCH_VIRT_PCIE_MMIO32_LIMIT 0x80000000 + +typedef struct QVirtMachine QVirtMachine; + +struct QVirtMachine { + QOSGraphObject obj; + QGuestAllocator alloc; + QVirtioMMIODevice virtio_mmio; + QGenericPCIHost bridge; +}; + +static void virt_destructor(QOSGraphObject *obj) +{ + QVirtMachine *machine = (QVirtMachine *) obj; + alloc_destroy(&machine->alloc); +} + +static void *virt_get_driver(void *object, const char *interface) +{ + QVirtMachine *machine = object; + if (!g_strcmp0(interface, "memory")) { + return &machine->alloc; + } + + fprintf(stderr, "%s not present in loongarch/virtio\n", interface); + g_assert_not_reached(); +} + +static QOSGraphObject *virt_get_device(void *obj, const char *device) +{ + QVirtMachine *machine = obj; + if (!g_strcmp0(device, "generic-pcihost")) { + return &machine->bridge.obj; + } else if (!g_strcmp0(device, "virtio-mmio")) { + return &machine->virtio_mmio.obj; + } + + fprintf(stderr, "%s not present in loongarch/virt\n", device); + g_assert_not_reached(); +} + +static void loongarch_config_qpci_bus(QGenericPCIBus *qpci) +{ + qpci->gpex_pio_base = LOONGARCH_VIRT_PIO_BASE; + qpci->bus.pio_alloc_ptr = LOONGARCH_VIRT_PCIE_PIO_OFFSET; + qpci->bus.pio_limit = LOONGARCH_VIRT_PCIE_PIO_LIMIT; + qpci->bus.mmio_alloc_ptr = LOONGARCH_VIRT_PCIE_MMIO32_BASE; + qpci->bus.mmio_limit = LOONGARCH_VIRT_PCIE_MMIO32_LIMIT; + qpci->ecam_alloc_ptr = LOONGARCH_VIRT_PCIE_ECAM_BASE; +} + +static void *qos_create_machine_loongarch_virt(QTestState *qts) +{ + QVirtMachine *machine = g_new0(QVirtMachine, 1); + + alloc_init(&machine->alloc, 0, + LOONGARCH_VIRT_RAM_ADDR, + LOONGARCH_VIRT_RAM_ADDR + LOONGARCH_VIRT_RAM_SIZE, + LOONGARCH_PAGE_SIZE); + + qos_create_generic_pcihost(&machine->bridge, qts, &machine->alloc); + loongarch_config_qpci_bus(&machine->bridge.pci); + + machine->obj.get_device = virt_get_device; + machine->obj.get_driver = virt_get_driver; + machine->obj.destructor = virt_destructor; + return machine; +} + +static void virt_machine_register_nodes(void) +{ + qos_node_create_machine_args("loongarch64/virt", + qos_create_machine_loongarch_virt, + " -cpu la464"); + qos_node_contains("loongarch64/virt", "generic-pcihost", NULL); +} + +libqos_init(virt_machine_register_nodes); diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build index 90aae42a225..482c9b2aab9 100644 --- a/tests/qtest/libqos/meson.build +++ b/tests/qtest/libqos/meson.build @@ -60,6 +60,7 @@ libqos_srcs = files( 'arm-xilinx-zynq-a9-machine.c', 'ppc64_pseries-machine.c', 'x86_64_pc-machine.c', + 'loongarch-virt-machine.c', ) if have_virtfs -- Gitee From 718f9f6636aa7957550bddec46d434c91c0199f8 Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Fri, 7 Jun 2024 11:50:16 +0800 Subject: [PATCH 12/12] target/loongarch/kvm: Add software breakpoint support With KVM virtualization, debug exception is injected to guest kernel rather than host for normal break intruction. Here hypercall instruction with special code is used for sw breakpoint usage, and detailed instruction comes from kvm kernel with user API KVM_REG_LOONGARCH_DEBUG_INST. Now only software breakpoint is supported, and it is allowed to insert/remove software breakpoint. We can debug guest kernel with gdb method after kernel is loaded, hardware breakpoint will be added in later. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Tested-by: Song Gao Message-Id: <20240607035016.2975799-1-maobibo@loongson.cn> Signed-off-by: Song Gao Signed-off-by: Xianglai Li --- configs/targets/loongarch64-softmmu.mak | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak index f23780fdd89..0034c336200 100644 --- a/configs/targets/loongarch64-softmmu.mak +++ b/configs/targets/loongarch64-softmmu.mak @@ -1,5 +1,6 @@ TARGET_ARCH=loongarch64 TARGET_BASE_ARCH=loongarch +TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml TARGET_NEED_FDT=y -- Gitee