aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/include
diff options
context:
space:
mode:
authorLeonid Yegoshin <Leonid.Yegoshin@imgtec.com>2014-12-03 10:47:03 -0500
committerMarkos Chandras <markos.chandras@imgtec.com>2015-02-17 10:37:37 -0500
commitb0a668fb2038d846a466c7a16a358d874002b697 (patch)
tree78e1a41109308a34e08dd552ddf6834f085d288c /arch/mips/include
parentb55b9e271544a23ca23b7ca3a87baf6329fcb341 (diff)
MIPS: kernel: mips-r2-to-r6-emul: Add R2 emulator for MIPS R6
MIPS R6 removed quite a few R2 instructions. However, there is plenty of <R6 userland code so we add an in-kernel emulator so we can still be able to execute all R2 userland out there. The emulator comes with a handy debugfs under /mips/ directory (r2-emul-stats) to provide some basic statistics of the instructions that are being emulated. Below are some statistics from booting a minimal buildroot image: Instruction Total BDslot ------------------------------ movs 236969 0 hilo 56686 0 muls 55279 0 divs 10941 0 dsps 0 0 bops 1 0 traps 0 0 fpus 0 0 loads 214981 17 stores 103364 0 llsc 56898 0 dsemul 150418 0 jr 370158 bltzl 43 bgezl 1594 bltzll 0 bgezll 0 bltzal 39 bgezal 39 beql 14503 bnel 138741 blezl 0 bgtzl 3988 Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Diffstat (limited to 'arch/mips/include')
-rw-r--r--arch/mips/include/asm/branch.h3
-rw-r--r--arch/mips/include/asm/mips-r2-to-r6-emul.h96
2 files changed, 96 insertions, 3 deletions
diff --git a/arch/mips/include/asm/branch.h b/arch/mips/include/asm/branch.h
index 2894ea58454d..de781cf54bc7 100644
--- a/arch/mips/include/asm/branch.h
+++ b/arch/mips/include/asm/branch.h
@@ -13,9 +13,6 @@
13#include <asm/ptrace.h> 13#include <asm/ptrace.h>
14#include <asm/inst.h> 14#include <asm/inst.h>
15 15
16static int mipsr2_emulation = 0;
17#define NO_R6EMU (cpu_has_mips_r6 && !mipsr2_emulation)
18
19extern int __isa_exception_epc(struct pt_regs *regs); 16extern int __isa_exception_epc(struct pt_regs *regs);
20extern int __compute_return_epc(struct pt_regs *regs); 17extern int __compute_return_epc(struct pt_regs *regs);
21extern int __compute_return_epc_for_insn(struct pt_regs *regs, 18extern int __compute_return_epc_for_insn(struct pt_regs *regs,
diff --git a/arch/mips/include/asm/mips-r2-to-r6-emul.h b/arch/mips/include/asm/mips-r2-to-r6-emul.h
new file mode 100644
index 000000000000..60570f2c3ba2
--- /dev/null
+++ b/arch/mips/include/asm/mips-r2-to-r6-emul.h
@@ -0,0 +1,96 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 2014 Imagination Technologies Ltd.
7 * Author: Markos Chandras <markos.chandras@imgtec.com>
8 */
9
10#ifndef __ASM_MIPS_R2_TO_R6_EMUL_H
11#define __ASM_MIPS_R2_TO_R6_EMUL_H
12
13struct mips_r2_emulator_stats {
14 u64 movs;
15 u64 hilo;
16 u64 muls;
17 u64 divs;
18 u64 dsps;
19 u64 bops;
20 u64 traps;
21 u64 fpus;
22 u64 loads;
23 u64 stores;
24 u64 llsc;
25 u64 dsemul;
26};
27
28struct mips_r2br_emulator_stats {
29 u64 jrs;
30 u64 bltzl;
31 u64 bgezl;
32 u64 bltzll;
33 u64 bgezll;
34 u64 bltzall;
35 u64 bgezall;
36 u64 bltzal;
37 u64 bgezal;
38 u64 beql;
39 u64 bnel;
40 u64 blezl;
41 u64 bgtzl;
42};
43
44#ifdef CONFIG_DEBUG_FS
45
46#define MIPS_R2_STATS(M) \
47do { \
48 u32 nir; \
49 int err; \
50 \
51 preempt_disable(); \
52 __this_cpu_inc(mipsr2emustats.M); \
53 err = __get_user(nir, (u32 __user *)regs->cp0_epc); \
54 if (!err) { \
55 if (nir == BREAK_MATH) \
56 __this_cpu_inc(mipsr2bdemustats.M); \
57 } \
58 preempt_enable(); \
59} while (0)
60
61#define MIPS_R2BR_STATS(M) \
62do { \
63 preempt_disable(); \
64 __this_cpu_inc(mipsr2bremustats.M); \
65 preempt_enable(); \
66} while (0)
67
68#else
69
70#define MIPS_R2_STATS(M) do { } while (0)
71#define MIPS_R2BR_STATS(M) do { } while (0)
72
73#endif /* CONFIG_DEBUG_FS */
74
75struct r2_decoder_table {
76 u32 mask;
77 u32 code;
78 int (*func)(struct pt_regs *regs, u32 inst);
79};
80
81
82extern void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
83 const char *str);
84
85#ifndef CONFIG_MIPSR2_TO_R6_EMULATOR
86static int mipsr2_emulation;
87static __maybe_unused int mipsr2_decoder(struct pt_regs *regs, u32 inst) { return 0; };
88#else
89/* MIPS R2 Emulator ON/OFF */
90extern int mipsr2_emulation;
91extern int mipsr2_decoder(struct pt_regs *regs, u32 inst);
92#endif /* CONFIG_MIPSR2_TO_R6_EMULATOR */
93
94#define NO_R6EMU (cpu_has_mips_r6 && !mipsr2_emulation)
95
96#endif /* __ASM_MIPS_R2_TO_R6_EMUL_H */