diff --git a/app-emulation/qemu/files/qemu-2.4-mips-fix-mtc0.patch b/app-emulation/qemu/files/qemu-2.4-mips-fix-mtc0.patch new file mode 100644 index 0000000..07c2be5 --- /dev/null +++ b/app-emulation/qemu/files/qemu-2.4-mips-fix-mtc0.patch @@ -0,0 +1,78 @@ +From d54a299b83a07642c85a22bfe19b69ca4def9ec4 Mon Sep 17 00:00:00 2001 +From: Leon Alrae +Date: Wed, 9 Sep 2015 12:44:25 +0100 +Subject: [PATCH] target-mips: correct MTC0 instruction on MIPS64 + +MTC0 on a 64-bit processor should move entire 64-bit GPR content to CP0 +register. + +Signed-off-by: Leon Alrae +Reviewed-by: Aurelien Jarno +--- + target-mips/translate.c | 18 +++++++----------- + 1 files changed, 7 insertions(+), 11 deletions(-) + +diff --git a/target-mips/translate.c b/target-mips/translate.c +index 0883782..a59b670 100644 +--- a/target-mips/translate.c ++++ b/target-mips/translate.c +@@ -4765,12 +4765,6 @@ static inline void gen_mtc0_store32 (TCGv arg, target_ulong off) + tcg_temp_free_i32(t0); + } + +-static inline void gen_mtc0_store64 (TCGv arg, target_ulong off) +-{ +- tcg_gen_ext32s_tl(arg, arg); +- tcg_gen_st_tl(arg, cpu_env, off); +-} +- + static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) + { + const char *rn = "invalid"; +@@ -5629,12 +5623,14 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) + break; + case 5: + CP0_CHECK(ctx->insn_flags & ASE_MT); +- gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); ++ tcg_gen_st_tl(arg, cpu_env, ++ offsetof(CPUMIPSState, CP0_VPESchedule)); + rn = "VPESchedule"; + break; + case 6: + CP0_CHECK(ctx->insn_flags & ASE_MT); +- gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); ++ tcg_gen_st_tl(arg, cpu_env, ++ offsetof(CPUMIPSState, CP0_VPEScheFBack)); + rn = "VPEScheFBack"; + break; + case 7: +@@ -5884,7 +5880,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) + case 14: + switch (sel) { + case 0: +- gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC)); ++ tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); + rn = "EPC"; + break; + default: +@@ -6057,7 +6053,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) + switch (sel) { + case 0: + /* EJTAG support */ +- gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC)); ++ tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); + rn = "DEPC"; + break; + default: +@@ -6160,7 +6156,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) + case 30: + switch (sel) { + case 0: +- gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC)); ++ tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); + rn = "ErrorEPC"; + break; + default: +-- +1.7.0.4 + diff --git a/app-emulation/qemu/files/qemu-2.4-mips-fix-rdhwr.patch b/app-emulation/qemu/files/qemu-2.4-mips-fix-rdhwr.patch new file mode 100644 index 0000000..998ec66 --- /dev/null +++ b/app-emulation/qemu/files/qemu-2.4-mips-fix-rdhwr.patch @@ -0,0 +1,44 @@ +From cdfcad788394ff53e317043e07b8e34f4987c659 Mon Sep 17 00:00:00 2001 +From: Alex Smith +Date: Tue, 8 Sep 2015 11:34:11 +0100 +Subject: [PATCH 1/1] target-mips: Fix RDHWR on CP0.Count + +For RDHWR on the CP0.Count register, env->CP0_Count was being returned. +This value is a delta against the QEMU_CLOCK_VIRTUAL clock, not the +correct current value of CP0.Count. Use cpu_mips_get_count() instead. + +Signed-off-by: Alex Smith +Cc: Aurelien Jarno +Cc: Leon Alrae +Reviewed-by: Leon Alrae +Reviewed-by: Aurelien Jarno +Signed-off-by: Leon Alrae +--- + target-mips/op_helper.c | 9 +++++++-- + 1 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c +index 1aa9e3c..94de108 100644 +--- a/target-mips/op_helper.c ++++ b/target-mips/op_helper.c +@@ -2184,10 +2184,15 @@ target_ulong helper_rdhwr_synci_step(CPUMIPSState *env) + target_ulong helper_rdhwr_cc(CPUMIPSState *env) + { + if ((env->hflags & MIPS_HFLAG_CP0) || +- (env->CP0_HWREna & (1 << 2))) ++ (env->CP0_HWREna & (1 << 2))) { ++#ifdef CONFIG_USER_ONLY + return env->CP0_Count; +- else ++#else ++ return (int32_t)cpu_mips_get_count(env); ++#endif ++ } else { + helper_raise_exception(env, EXCP_RI); ++ } + + return 0; + } +-- +1.7.0.4 + diff --git a/app-emulation/qemu/files/qemu-2.4-mips-move-interrupts-new-func.patch b/app-emulation/qemu/files/qemu-2.4-mips-move-interrupts-new-func.patch new file mode 100644 index 0000000..0ea5df5 --- /dev/null +++ b/app-emulation/qemu/files/qemu-2.4-mips-move-interrupts-new-func.patch @@ -0,0 +1,89 @@ +Pending upstream inclusion + +Link: https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg03573.html +Patchwork: https://patchwork.ozlabs.org/patch/517392/ +X-Gentoo-Bug: 563162 +X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=563162 + +Signed-off-by: Markos Chandras + +diff --git a/target-mips/cpu.c b/target-mips/cpu.c +index 4027d0f..144eea9 100644 +--- a/target-mips/cpu.c ++++ b/target-mips/cpu.c +@@ -58,7 +58,9 @@ static bool mips_cpu_has_work(CPUState *cs) + check for interrupts that can be taken. */ + if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && + cpu_mips_hw_interrupts_pending(env)) { +- has_work = true; ++ if (cpu_mips_hw_interrupts_enabled(env)) { ++ has_work = true; ++ } + } + + /* MIPS-MT has the ability to halt the CPU. */ +diff --git a/target-mips/cpu.h b/target-mips/cpu.h +index c91883d..210370e 100644 +--- a/target-mips/cpu.h ++++ b/target-mips/cpu.h +@@ -639,23 +639,24 @@ static inline int cpu_mmu_index (CPUMIPSState *env) + return env->hflags & MIPS_HFLAG_KSU; + } + +-static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env) ++static inline bool cpu_mips_hw_interrupts_enabled(CPUMIPSState *env) + { +- int32_t pending; +- int32_t status; +- int r; +- +- if (!(env->CP0_Status & (1 << CP0St_IE)) || +- (env->CP0_Status & (1 << CP0St_EXL)) || +- (env->CP0_Status & (1 << CP0St_ERL)) || ++ return (env->CP0_Status & (1 << CP0St_IE)) && ++ !(env->CP0_Status & (1 << CP0St_EXL)) && ++ !(env->CP0_Status & (1 << CP0St_ERL)) && ++ !(env->hflags & MIPS_HFLAG_DM) && + /* Note that the TCStatus IXMT field is initialized to zero, + and only MT capable cores can set it to one. So we don't + need to check for MT capabilities here. */ +- (env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT)) || +- (env->hflags & MIPS_HFLAG_DM)) { +- /* Interrupts are disabled */ +- return 0; +- } ++ !(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT)); ++} ++ ++/* Check if there is pending and not masked out interrupt */ ++static inline bool cpu_mips_hw_interrupts_pending(CPUMIPSState *env) ++{ ++ int32_t pending; ++ int32_t status; ++ bool r; + + pending = env->CP0_Cause & CP0Ca_IP_mask; + status = env->CP0_Status & CP0Ca_IP_mask; +@@ -669,7 +670,7 @@ static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env) + /* A MIPS configured with compatibility or VInt (Vectored Interrupts) + treats the pending lines as individual interrupt lines, the status + lines are individual masks. */ +- r = pending & status; ++ r = (pending & status) != 0; + } + return r; + } +diff --git a/target-mips/helper.c b/target-mips/helper.c +index 01c4461..2d86323 100644 +--- a/target-mips/helper.c ++++ b/target-mips/helper.c +@@ -759,7 +759,8 @@ bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request) + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; + +- if (cpu_mips_hw_interrupts_pending(env)) { ++ if (cpu_mips_hw_interrupts_enabled(env) && ++ cpu_mips_hw_interrupts_pending(env)) { + /* Raise it */ + cs->exception_index = EXCP_EXT_INTERRUPT; + env->error_code = 0; diff --git a/app-emulation/qemu/files/qemu-2.4-mips-wake-up-on-irq.patch b/app-emulation/qemu/files/qemu-2.4-mips-wake-up-on-irq.patch new file mode 100644 index 0000000..559a4af --- /dev/null +++ b/app-emulation/qemu/files/qemu-2.4-mips-wake-up-on-irq.patch @@ -0,0 +1,29 @@ +Pending upstream inclusion + +Link: https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg03572.html +Patchwork: https://patchwork.ozlabs.org/patch/517391/ +X-Gentoo-Bug: 563162 +X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=563162 + +Signed-off-by: Markos Chandras +diff --git a/target-mips/cpu.c b/target-mips/cpu.c +index 144eea9..cbeca04 100644 +--- a/target-mips/cpu.c ++++ b/target-mips/cpu.c +@@ -53,12 +53,13 @@ static bool mips_cpu_has_work(CPUState *cs) + CPUMIPSState *env = &cpu->env; + bool has_work = false; + +- /* It is implementation dependent if non-enabled interrupts +- wake-up the CPU, however most of the implementations only ++ /* Prior to MIPS Release 6 it is implementation dependent if non-enabled ++ interrupts wake-up the CPU, however most of the implementations only + check for interrupts that can be taken. */ + if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && + cpu_mips_hw_interrupts_pending(env)) { +- if (cpu_mips_hw_interrupts_enabled(env)) { ++ if (cpu_mips_hw_interrupts_enabled(env) || ++ (env->insn_flags & ISA_MIPS32R6)) { + has_work = true; + } + } diff --git a/app-emulation/qemu/qemu-2.4.0.1.ebuild b/app-emulation/qemu/qemu-2.4.0.1-r1.ebuild similarity index 99% rename from app-emulation/qemu/qemu-2.4.0.1.ebuild rename to app-emulation/qemu/qemu-2.4.0.1-r1.ebuild index 019794c..2d793e9 100644 --- a/app-emulation/qemu/qemu-2.4.0.1.ebuild +++ b/app-emulation/qemu/qemu-2.4.0.1-r1.ebuild @@ -310,6 +310,11 @@ src_prepare() { EPATCH_FORCE=yes EPATCH_SUFFIX="patch" EPATCH_SOURCE="${S}/patches" \ epatch + # MIPS specific fixes. Bug #563162 + for x in "${FILESDIR}"/${PN}-2.4-mips-*; do + epatch "${x}" + done + # Fix ld and objcopy being called directly tc-export AR LD OBJCOPY