48 lines
1.4 KiB
C
48 lines
1.4 KiB
C
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||
|
|
||
|
#ifndef _RISCV_KERNEL_PROBES_SIMULATE_INSN_H
|
||
|
#define _RISCV_KERNEL_PROBES_SIMULATE_INSN_H
|
||
|
|
||
|
#define __RISCV_INSN_FUNCS(name, mask, val) \
|
||
|
static __always_inline bool riscv_insn_is_##name(probe_opcode_t code) \
|
||
|
{ \
|
||
|
BUILD_BUG_ON(~(mask) & (val)); \
|
||
|
return (code & (mask)) == (val); \
|
||
|
} \
|
||
|
bool simulate_##name(u32 opcode, unsigned long addr, \
|
||
|
struct pt_regs *regs)
|
||
|
|
||
|
#define RISCV_INSN_REJECTED(name, code) \
|
||
|
do { \
|
||
|
if (riscv_insn_is_##name(code)) { \
|
||
|
return INSN_REJECTED; \
|
||
|
} \
|
||
|
} while (0)
|
||
|
|
||
|
__RISCV_INSN_FUNCS(system, 0x7f, 0x73);
|
||
|
__RISCV_INSN_FUNCS(fence, 0x7f, 0x0f);
|
||
|
|
||
|
#define RISCV_INSN_SET_SIMULATE(name, code) \
|
||
|
do { \
|
||
|
if (riscv_insn_is_##name(code)) { \
|
||
|
api->handler = simulate_##name; \
|
||
|
return INSN_GOOD_NO_SLOT; \
|
||
|
} \
|
||
|
} while (0)
|
||
|
|
||
|
__RISCV_INSN_FUNCS(c_j, 0xe003, 0xa001);
|
||
|
__RISCV_INSN_FUNCS(c_jr, 0xf07f, 0x8002);
|
||
|
__RISCV_INSN_FUNCS(c_jal, 0xe003, 0x2001);
|
||
|
__RISCV_INSN_FUNCS(c_jalr, 0xf07f, 0x9002);
|
||
|
__RISCV_INSN_FUNCS(c_beqz, 0xe003, 0xc001);
|
||
|
__RISCV_INSN_FUNCS(c_bnez, 0xe003, 0xe001);
|
||
|
__RISCV_INSN_FUNCS(c_ebreak, 0xffff, 0x9002);
|
||
|
|
||
|
__RISCV_INSN_FUNCS(auipc, 0x7f, 0x17);
|
||
|
__RISCV_INSN_FUNCS(branch, 0x7f, 0x63);
|
||
|
|
||
|
__RISCV_INSN_FUNCS(jal, 0x7f, 0x6f);
|
||
|
__RISCV_INSN_FUNCS(jalr, 0x707f, 0x67);
|
||
|
|
||
|
#endif /* _RISCV_KERNEL_PROBES_SIMULATE_INSN_H */
|