mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
b0a668fb20
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>
97 lines
2.0 KiB
C
97 lines
2.0 KiB
C
/*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file "COPYING" in the main directory of this archive
|
|
* for more details.
|
|
*
|
|
* Copyright (c) 2014 Imagination Technologies Ltd.
|
|
* Author: Markos Chandras <markos.chandras@imgtec.com>
|
|
*/
|
|
|
|
#ifndef __ASM_MIPS_R2_TO_R6_EMUL_H
|
|
#define __ASM_MIPS_R2_TO_R6_EMUL_H
|
|
|
|
struct mips_r2_emulator_stats {
|
|
u64 movs;
|
|
u64 hilo;
|
|
u64 muls;
|
|
u64 divs;
|
|
u64 dsps;
|
|
u64 bops;
|
|
u64 traps;
|
|
u64 fpus;
|
|
u64 loads;
|
|
u64 stores;
|
|
u64 llsc;
|
|
u64 dsemul;
|
|
};
|
|
|
|
struct mips_r2br_emulator_stats {
|
|
u64 jrs;
|
|
u64 bltzl;
|
|
u64 bgezl;
|
|
u64 bltzll;
|
|
u64 bgezll;
|
|
u64 bltzall;
|
|
u64 bgezall;
|
|
u64 bltzal;
|
|
u64 bgezal;
|
|
u64 beql;
|
|
u64 bnel;
|
|
u64 blezl;
|
|
u64 bgtzl;
|
|
};
|
|
|
|
#ifdef CONFIG_DEBUG_FS
|
|
|
|
#define MIPS_R2_STATS(M) \
|
|
do { \
|
|
u32 nir; \
|
|
int err; \
|
|
\
|
|
preempt_disable(); \
|
|
__this_cpu_inc(mipsr2emustats.M); \
|
|
err = __get_user(nir, (u32 __user *)regs->cp0_epc); \
|
|
if (!err) { \
|
|
if (nir == BREAK_MATH) \
|
|
__this_cpu_inc(mipsr2bdemustats.M); \
|
|
} \
|
|
preempt_enable(); \
|
|
} while (0)
|
|
|
|
#define MIPS_R2BR_STATS(M) \
|
|
do { \
|
|
preempt_disable(); \
|
|
__this_cpu_inc(mipsr2bremustats.M); \
|
|
preempt_enable(); \
|
|
} while (0)
|
|
|
|
#else
|
|
|
|
#define MIPS_R2_STATS(M) do { } while (0)
|
|
#define MIPS_R2BR_STATS(M) do { } while (0)
|
|
|
|
#endif /* CONFIG_DEBUG_FS */
|
|
|
|
struct r2_decoder_table {
|
|
u32 mask;
|
|
u32 code;
|
|
int (*func)(struct pt_regs *regs, u32 inst);
|
|
};
|
|
|
|
|
|
extern void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
|
|
const char *str);
|
|
|
|
#ifndef CONFIG_MIPSR2_TO_R6_EMULATOR
|
|
static int mipsr2_emulation;
|
|
static __maybe_unused int mipsr2_decoder(struct pt_regs *regs, u32 inst) { return 0; };
|
|
#else
|
|
/* MIPS R2 Emulator ON/OFF */
|
|
extern int mipsr2_emulation;
|
|
extern int mipsr2_decoder(struct pt_regs *regs, u32 inst);
|
|
#endif /* CONFIG_MIPSR2_TO_R6_EMULATOR */
|
|
|
|
#define NO_R6EMU (cpu_has_mips_r6 && !mipsr2_emulation)
|
|
|
|
#endif /* __ASM_MIPS_R2_TO_R6_EMUL_H */
|