Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 #ifndef _ASM_POWERPC_PROBES_H
0003 #define _ASM_POWERPC_PROBES_H
0004 #ifdef __KERNEL__
0005 /*
0006  * Definitions common to probes files
0007  *
0008  * Copyright IBM Corporation, 2012
0009  */
0010 #include <linux/types.h>
0011 #include <asm/disassemble.h>
0012 #include <asm/ppc-opcode.h>
0013 
0014 #define BREAKPOINT_INSTRUCTION  PPC_RAW_TRAP()  /* trap */
0015 
0016 /* Trap definitions per ISA */
0017 #define IS_TW(instr)        (((instr) & 0xfc0007fe) == 0x7c000008)
0018 #define IS_TD(instr)        (((instr) & 0xfc0007fe) == 0x7c000088)
0019 #define IS_TDI(instr)       (((instr) & 0xfc000000) == 0x08000000)
0020 #define IS_TWI(instr)       (((instr) & 0xfc000000) == 0x0c000000)
0021 
0022 #ifdef CONFIG_PPC64
0023 #define is_trap(instr)      (IS_TW(instr) || IS_TD(instr) || \
0024                 IS_TWI(instr) || IS_TDI(instr))
0025 #else
0026 #define is_trap(instr)      (IS_TW(instr) || IS_TWI(instr))
0027 #endif /* CONFIG_PPC64 */
0028 
0029 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
0030 #define MSR_SINGLESTEP  (MSR_DE)
0031 #else
0032 #define MSR_SINGLESTEP  (MSR_SE)
0033 #endif
0034 
0035 static inline bool can_single_step(u32 inst)
0036 {
0037     switch (get_op(inst)) {
0038     case OP_TRAP_64:    return false;
0039     case OP_TRAP:       return false;
0040     case OP_SC:     return false;
0041     case OP_19:
0042         switch (get_xop(inst)) {
0043         case OP_19_XOP_RFID:        return false;
0044         case OP_19_XOP_RFMCI:       return false;
0045         case OP_19_XOP_RFDI:        return false;
0046         case OP_19_XOP_RFI:     return false;
0047         case OP_19_XOP_RFCI:        return false;
0048         case OP_19_XOP_RFSCV:       return false;
0049         case OP_19_XOP_HRFID:       return false;
0050         case OP_19_XOP_URFID:       return false;
0051         case OP_19_XOP_STOP:        return false;
0052         case OP_19_XOP_DOZE:        return false;
0053         case OP_19_XOP_NAP:     return false;
0054         case OP_19_XOP_SLEEP:       return false;
0055         case OP_19_XOP_RVWINKLE:    return false;
0056         }
0057         break;
0058     case OP_31:
0059         switch (get_xop(inst)) {
0060         case OP_31_XOP_TRAP:        return false;
0061         case OP_31_XOP_TRAP_64:     return false;
0062         case OP_31_XOP_MTMSR:       return false;
0063         case OP_31_XOP_MTMSRD:      return false;
0064         }
0065         break;
0066     }
0067     return true;
0068 }
0069 
0070 /* Enable single stepping for the current task */
0071 static inline void enable_single_step(struct pt_regs *regs)
0072 {
0073     regs_set_return_msr(regs, regs->msr | MSR_SINGLESTEP);
0074 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
0075     /*
0076      * We turn off Critical Input Exception(CE) to ensure that the single
0077      * step will be for the instruction we have the probe on; if we don't,
0078      * it is possible we'd get the single step reported for CE.
0079      */
0080     regs_set_return_msr(regs, regs->msr & ~MSR_CE);
0081     mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
0082 #ifdef CONFIG_PPC_47x
0083     isync();
0084 #endif
0085 #endif
0086 }
0087 
0088 
0089 #endif /* __KERNEL__ */
0090 #endif  /* _ASM_POWERPC_PROBES_H */