From dab1e1e15b559c11b980a6b921027dd4939107e9 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Sat, 5 Dec 2020 17:22:01 +0800 Subject: [PATCH 01/26] MAINTAINERS: chenhc@lemote.com -> chenhuacai@kernel.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use @kernel.org address as the main communications end point. Update the corresponding M-entries and .mailmap (for git shortlog translation). Signed-off-by: Huacai Chen Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Message-Id: <1607160121-9977-1-git-send-email-chenhuacai@kernel.org> --- .mailmap | 2 ++ MAINTAINERS | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.mailmap b/.mailmap index 663819fb01..a1bd659817 100644 --- a/.mailmap +++ b/.mailmap @@ -49,6 +49,8 @@ Anthony Liguori Anthony Liguori Filip Bozuta Frederic Konrad Greg Kurz +Huacai Chen +Huacai Chen James Hogan Leif Lindholm Radoslaw Biernacki diff --git a/MAINTAINERS b/MAINTAINERS index d48a4e8a8b..d396c5943b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -388,7 +388,7 @@ S: Maintained F: target/arm/kvm.c MIPS KVM CPUs -M: Huacai Chen +M: Huacai Chen S: Odd Fixes F: target/mips/kvm.c @@ -1149,7 +1149,7 @@ F: hw/mips/mipssim.c F: hw/net/mipsnet.c Fuloong 2E -M: Huacai Chen +M: Huacai Chen M: Philippe Mathieu-Daudé R: Jiaxun Yang S: Odd Fixes @@ -1159,7 +1159,7 @@ F: hw/pci-host/bonito.c F: include/hw/isa/vt82c686.h Loongson-3 virtual platforms -M: Huacai Chen +M: Huacai Chen R: Jiaxun Yang S: Maintained F: hw/intc/loongson_liointc.c @@ -2861,7 +2861,7 @@ F: disas/i386.c MIPS TCG target M: Philippe Mathieu-Daudé R: Aurelien Jarno -R: Huacai Chen +R: Huacai Chen R: Jiaxun Yang R: Aleksandar Rikalo S: Odd Fixes From 11cb076b26ff25a909f07c593f9a4e0416ac147f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 29 Apr 2020 10:23:55 +0200 Subject: [PATCH 02/26] target/mips/kvm: Assert unreachable code is not used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This code must not be used outside of KVM. Abort if it is. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Huacai Chen Acked-by: Paolo Bonzini Message-Id: <20200429082916.10669-3-f4bug@amsat.org> --- target/mips/kvm.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/target/mips/kvm.c b/target/mips/kvm.c index 72637a1e02..cbd0cb8faa 100644 --- a/target/mips/kvm.c +++ b/target/mips/kvm.c @@ -198,9 +198,7 @@ int kvm_mips_set_interrupt(MIPSCPU *cpu, int irq, int level) CPUState *cs = CPU(cpu); struct kvm_mips_interrupt intr; - if (!kvm_enabled()) { - return 0; - } + assert(kvm_enabled()); intr.cpu = -1; @@ -221,9 +219,7 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level) CPUState *dest_cs = CPU(cpu); struct kvm_mips_interrupt intr; - if (!kvm_enabled()) { - return 0; - } + assert(kvm_enabled()); intr.cpu = dest_cs->cpu_index; From 86deb70172b5aecac65229c88b1a2090179a027c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 5 Dec 2020 18:35:03 +0100 Subject: [PATCH 03/26] target/mips/kvm: Remove unused headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-7-f4bug@amsat.org> --- target/mips/kvm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/target/mips/kvm.c b/target/mips/kvm.c index cbd0cb8faa..94b3a88d8f 100644 --- a/target/mips/kvm.c +++ b/target/mips/kvm.c @@ -19,11 +19,9 @@ #include "internal.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" -#include "qemu/timer.h" #include "sysemu/kvm.h" #include "sysemu/kvm_int.h" #include "sysemu/runstate.h" -#include "sysemu/cpus.h" #include "kvm_mips.h" #include "exec/memattrs.h" #include "hw/boards.h" From 34cffe960e494ae6dc79efeb87fc3e79fe7de90c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 5 Dec 2020 18:34:15 +0100 Subject: [PATCH 04/26] target/mips: Include "exec/memattrs.h" in 'internal.h' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mips_cpu_do_transaction_failed() requires MemTxAttrs and MemTxResult declarations. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-8-f4bug@amsat.org> --- target/mips/internal.h | 1 + target/mips/kvm.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/target/mips/internal.h b/target/mips/internal.h index dd8a7809b6..76b7a85cbb 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -8,6 +8,7 @@ #ifndef MIPS_INTERNAL_H #define MIPS_INTERNAL_H +#include "exec/memattrs.h" #include "fpu/softfloat-helpers.h" /* diff --git a/target/mips/kvm.c b/target/mips/kvm.c index 94b3a88d8f..477692566a 100644 --- a/target/mips/kvm.c +++ b/target/mips/kvm.c @@ -23,7 +23,6 @@ #include "sysemu/kvm_int.h" #include "sysemu/runstate.h" #include "kvm_mips.h" -#include "exec/memattrs.h" #include "hw/boards.h" #define DEBUG_KVM 0 From 547b9b17f9cbe7bc16db73f4aaceeead54c03f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 9 Nov 2020 09:15:41 +0100 Subject: [PATCH 05/26] target/mips: Replace magic values by CP0PM_MASK or TARGET_PAGE_BITS_MIN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace magic values related to page size: 12 -> TARGET_PAGE_BITS_MIN 13 -> CP0PM_MASK Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Huacai Chen Message-Id: <20201109090422.2445166-2-f4bug@amsat.org> --- target/mips/cp0_helper.c | 5 +++-- target/mips/helper.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/target/mips/cp0_helper.c b/target/mips/cp0_helper.c index a1b5140cca..e8b9343ec9 100644 --- a/target/mips/cp0_helper.c +++ b/target/mips/cp0_helper.c @@ -904,7 +904,7 @@ void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask) goto invalid; } /* We don't support VTLB entry smaller than target page */ - if ((maskbits + 12) < TARGET_PAGE_BITS) { + if ((maskbits + TARGET_PAGE_BITS_MIN) < TARGET_PAGE_BITS) { goto invalid; } env->CP0_PageMask = mask << CP0PM_MASK; @@ -913,7 +913,8 @@ void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask) invalid: /* When invalid, set to default target page size. */ - env->CP0_PageMask = (~TARGET_PAGE_MASK >> 12) << CP0PM_MASK; + mask = (~TARGET_PAGE_MASK >> TARGET_PAGE_BITS_MIN); + env->CP0_PageMask = mask << CP0PM_MASK; } void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1) diff --git a/target/mips/helper.c b/target/mips/helper.c index 063b65c052..041432489d 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -858,8 +858,8 @@ refill: break; } } - pw_pagemask = m >> 12; - update_pagemask(env, pw_pagemask << 13, &pw_pagemask); + pw_pagemask = m >> TARGET_PAGE_BITS_MIN; + update_pagemask(env, pw_pagemask << CP0PM_MASK, &pw_pagemask); pw_entryhi = (address & ~0x1fff) | (env->CP0_EntryHi & 0xFF); { target_ulong tmp_entryhi = env->CP0_EntryHi; From 55671f80cbb011343cf5786186daed600fcfab4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 9 Nov 2020 09:41:24 +0100 Subject: [PATCH 06/26] target/mips: Do not include CP0 helpers in user-mode emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CP0 helpers are restricted to system-mode emulation. Do not intent do build cp0_helper.c in user-mode (this allows to simplify some #ifdef'ry). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Huacai Chen Message-Id: <20201109090422.2445166-3-f4bug@amsat.org> --- target/mips/cp0_helper.c | 4 ---- target/mips/meson.build | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/target/mips/cp0_helper.c b/target/mips/cp0_helper.c index e8b9343ec9..caaaefcc8a 100644 --- a/target/mips/cp0_helper.c +++ b/target/mips/cp0_helper.c @@ -32,7 +32,6 @@ #include "sysemu/kvm.h" -#ifndef CONFIG_USER_ONLY /* SMP helpers. */ static bool mips_vpe_is_wfi(MIPSCPU *c) { @@ -1667,10 +1666,8 @@ target_ulong helper_evpe(CPUMIPSState *env) } return prev; } -#endif /* !CONFIG_USER_ONLY */ /* R6 Multi-threading */ -#ifndef CONFIG_USER_ONLY target_ulong helper_dvp(CPUMIPSState *env) { CPUState *other_cs = first_cpu; @@ -1709,4 +1706,3 @@ target_ulong helper_evp(CPUMIPSState *env) } return prev; } -#endif /* !CONFIG_USER_ONLY */ diff --git a/target/mips/meson.build b/target/mips/meson.build index fa1f024e78..681a5524c0 100644 --- a/target/mips/meson.build +++ b/target/mips/meson.build @@ -1,6 +1,5 @@ mips_ss = ss.source_set() mips_ss.add(files( - 'cp0_helper.c', 'cpu.c', 'dsp_helper.c', 'fpu_helper.c', @@ -15,6 +14,7 @@ mips_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) mips_softmmu_ss = ss.source_set() mips_softmmu_ss.add(files( + 'cp0_helper.c', 'cp0_timer.c', 'machine.c', 'mips-semi.c', From 5777c8a905d5aa35d5308a6785c9d9b60cd498cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 5 Dec 2020 18:35:12 +0100 Subject: [PATCH 07/26] target/mips: Remove unused headers from cp0_helper.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove unused headers and add missing "qemu/log.h" since qemu_log() is called. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-5-f4bug@amsat.org> --- target/mips/cp0_helper.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/target/mips/cp0_helper.c b/target/mips/cp0_helper.c index caaaefcc8a..cb899fe3d7 100644 --- a/target/mips/cp0_helper.c +++ b/target/mips/cp0_helper.c @@ -21,15 +21,13 @@ */ #include "qemu/osdep.h" +#include "qemu/log.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 "exec/memop.h" -#include "sysemu/kvm.h" /* SMP helpers. */ From 90c429ee765ec6ca2e2384edc9e45b4ddfae9adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 18 Nov 2020 17:47:29 +0100 Subject: [PATCH 08/26] target/mips: Also display exception names in user-mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently MIPS exceptions are displayed as string in system-mode emulation, but as number in user-mode. Unify by extracting the current system-mode code as excp_name() and use that in user-mode. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201119160536.1980329-1-f4bug@amsat.org> --- target/mips/helper.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/target/mips/helper.c b/target/mips/helper.c index 041432489d..59de58fcbc 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -978,6 +978,7 @@ hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address, return physical; } } +#endif /* !CONFIG_USER_ONLY */ static const char * const excp_names[EXCP_LAST + 1] = { [EXCP_RESET] = "reset", @@ -1018,7 +1019,14 @@ static const char * const excp_names[EXCP_LAST + 1] = { [EXCP_MSADIS] = "MSA disabled", [EXCP_MSAFPE] = "MSA floating point", }; -#endif + +static const char *mips_exception_name(int32_t exception) +{ + if (exception < 0 || exception > EXCP_LAST) { + return "unknown"; + } + return excp_names[exception]; +} target_ulong exception_resume_pc(CPUMIPSState *env) { @@ -1091,19 +1099,13 @@ void mips_cpu_do_interrupt(CPUState *cs) bool update_badinstr = 0; target_ulong offset; 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 " EPC " TARGET_FMT_lx " %s exception\n", - __func__, env->active_tc.PC, env->CP0_EPC, name); + __func__, env->active_tc.PC, env->CP0_EPC, + mips_exception_name(cs->exception_index)); } if (cs->exception_index == EXCP_EXT_INTERRUPT && (env->hflags & MIPS_HFLAG_DM)) { @@ -1490,8 +1492,9 @@ void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env, { CPUState *cs = env_cpu(env); - qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n", - __func__, exception, error_code); + qemu_log_mask(CPU_LOG_INT, "%s: %d (%s) %d\n", + __func__, exception, mips_exception_name(exception), + error_code); cs->exception_index = exception; env->error_code = error_code; From 7d6f01a12be534ce2ffaf0aa8741e5f5efca2362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 30 Nov 2020 11:13:01 +0100 Subject: [PATCH 09/26] target/mips: Allow executing MSA instructions on Loongson-3A4000 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Loongson-3A4000 is a GS464V-based processor with MIPS MSA ASE: https://www.mail-archive.com/qemu-devel@nongnu.org/msg763059.html Commit af868995e1b correctly set the 'MSA present' bit of Config3 register, but forgot to allow the MSA instructions decoding in insn_flags, so executing them triggers a 'Reserved Instruction'. Fix by adding the ASE_MSA mask to insn_flags. Fixes: af868995e1b ("target/mips: Add Loongson-3 CPU definition") Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Huacai Chen Message-Id: <20201130102228.2395100-1-f4bug@amsat.org> --- target/mips/translate_init.c.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/mips/translate_init.c.inc b/target/mips/translate_init.c.inc index ea85d5c6a7..79f75ed863 100644 --- a/target/mips/translate_init.c.inc +++ b/target/mips/translate_init.c.inc @@ -832,7 +832,7 @@ const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { - .name = "Loongson-3A4000", + .name = "Loongson-3A4000", /* GS464V-based */ .CP0_PRid = 0x14C000, /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */ .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | @@ -885,7 +885,7 @@ const mips_def_t mips_defs[] = .CP1_fcr31_rw_bitmask = 0xFF83FFFF, .SEGBITS = 48, .PABITS = 48, - .insn_flags = CPU_LOONGSON3A, + .insn_flags = CPU_LOONGSON3A | ASE_MSA, .mmu_type = MMU_TYPE_R4000, }, { From 1ab3a0de2f40f70bdfbd1a319a9734089bddcf72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 1 Dec 2020 12:26:09 +0100 Subject: [PATCH 10/26] target/mips: Explicit Release 6 MMU types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As of Release 6, MMU type 4 is assigned to "Dual Variable-Page-Size and Fixed-Page-Size TLBs" and type 2 to "Block Address Translation. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201201132817.2863301-4-f4bug@amsat.org> --- target/mips/internal.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target/mips/internal.h b/target/mips/internal.h index 76b7a85cbb..bcd3d857ab 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -16,10 +16,11 @@ * CP0C0_MT field. */ enum mips_mmu_types { - MMU_TYPE_NONE, - MMU_TYPE_R4000, - MMU_TYPE_RESERVED, - MMU_TYPE_FMT, + MMU_TYPE_NONE = 0, + MMU_TYPE_R4000 = 1, /* Standard TLB */ + MMU_TYPE_BAT = 2, /* Block Address Translation */ + MMU_TYPE_FMT = 3, /* Fixed Mapping */ + MMU_TYPE_DVF = 4, /* Dual VTLB and FTLB */ MMU_TYPE_R3000, MMU_TYPE_R6000, MMU_TYPE_R8000 From ac70f9767cba3a5966f7eefc102fcda8b3c7d09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 7 Dec 2020 22:32:49 +0100 Subject: [PATCH 11/26] target/mips: Rename cpu_supports_FEAT() as cpu_type_supports_FEAT() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As cpu_supports_isa() / cpu_supports_cps_smp() take a 'cpu_type' name argument, rename them cpu_type_supports_FEAT(). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201207215257.4004222-2-f4bug@amsat.org> --- hw/mips/boston.c | 4 ++-- hw/mips/malta.c | 4 ++-- target/mips/cpu.h | 4 ++-- target/mips/translate.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/mips/boston.c b/hw/mips/boston.c index 3d40867dc4..16467ea475 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -459,12 +459,12 @@ static void boston_mach_init(MachineState *machine) s = BOSTON(dev); s->mach = machine; - if (!cpu_supports_cps_smp(machine->cpu_type)) { + if (!cpu_type_supports_cps_smp(machine->cpu_type)) { error_report("Boston requires CPUs which support CPS"); exit(1); } - is_64b = cpu_supports_isa(machine->cpu_type, ISA_MIPS64); + is_64b = cpu_type_supports_isa(machine->cpu_type, ISA_MIPS64); object_initialize_child(OBJECT(machine), "cps", &s->cps, TYPE_MIPS_CPS); object_property_set_str(OBJECT(&s->cps), "cpu-type", machine->cpu_type, diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 5c11eecec1..4651a1055c 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -1205,7 +1205,7 @@ static void create_cps(MachineState *ms, MaltaState *s, static void mips_create_cpu(MachineState *ms, MaltaState *s, qemu_irq *cbus_irq, qemu_irq *i8259_irq) { - if ((ms->smp.cpus > 1) && cpu_supports_cps_smp(ms->cpu_type)) { + if ((ms->smp.cpus > 1) && cpu_type_supports_cps_smp(ms->cpu_type)) { create_cps(ms, s, cbus_irq, i8259_irq); } else { create_cpu_without_cps(ms, s, cbus_irq, i8259_irq); @@ -1309,7 +1309,7 @@ void mips_malta_init(MachineState *machine) loaderparams.initrd_filename = initrd_filename; kernel_entry = load_kernel(); - if (!cpu_supports_isa(machine->cpu_type, ISA_NANOMIPS32)) { + if (!cpu_type_supports_isa(machine->cpu_type, ISA_NANOMIPS32)) { write_bootloader(memory_region_get_ram_ptr(bios), bootloader_run_addr, kernel_entry); } else { diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 23f8c6f96c..9c65c87bf9 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -1286,8 +1286,8 @@ int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc); #define MIPS_CPU_TYPE_NAME(model) model MIPS_CPU_TYPE_SUFFIX #define CPU_RESOLVING_TYPE TYPE_MIPS_CPU -bool cpu_supports_cps_smp(const char *cpu_type); -bool cpu_supports_isa(const char *cpu_type, uint64_t isa); +bool cpu_type_supports_cps_smp(const char *cpu_type); +bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa); void cpu_set_exception_base(int vp_index, target_ulong address); /* mips_int.c */ diff --git a/target/mips/translate.c b/target/mips/translate.c index c64a1bc42e..b8ed16bb77 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -31770,13 +31770,13 @@ void cpu_mips_realize_env(CPUMIPSState *env) mvp_init(env, env->cpu_model); } -bool cpu_supports_cps_smp(const char *cpu_type) +bool cpu_type_supports_cps_smp(const char *cpu_type) { const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type)); return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0; } -bool cpu_supports_isa(const char *cpu_type, uint64_t isa) +bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa) { const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type)); return (mcc->cpu_def->insn_flags & isa) != 0; From df6adb68c1b1808f164c9ed8a04fe14d9c04e82c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 7 Dec 2020 22:33:22 +0100 Subject: [PATCH 12/26] target/mips: Introduce cpu_supports_isa() taking CPUMIPSState argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce cpu_supports_isa() which takes a CPUMIPSState argument, more useful at runtime when the CPU is created (no need to call the extensive object_class_by_name()). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201207215257.4004222-3-f4bug@amsat.org> --- target/mips/cpu.c | 5 +++++ target/mips/cpu.h | 1 + 2 files changed, 6 insertions(+) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 76d50b00b4..687e2680dd 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -310,3 +310,8 @@ MIPSCPU *mips_cpu_create_with_clock(const char *cpu_type, Clock *cpu_refclk) return MIPS_CPU(cpu); } + +bool cpu_supports_isa(const CPUMIPSState *env, uint64_t isa_mask) +{ + return (env->cpu_model->insn_flags & isa_mask) != 0; +} diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 9c65c87bf9..e8bca75f23 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -1287,6 +1287,7 @@ int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc); #define CPU_RESOLVING_TYPE TYPE_MIPS_CPU bool cpu_type_supports_cps_smp(const char *cpu_type); +bool cpu_supports_isa(const CPUMIPSState *env, uint64_t isa_mask); bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa); void cpu_set_exception_base(int vp_index, target_ulong address); From 2fd9c5ad4449c862932b21e8f6b4573cc50b9ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 6 Dec 2020 20:29:00 +0100 Subject: [PATCH 13/26] hw/mips: Move address translation helpers to target/mips/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address translation is an architectural thing (not hardware related). Move the helpers from hw/ to target/. As physical address and KVM are specific to system mode emulation, restrict this file to softmmu, so it doesn't get compiled for user-mode emulation. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-2-f4bug@amsat.org> --- hw/mips/boston.c | 1 - hw/mips/meson.build | 2 +- include/hw/mips/cpudevs.h | 7 ------- {hw => target}/mips/addr.c | 2 +- target/mips/cpu.h | 8 ++++++++ target/mips/meson.build | 1 + target/mips/translate.c | 2 -- 7 files changed, 11 insertions(+), 12 deletions(-) rename {hw => target}/mips/addr.c (98%) diff --git a/hw/mips/boston.c b/hw/mips/boston.c index 16467ea475..c3b94c68e1 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -28,7 +28,6 @@ #include "hw/loader.h" #include "hw/loader-fit.h" #include "hw/mips/cps.h" -#include "hw/mips/cpudevs.h" #include "hw/pci-host/xilinx-pcie.h" #include "hw/qdev-clock.h" #include "hw/qdev-properties.h" diff --git a/hw/mips/meson.build b/hw/mips/meson.build index bcdf96be69..77b4d8f365 100644 --- a/hw/mips/meson.build +++ b/hw/mips/meson.build @@ -1,5 +1,5 @@ mips_ss = ss.source_set() -mips_ss.add(files('addr.c', 'mips_int.c')) +mips_ss.add(files('mips_int.c')) mips_ss.add(when: 'CONFIG_FULOONG', if_true: files('fuloong2e.c')) mips_ss.add(when: 'CONFIG_JAZZ', if_true: files('jazz.c')) mips_ss.add(when: 'CONFIG_MALTA', if_true: files('gt64xxx_pci.c', 'malta.c')) diff --git a/include/hw/mips/cpudevs.h b/include/hw/mips/cpudevs.h index 291f59281a..f7c9728fa9 100644 --- a/include/hw/mips/cpudevs.h +++ b/include/hw/mips/cpudevs.h @@ -5,13 +5,6 @@ /* Definitions for MIPS CPU internal devices. */ -/* addr.c */ -uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr); -uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr); -uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr); -bool mips_um_ksegs_enabled(void); -void mips_um_ksegs_enable(void); - /* mips_int.c */ void cpu_mips_irq_init_cpu(MIPSCPU *cpu); diff --git a/hw/mips/addr.c b/target/mips/addr.c similarity index 98% rename from hw/mips/addr.c rename to target/mips/addr.c index 2f138fe1ea..27a6036c45 100644 --- a/hw/mips/addr.c +++ b/target/mips/addr.c @@ -21,7 +21,7 @@ */ #include "qemu/osdep.h" -#include "hw/mips/cpudevs.h" +#include "cpu.h" static int mips_um_ksegs; diff --git a/target/mips/cpu.h b/target/mips/cpu.h index e8bca75f23..5d3b2a01c0 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -1291,6 +1291,14 @@ bool cpu_supports_isa(const CPUMIPSState *env, uint64_t isa_mask); bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa); void cpu_set_exception_base(int vp_index, target_ulong address); +/* addr.c */ +uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr); +uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr); + +uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr); +bool mips_um_ksegs_enabled(void); +void mips_um_ksegs_enable(void); + /* mips_int.c */ void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level); diff --git a/target/mips/meson.build b/target/mips/meson.build index 681a5524c0..4179395a8e 100644 --- a/target/mips/meson.build +++ b/target/mips/meson.build @@ -14,6 +14,7 @@ mips_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) mips_softmmu_ss = ss.source_set() mips_softmmu_ss.add(files( + 'addr.c', 'cp0_helper.c', 'cp0_timer.c', 'machine.c', diff --git a/target/mips/translate.c b/target/mips/translate.c index b8ed16bb77..4a1ae73f9d 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28,8 +28,6 @@ #include "exec/exec-all.h" #include "tcg/tcg-op.h" #include "exec/cpu_ldst.h" -#include "hw/mips/cpudevs.h" - #include "exec/helper-proto.h" #include "exec/helper-gen.h" #include "hw/semihosting/semihost.h" From 1379307db20ab2e865d3ec148669c95cfe49b666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 7 Dec 2020 00:36:03 +0100 Subject: [PATCH 14/26] target/mips: Remove unused headers from translate.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-3-f4bug@amsat.org> --- target/mips/translate.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 4a1ae73f9d..e87f472a8d 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -24,8 +24,6 @@ #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 "exec/helper-proto.h" From 5f3013654e879bb4b22876617fdb235aa22568d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 5 Dec 2020 18:36:03 +0100 Subject: [PATCH 15/26] target/mips: Remove unused headers from op_helper.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-6-f4bug@amsat.org> --- target/mips/op_helper.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index 5184a1838b..5aa97902e9 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -19,15 +19,11 @@ */ #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 "exec/memop.h" -#include "sysemu/kvm.h" /*****************************************************************************/ From 585c80ad7bb1bfd62721d03b62424fb1a786f659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 30 Nov 2020 10:04:39 +0100 Subject: [PATCH 16/26] target/mips: Remove mips_def_t unused argument from mvp_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mvp_init() doesn't require any CPU definition (beside the information accessible via CPUMIPSState). Remove the unused argument. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201204222622.2743175-2-f4bug@amsat.org> --- target/mips/translate.c | 2 +- target/mips/translate_init.c.inc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index e87f472a8d..f218997f04 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -31763,7 +31763,7 @@ void cpu_mips_realize_env(CPUMIPSState *env) mmu_init(env, env->cpu_model); #endif fpu_init(env, env->cpu_model); - mvp_init(env, env->cpu_model); + mvp_init(env); } bool cpu_type_supports_cps_smp(const char *cpu_type) diff --git a/target/mips/translate_init.c.inc b/target/mips/translate_init.c.inc index 79f75ed863..5a926bc6df 100644 --- a/target/mips/translate_init.c.inc +++ b/target/mips/translate_init.c.inc @@ -989,7 +989,7 @@ static void fpu_init (CPUMIPSState *env, const mips_def_t *def) memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu)); } -static void mvp_init (CPUMIPSState *env, const mips_def_t *def) +static void mvp_init(CPUMIPSState *env) { env->mvp = g_malloc0(sizeof(CPUMIPSMVPContext)); From 17c2c320f3c216f80c2fad1f0fa9358c2ffbd0d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 2 Dec 2020 18:49:00 +0100 Subject: [PATCH 17/26] target/mips: Introduce ase_mt_available() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of accessing CP0_Config3 directly and checking the 'Multi-Threading Present' bit, introduce an helper to simplify code review. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201204222622.2743175-3-f4bug@amsat.org> --- hw/mips/cps.c | 3 +-- target/mips/cp0_helper.c | 2 +- target/mips/cpu.c | 2 +- target/mips/cpu.h | 7 +++++++ target/mips/helper.c | 2 +- target/mips/translate.c | 2 +- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/hw/mips/cps.c b/hw/mips/cps.c index 962b1b0b87..7a0d289efa 100644 --- a/hw/mips/cps.c +++ b/hw/mips/cps.c @@ -58,8 +58,7 @@ static void main_cpu_reset(void *opaque) static bool cpu_mips_itu_supported(CPUMIPSState *env) { - bool is_mt = (env->CP0_Config5 & (1 << CP0C5_VP)) || - (env->CP0_Config3 & (1 << CP0C3_MT)); + bool is_mt = (env->CP0_Config5 & (1 << CP0C5_VP)) || ase_mt_available(env); return is_mt && !kvm_enabled(); } diff --git a/target/mips/cp0_helper.c b/target/mips/cp0_helper.c index cb899fe3d7..36a92857bf 100644 --- a/target/mips/cp0_helper.c +++ b/target/mips/cp0_helper.c @@ -1164,7 +1164,7 @@ void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1) old = env->CP0_EntryHi; val = (arg1 & mask) | (old & ~mask); env->CP0_EntryHi = val; - if (env->CP0_Config3 & (1 << CP0C3_MT)) { + if (ase_mt_available(env)) { sync_c0_entryhi(env, env->current_tc); } /* If the ASID changes, flush qemu's TLB. */ diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 687e2680dd..9d7edc1ca2 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -74,7 +74,7 @@ static bool mips_cpu_has_work(CPUState *cs) } /* MIPS-MT has the ability to halt the CPU. */ - if (env->CP0_Config3 & (1 << CP0C3_MT)) { + if (ase_mt_available(env)) { /* * The QEMU model will issue an _WAKE request whenever the CPUs * should be woken up. diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 5d3b2a01c0..3ac21d0e9c 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -1289,6 +1289,13 @@ int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc); bool cpu_type_supports_cps_smp(const char *cpu_type); bool cpu_supports_isa(const CPUMIPSState *env, uint64_t isa_mask); bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa); + +/* Check presence of multi-threading ASE implementation */ +static inline bool ase_mt_available(CPUMIPSState *env) +{ + return env->CP0_Config3 & (1 << CP0C3_MT); +} + void cpu_set_exception_base(int vp_index, target_ulong address); /* addr.c */ diff --git a/target/mips/helper.c b/target/mips/helper.c index 59de58fcbc..0c65786579 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -419,7 +419,7 @@ void cpu_mips_store_status(CPUMIPSState *env, target_ulong val) tlb_flush(env_cpu(env)); } #endif - if (env->CP0_Config3 & (1 << CP0C3_MT)) { + if (ase_mt_available(env)) { sync_c0_status(env, env, env->current_tc); } else { compute_hflags(env); diff --git a/target/mips/translate.c b/target/mips/translate.c index f218997f04..ccc82abce0 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -31917,7 +31917,7 @@ void cpu_state_reset(CPUMIPSState *env) cpu_mips_store_count(env, 1); - if (env->CP0_Config3 & (1 << CP0C3_MT)) { + if (ase_mt_available(env)) { int i; /* Only TC0 on VPE 0 starts as active. */ From ecc268e7c2488c0285684fad6d04cac6a794991d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 2 Dec 2020 18:53:20 +0100 Subject: [PATCH 18/26] target/mips: Do not initialize MT registers if MT ASE absent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not initialize MT-related config registers if the MT ASE is not present. As some functions access the 'mvp' structure, we still zero-allocate it. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201204222622.2743175-4-f4bug@amsat.org> --- target/mips/translate_init.c.inc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/target/mips/translate_init.c.inc b/target/mips/translate_init.c.inc index 5a926bc6df..f72fee3b40 100644 --- a/target/mips/translate_init.c.inc +++ b/target/mips/translate_init.c.inc @@ -993,6 +993,10 @@ static void mvp_init(CPUMIPSState *env) { env->mvp = g_malloc0(sizeof(CPUMIPSMVPContext)); + if (!ase_mt_available(env)) { + return; + } + /* MVPConf1 implemented, TLB sharable, no gating storage support, programmable cache partitioning implemented, number of allocatable and shareable TLB entries, MVP has allocatable TCs, 2 VPEs From 8de0f2804676decfa82ce51ef18293523e67af32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 2 Dec 2020 18:53:09 +0100 Subject: [PATCH 19/26] hw/mips/malta: Do not initialize MT registers if MT ASE absent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not initialize MT-related config register if the MT ASE is not present. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201204222622.2743175-5-f4bug@amsat.org> --- hw/mips/malta.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 4651a1055c..f06cb90a44 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -1135,8 +1135,10 @@ static void malta_mips_config(MIPSCPU *cpu) CPUMIPSState *env = &cpu->env; CPUState *cs = CPU(cpu); - env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) | + if (ase_mt_available(env)) { + env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) | ((smp_cpus * cs->nr_threads - 1) << CP0MVPC0_PTC); + } } static void main_cpu_reset(void *opaque) From 07741e67542d061b45628a5de60637b006ca2de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 4 Dec 2020 23:16:45 +0100 Subject: [PATCH 20/26] hw/mips/malta: Rewrite CP0_MVPConf0 access using deposit() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PTC field has 8 bits, PVPE has 4. We plan to use the "hw/registerfields.h" API with MIPS CPU definitions (target/mips/cpu.h). Meanwhile we use magic 8 and 4. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201204222622.2743175-6-f4bug@amsat.org> --- hw/mips/malta.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index f06cb90a44..366f4fdfcd 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" +#include "qemu/bitops.h" #include "qemu-common.h" #include "qemu/datadir.h" #include "cpu.h" @@ -1136,8 +1137,11 @@ static void malta_mips_config(MIPSCPU *cpu) CPUState *cs = CPU(cpu); if (ase_mt_available(env)) { - env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) | - ((smp_cpus * cs->nr_threads - 1) << CP0MVPC0_PTC); + env->mvp->CP0_MVPConf0 = deposit32(env->mvp->CP0_MVPConf0, + CP0MVPC0_PTC, 8, + smp_cpus * cs->nr_threads - 1); + env->mvp->CP0_MVPConf0 = deposit32(env->mvp->CP0_MVPConf0, + CP0MVPC0_PVPE, 4, smp_cpus - 1); } } From ffa657ee70ced89168e432ace4b4b8af5a227117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 6 Dec 2020 22:03:35 +0100 Subject: [PATCH 21/26] target/mips: Extract cpu_supports*/cpu_set* translate.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move cpu_supports*() and cpu_set_exception_base() from translate.c to cpu.c. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-9-f4bug@amsat.org> --- target/mips/cpu.c | 18 ++++++++++++++++++ target/mips/translate.c | 18 ------------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 9d7edc1ca2..3024c51a21 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -315,3 +315,21 @@ bool cpu_supports_isa(const CPUMIPSState *env, uint64_t isa_mask) { return (env->cpu_model->insn_flags & isa_mask) != 0; } + +bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa) +{ + const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type)); + return (mcc->cpu_def->insn_flags & isa) != 0; +} + +bool cpu_type_supports_cps_smp(const char *cpu_type) +{ + const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type)); + return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0; +} + +void cpu_set_exception_base(int vp_index, target_ulong address) +{ + MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index)); + vp->env.exception_base = address; +} diff --git a/target/mips/translate.c b/target/mips/translate.c index ccc82abce0..84d2d44e5d 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -31766,24 +31766,6 @@ void cpu_mips_realize_env(CPUMIPSState *env) mvp_init(env); } -bool cpu_type_supports_cps_smp(const char *cpu_type) -{ - const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type)); - return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0; -} - -bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa) -{ - const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type)); - return (mcc->cpu_def->insn_flags & isa) != 0; -} - -void cpu_set_exception_base(int vp_index, target_ulong address) -{ - MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index)); - vp->env.exception_base = address; -} - void cpu_state_reset(CPUMIPSState *env) { CPUState *cs = env_cpu(env); From a10b453a52a1f5c9511a0eed164d5e89c88033e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 6 Dec 2020 22:07:34 +0100 Subject: [PATCH 22/26] target/mips: Move mips_cpu_add_definition() from helper.c to cpu.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-10-f4bug@amsat.org> --- target/mips/cpu.c | 33 +++++++++++++++++++++++++++++++++ target/mips/helper.c | 33 --------------------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 3024c51a21..c29fef29d0 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -30,6 +30,7 @@ #include "exec/exec-all.h" #include "hw/qdev-properties.h" #include "hw/qdev-clock.h" +#include "qapi/qapi-commands-machine-target.h" static void mips_cpu_set_pc(CPUState *cs, vaddr value) { @@ -299,6 +300,38 @@ static void mips_cpu_register_types(void) type_init(mips_cpu_register_types) +static void mips_cpu_add_definition(gpointer data, gpointer user_data) +{ + ObjectClass *oc = data; + CpuDefinitionInfoList **cpu_list = user_data; + CpuDefinitionInfoList *entry; + CpuDefinitionInfo *info; + const char *typename; + + typename = object_class_get_name(oc); + info = g_malloc0(sizeof(*info)); + info->name = g_strndup(typename, + strlen(typename) - strlen("-" TYPE_MIPS_CPU)); + info->q_typename = g_strdup(typename); + + entry = g_malloc0(sizeof(*entry)); + entry->value = info; + entry->next = *cpu_list; + *cpu_list = entry; +} + +CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +{ + CpuDefinitionInfoList *cpu_list = NULL; + GSList *list; + + list = object_class_get_list(TYPE_MIPS_CPU, false); + g_slist_foreach(list, mips_cpu_add_definition, &cpu_list); + g_slist_free(list); + + return cpu_list; +} + /* Could be used by generic CPU object */ MIPSCPU *mips_cpu_create_with_clock(const char *cpu_type, Clock *cpu_refclk) { diff --git a/target/mips/helper.c b/target/mips/helper.c index 0c65786579..87296fbad6 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -24,7 +24,6 @@ #include "exec/cpu_ldst.h" #include "exec/log.h" #include "hw/mips/cpudevs.h" -#include "qapi/qapi-commands-machine-target.h" enum { TLBRET_XI = -6, @@ -1500,35 +1499,3 @@ void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env, cpu_loop_exit_restore(cs, pc); } - -static void mips_cpu_add_definition(gpointer data, gpointer user_data) -{ - ObjectClass *oc = data; - CpuDefinitionInfoList **cpu_list = user_data; - CpuDefinitionInfoList *entry; - CpuDefinitionInfo *info; - const char *typename; - - typename = object_class_get_name(oc); - info = g_malloc0(sizeof(*info)); - info->name = g_strndup(typename, - strlen(typename) - strlen("-" TYPE_MIPS_CPU)); - info->q_typename = g_strdup(typename); - - entry = g_malloc0(sizeof(*entry)); - entry->value = info; - entry->next = *cpu_list; - *cpu_list = entry; -} - -CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) -{ - CpuDefinitionInfoList *cpu_list = NULL; - GSList *list; - - list = object_class_get_list(TYPE_MIPS_CPU, false); - g_slist_foreach(list, mips_cpu_add_definition, &cpu_list); - g_slist_free(list); - - return cpu_list; -} From c20cf02bbd88146ffc75c7722423b1ef6991676c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 6 Dec 2020 23:29:33 +0100 Subject: [PATCH 23/26] target/mips: Move cpu definitions, reset() and realize() to cpu.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nothing TCG specific there, move to common cpu code. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-16-f4bug@amsat.org> --- target/mips/cpu.c | 243 ++++++++++++++++++++++++++++++++++++++++ target/mips/internal.h | 4 - target/mips/translate.c | 240 --------------------------------------- 3 files changed, 243 insertions(+), 244 deletions(-) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index c29fef29d0..f2c4de7d07 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "qemu/cutils.h" +#include "qemu/qemu-print.h" #include "qapi/error.h" #include "cpu.h" #include "internal.h" @@ -30,6 +31,7 @@ #include "exec/exec-all.h" #include "hw/qdev-properties.h" #include "hw/qdev-clock.h" +#include "hw/semihosting/semihost.h" #include "qapi/qapi-commands-machine-target.h" static void mips_cpu_set_pc(CPUState *cs, vaddr value) @@ -100,6 +102,247 @@ static bool mips_cpu_has_work(CPUState *cs) return has_work; } +#include "translate_init.c.inc" + +static void cpu_mips_realize_env(CPUMIPSState *env) +{ + env->exception_base = (int32_t)0xBFC00000; + +#ifndef CONFIG_USER_ONLY + mmu_init(env, env->cpu_model); +#endif + fpu_init(env, env->cpu_model); + mvp_init(env); +} + +/* TODO QOM'ify CPU reset and remove */ +static void cpu_state_reset(CPUMIPSState *env) +{ + CPUState *cs = env_cpu(env); + + /* Reset registers to their default values */ + env->CP0_PRid = env->cpu_model->CP0_PRid; + env->CP0_Config0 = env->cpu_model->CP0_Config0; +#ifdef TARGET_WORDS_BIGENDIAN + env->CP0_Config0 |= (1 << CP0C0_BE); +#endif + env->CP0_Config1 = env->cpu_model->CP0_Config1; + env->CP0_Config2 = env->cpu_model->CP0_Config2; + env->CP0_Config3 = env->cpu_model->CP0_Config3; + env->CP0_Config4 = env->cpu_model->CP0_Config4; + env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask; + env->CP0_Config5 = env->cpu_model->CP0_Config5; + env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask; + env->CP0_Config6 = env->cpu_model->CP0_Config6; + env->CP0_Config6_rw_bitmask = env->cpu_model->CP0_Config6_rw_bitmask; + env->CP0_Config7 = env->cpu_model->CP0_Config7; + env->CP0_Config7_rw_bitmask = env->cpu_model->CP0_Config7_rw_bitmask; + env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask + << env->cpu_model->CP0_LLAddr_shift; + env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift; + env->SYNCI_Step = env->cpu_model->SYNCI_Step; + env->CCRes = env->cpu_model->CCRes; + env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask; + env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask; + env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl; + env->current_tc = 0; + env->SEGBITS = env->cpu_model->SEGBITS; + env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1); +#if defined(TARGET_MIPS64) + if (env->cpu_model->insn_flags & ISA_MIPS3) { + env->SEGMask |= 3ULL << 62; + } +#endif + env->PABITS = env->cpu_model->PABITS; + env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask; + env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0; + env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask; + env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1; + env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask; + env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2; + env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask; + env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3; + env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask; + env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4; + env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask; + env->CP0_PageGrain = env->cpu_model->CP0_PageGrain; + env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask; + env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0; + env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask; + env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31; + env->msair = env->cpu_model->MSAIR; + env->insn_flags = env->cpu_model->insn_flags; + +#if defined(CONFIG_USER_ONLY) + env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU); +# ifdef TARGET_MIPS64 + /* Enable 64-bit register mode. */ + env->CP0_Status |= (1 << CP0St_PX); +# endif +# ifdef TARGET_ABI_MIPSN64 + /* Enable 64-bit address mode. */ + env->CP0_Status |= (1 << CP0St_UX); +# endif + /* + * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR + * hardware registers. + */ + env->CP0_HWREna |= 0x0000000F; + if (env->CP0_Config1 & (1 << CP0C1_FP)) { + env->CP0_Status |= (1 << CP0St_CU1); + } + if (env->CP0_Config3 & (1 << CP0C3_DSPP)) { + env->CP0_Status |= (1 << CP0St_MX); + } +# if defined(TARGET_MIPS64) + /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */ + if ((env->CP0_Config1 & (1 << CP0C1_FP)) && + (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) { + env->CP0_Status |= (1 << CP0St_FR); + } +# endif +#else /* !CONFIG_USER_ONLY */ + if (env->hflags & MIPS_HFLAG_BMASK) { + /* + * If the exception was raised from a delay slot, + * come back to the jump. + */ + env->CP0_ErrorEPC = (env->active_tc.PC + - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4)); + } else { + env->CP0_ErrorEPC = env->active_tc.PC; + } + env->active_tc.PC = env->exception_base; + env->CP0_Random = env->tlb->nb_tlb - 1; + env->tlb->tlb_in_use = env->tlb->nb_tlb; + env->CP0_Wired = 0; + env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId; + env->CP0_EBase = (cs->cpu_index & 0x3FF); + if (mips_um_ksegs_enabled()) { + env->CP0_EBase |= 0x40000000; + } else { + env->CP0_EBase |= (int32_t)0x80000000; + } + if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) { + env->CP0_CMGCRBase = 0x1fbf8000 >> 4; + } + env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ? + 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff; + env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); + /* + * Vectored interrupts not implemented, timer on int 7, + * no performance counters. + */ + env->CP0_IntCtl = 0xe0000000; + { + int i; + + for (i = 0; i < 7; i++) { + env->CP0_WatchLo[i] = 0; + env->CP0_WatchHi[i] = 0x80000000; + } + env->CP0_WatchLo[7] = 0; + env->CP0_WatchHi[7] = 0; + } + /* Count register increments in debug mode, EJTAG version 1 */ + env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); + + cpu_mips_store_count(env, 1); + + if (ase_mt_available(env)) { + int i; + + /* Only TC0 on VPE 0 starts as active. */ + for (i = 0; i < ARRAY_SIZE(env->tcs); i++) { + env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE; + env->tcs[i].CP0_TCHalt = 1; + } + env->active_tc.CP0_TCHalt = 1; + cs->halted = 1; + + if (cs->cpu_index == 0) { + /* VPE0 starts up enabled. */ + env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP); + env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA); + + /* TC0 starts up unhalted. */ + cs->halted = 0; + env->active_tc.CP0_TCHalt = 0; + env->tcs[0].CP0_TCHalt = 0; + /* With thread 0 active. */ + env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A); + env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A); + } + } + + /* + * Configure default legacy segmentation control. We use this regardless of + * whether segmentation control is presented to the guest. + */ + /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */ + env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM); + /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */ + env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16; + /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */ + env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) | + (2 << CP0SC_C); + /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */ + env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) | + (3 << CP0SC_C)) << 16; + /* USeg (seg4 0x40000000..0x7FFFFFFF) */ + env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) | + (1 << CP0SC_EU) | (2 << CP0SC_C); + /* USeg (seg5 0x00000000..0x3FFFFFFF) */ + env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) | + (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16; + /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */ + env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM); +#endif /* !CONFIG_USER_ONLY */ + if ((env->insn_flags & ISA_MIPS32R6) && + (env->active_fpu.fcr0 & (1 << FCR0_F64))) { + /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */ + env->CP0_Status |= (1 << CP0St_FR); + } + + if (env->insn_flags & ISA_MIPS32R6) { + /* PTW = 1 */ + env->CP0_PWSize = 0x40; + /* GDI = 12 */ + /* UDI = 12 */ + /* MDI = 12 */ + /* PRI = 12 */ + /* PTEI = 2 */ + env->CP0_PWField = 0x0C30C302; + } else { + /* GDI = 0 */ + /* UDI = 0 */ + /* MDI = 0 */ + /* PRI = 0 */ + /* PTEI = 2 */ + env->CP0_PWField = 0x02; + } + + if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) { + /* microMIPS on reset when Config3.ISA is 3 */ + env->hflags |= MIPS_HFLAG_M16; + } + + /* MSA */ + if (env->CP0_Config3 & (1 << CP0C3_MSAP)) { + msa_reset(env); + } + + compute_hflags(env); + restore_fp_status(env); + restore_pamask(env); + cs->exception_index = EXCP_NONE; + + if (semihosting_get_argc()) { + /* UHI interface can be used to obtain argc and argv */ + env->active_tc.gpr[4] = -1; + } +} + static void mips_cpu_reset(DeviceState *dev) { CPUState *s = CPU(dev); diff --git a/target/mips/internal.h b/target/mips/internal.h index bcd3d857ab..0515966469 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -207,10 +207,6 @@ static inline bool cpu_mips_hw_interrupts_pending(CPUMIPSState *env) void mips_tcg_init(void); -/* TODO QOM'ify CPU reset and remove */ -void cpu_state_reset(CPUMIPSState *s); -void cpu_mips_realize_env(CPUMIPSState *env); - /* cp0_timer.c */ uint32_t cpu_mips_get_count(CPUMIPSState *env); void cpu_mips_store_count(CPUMIPSState *env, uint32_t value); diff --git a/target/mips/translate.c b/target/mips/translate.c index 84d2d44e5d..19933b7868 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -31753,246 +31753,6 @@ void mips_tcg_init(void) #endif } -#include "translate_init.c.inc" - -void cpu_mips_realize_env(CPUMIPSState *env) -{ - env->exception_base = (int32_t)0xBFC00000; - -#ifndef CONFIG_USER_ONLY - mmu_init(env, env->cpu_model); -#endif - fpu_init(env, env->cpu_model); - mvp_init(env); -} - -void cpu_state_reset(CPUMIPSState *env) -{ - CPUState *cs = env_cpu(env); - - /* Reset registers to their default values */ - env->CP0_PRid = env->cpu_model->CP0_PRid; - env->CP0_Config0 = env->cpu_model->CP0_Config0; -#ifdef TARGET_WORDS_BIGENDIAN - env->CP0_Config0 |= (1 << CP0C0_BE); -#endif - env->CP0_Config1 = env->cpu_model->CP0_Config1; - env->CP0_Config2 = env->cpu_model->CP0_Config2; - env->CP0_Config3 = env->cpu_model->CP0_Config3; - env->CP0_Config4 = env->cpu_model->CP0_Config4; - env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask; - env->CP0_Config5 = env->cpu_model->CP0_Config5; - env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask; - env->CP0_Config6 = env->cpu_model->CP0_Config6; - env->CP0_Config6_rw_bitmask = env->cpu_model->CP0_Config6_rw_bitmask; - env->CP0_Config7 = env->cpu_model->CP0_Config7; - env->CP0_Config7_rw_bitmask = env->cpu_model->CP0_Config7_rw_bitmask; - env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask - << env->cpu_model->CP0_LLAddr_shift; - env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift; - env->SYNCI_Step = env->cpu_model->SYNCI_Step; - env->CCRes = env->cpu_model->CCRes; - env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask; - env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask; - env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl; - env->current_tc = 0; - env->SEGBITS = env->cpu_model->SEGBITS; - env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1); -#if defined(TARGET_MIPS64) - if (env->cpu_model->insn_flags & ISA_MIPS3) { - env->SEGMask |= 3ULL << 62; - } -#endif - env->PABITS = env->cpu_model->PABITS; - env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask; - env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0; - env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask; - env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1; - env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask; - env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2; - env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask; - env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3; - env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask; - env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4; - env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask; - env->CP0_PageGrain = env->cpu_model->CP0_PageGrain; - env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask; - env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0; - env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask; - env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31; - env->msair = env->cpu_model->MSAIR; - env->insn_flags = env->cpu_model->insn_flags; - -#if defined(CONFIG_USER_ONLY) - env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU); -# ifdef TARGET_MIPS64 - /* Enable 64-bit register mode. */ - env->CP0_Status |= (1 << CP0St_PX); -# endif -# ifdef TARGET_ABI_MIPSN64 - /* Enable 64-bit address mode. */ - env->CP0_Status |= (1 << CP0St_UX); -# endif - /* - * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR - * hardware registers. - */ - env->CP0_HWREna |= 0x0000000F; - if (env->CP0_Config1 & (1 << CP0C1_FP)) { - env->CP0_Status |= (1 << CP0St_CU1); - } - if (env->CP0_Config3 & (1 << CP0C3_DSPP)) { - env->CP0_Status |= (1 << CP0St_MX); - } -# if defined(TARGET_MIPS64) - /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */ - if ((env->CP0_Config1 & (1 << CP0C1_FP)) && - (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) { - env->CP0_Status |= (1 << CP0St_FR); - } -# endif -#else - if (env->hflags & MIPS_HFLAG_BMASK) { - /* - * If the exception was raised from a delay slot, - * come back to the jump. - */ - env->CP0_ErrorEPC = (env->active_tc.PC - - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4)); - } else { - env->CP0_ErrorEPC = env->active_tc.PC; - } - env->active_tc.PC = env->exception_base; - env->CP0_Random = env->tlb->nb_tlb - 1; - env->tlb->tlb_in_use = env->tlb->nb_tlb; - env->CP0_Wired = 0; - env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId; - env->CP0_EBase = (cs->cpu_index & 0x3FF); - if (mips_um_ksegs_enabled()) { - env->CP0_EBase |= 0x40000000; - } else { - env->CP0_EBase |= (int32_t)0x80000000; - } - if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) { - env->CP0_CMGCRBase = 0x1fbf8000 >> 4; - } - env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ? - 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff; - env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); - /* - * Vectored interrupts not implemented, timer on int 7, - * no performance counters. - */ - env->CP0_IntCtl = 0xe0000000; - { - int i; - - for (i = 0; i < 7; i++) { - env->CP0_WatchLo[i] = 0; - env->CP0_WatchHi[i] = 0x80000000; - } - env->CP0_WatchLo[7] = 0; - env->CP0_WatchHi[7] = 0; - } - /* Count register increments in debug mode, EJTAG version 1 */ - env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); - - cpu_mips_store_count(env, 1); - - if (ase_mt_available(env)) { - int i; - - /* Only TC0 on VPE 0 starts as active. */ - for (i = 0; i < ARRAY_SIZE(env->tcs); i++) { - env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE; - env->tcs[i].CP0_TCHalt = 1; - } - env->active_tc.CP0_TCHalt = 1; - cs->halted = 1; - - if (cs->cpu_index == 0) { - /* VPE0 starts up enabled. */ - env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP); - env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA); - - /* TC0 starts up unhalted. */ - cs->halted = 0; - env->active_tc.CP0_TCHalt = 0; - env->tcs[0].CP0_TCHalt = 0; - /* With thread 0 active. */ - env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A); - env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A); - } - } - - /* - * Configure default legacy segmentation control. We use this regardless of - * whether segmentation control is presented to the guest. - */ - /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */ - env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM); - /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */ - env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16; - /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */ - env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) | - (2 << CP0SC_C); - /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */ - env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) | - (3 << CP0SC_C)) << 16; - /* USeg (seg4 0x40000000..0x7FFFFFFF) */ - env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) | - (1 << CP0SC_EU) | (2 << CP0SC_C); - /* USeg (seg5 0x00000000..0x3FFFFFFF) */ - env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) | - (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16; - /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */ - env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM); -#endif - if ((env->insn_flags & ISA_MIPS32R6) && - (env->active_fpu.fcr0 & (1 << FCR0_F64))) { - /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */ - env->CP0_Status |= (1 << CP0St_FR); - } - - if (env->insn_flags & ISA_MIPS32R6) { - /* PTW = 1 */ - env->CP0_PWSize = 0x40; - /* GDI = 12 */ - /* UDI = 12 */ - /* MDI = 12 */ - /* PRI = 12 */ - /* PTEI = 2 */ - env->CP0_PWField = 0x0C30C302; - } else { - /* GDI = 0 */ - /* UDI = 0 */ - /* MDI = 0 */ - /* PRI = 0 */ - /* PTEI = 2 */ - env->CP0_PWField = 0x02; - } - - if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) { - /* microMIPS on reset when Config3.ISA is 3 */ - env->hflags |= MIPS_HFLAG_M16; - } - - /* MSA */ - if (env->CP0_Config3 & (1 << CP0C3_MSAP)) { - msa_reset(env); - } - - compute_hflags(env); - restore_fp_status(env); - restore_pamask(env); - cs->exception_index = EXCP_NONE; - - if (semihosting_get_argc()) { - /* UHI interface can be used to obtain argc and argv */ - env->active_tc.gpr[4] = -1; - } -} - void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, target_ulong *data) { From 7b884bf51e7feb6aee2a6293aee0c40a07bf8080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 6 Dec 2020 23:49:07 +0100 Subject: [PATCH 24/26] target/mips: Inline cpu_mips_realize_env() in mips_cpu_realizefn() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-17-f4bug@amsat.org> --- target/mips/cpu.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index f2c4de7d07..aadc6f8e74 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -104,17 +104,6 @@ static bool mips_cpu_has_work(CPUState *cs) #include "translate_init.c.inc" -static void cpu_mips_realize_env(CPUMIPSState *env) -{ - env->exception_base = (int32_t)0xBFC00000; - -#ifndef CONFIG_USER_ONLY - mmu_init(env, env->cpu_model); -#endif - fpu_init(env, env->cpu_model); - mvp_init(env); -} - /* TODO QOM'ify CPU reset and remove */ static void cpu_state_reset(CPUMIPSState *env) { @@ -400,6 +389,7 @@ static void mips_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); MIPSCPU *cpu = MIPS_CPU(dev); + CPUMIPSState *env = &cpu->env; MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(dev); Error *local_err = NULL; @@ -423,7 +413,13 @@ static void mips_cpu_realizefn(DeviceState *dev, Error **errp) return; } - cpu_mips_realize_env(&cpu->env); + env->exception_base = (int32_t)0xBFC00000; + +#ifndef CONFIG_USER_ONLY + mmu_init(env, env->cpu_model); +#endif + fpu_init(env, env->cpu_model); + mvp_init(env); cpu_reset(cs); qemu_init_vcpu(cs); From 98cf80baa75fb8d3d6516e39895247c07a6f83ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 5 Dec 2020 18:34:51 +0100 Subject: [PATCH 25/26] target/mips: Remove unused headers from fpu_helper.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201206233949.3783184-4-f4bug@amsat.org> --- target/mips/fpu_helper.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c index 020b768e87..956e3417d0 100644 --- a/target/mips/fpu_helper.c +++ b/target/mips/fpu_helper.c @@ -21,15 +21,11 @@ */ #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 "exec/memop.h" -#include "sysemu/kvm.h" #include "fpu/softfloat.h" From 3533ee301c46620fd5699cb97f2d4bd194fe0c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 22 Nov 2020 18:05:25 +0100 Subject: [PATCH 26/26] target/mips: Use FloatRoundMode enum for FCR31 modes conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the FloatRoundMode enum type introduced in commit 3dede407cc6 ("softfloat: Name rounding mode enum") instead of 'unsigned int'. Suggested-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20201123204448.3260804-2-f4bug@amsat.org> --- target/mips/fpu_helper.c | 2 +- target/mips/internal.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c index 956e3417d0..bdb65065ee 100644 --- a/target/mips/fpu_helper.c +++ b/target/mips/fpu_helper.c @@ -38,7 +38,7 @@ #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL /* convert MIPS rounding mode in FCR31 to IEEE library */ -unsigned int ieee_rm[] = { +const FloatRoundMode ieee_rm[4] = { float_round_nearest_even, float_round_to_zero, float_round_up, diff --git a/target/mips/internal.h b/target/mips/internal.h index 0515966469..e4d2d9f44f 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -223,7 +223,8 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size, uint32_t float_class_s(uint32_t arg, float_status *fst); uint64_t float_class_d(uint64_t arg, float_status *fst); -extern unsigned int ieee_rm[]; +extern const FloatRoundMode ieee_rm[4]; + void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask); static inline void restore_rounding_mode(CPUMIPSState *env)