xref: /linux/arch/powerpc/include/asm/sstep.h (revision e93ad65e3611b06288efdf0cfd76c012df3feec1)
12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2b8b572e1SStephen Rothwell /*
3b8b572e1SStephen Rothwell  * Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM
4b8b572e1SStephen Rothwell  */
594afd069SJordan Niethe #include <asm/inst.h>
6b8b572e1SStephen Rothwell 
7b8b572e1SStephen Rothwell struct pt_regs;
8b8b572e1SStephen Rothwell 
9b8b572e1SStephen Rothwell /*
10b8b572e1SStephen Rothwell  * We don't allow single-stepping an mtmsrd that would clear
11b8b572e1SStephen Rothwell  * MSR_RI, since that would make the exception unrecoverable.
12b8b572e1SStephen Rothwell  * Since we need to single-step to proceed from a breakpoint,
13b8b572e1SStephen Rothwell  * we don't allow putting a breakpoint on an mtmsrd instruction.
14b8b572e1SStephen Rothwell  * Similarly we don't allow breakpoints on rfid instructions.
15b8b572e1SStephen Rothwell  * These macros tell us if an instruction is a mtmsrd or rfid.
16b8b572e1SStephen Rothwell  * Note that IS_MTMSRD returns true for both an mtmsr (32-bit)
17b8b572e1SStephen Rothwell  * and an mtmsrd (64-bit).
18b8b572e1SStephen Rothwell  */
19777e26f0SJordan Niethe #define IS_MTMSRD(instr)	((ppc_inst_val(instr) & 0xfc0007be) == 0x7c000124)
20777e26f0SJordan Niethe #define IS_RFID(instr)		((ppc_inst_val(instr) & 0xfc0007fe) == 0x4c000024)
21777e26f0SJordan Niethe #define IS_RFI(instr)		((ppc_inst_val(instr) & 0xfc0007fe) == 0x4c000064)
22b8b572e1SStephen Rothwell 
23be96f633SPaul Mackerras enum instruction_type {
24be96f633SPaul Mackerras 	COMPUTE,		/* arith/logical/CR op, etc. */
25d120cdbcSPaul Mackerras 	LOAD,			/* load and store types need to be contiguous */
26be96f633SPaul Mackerras 	LOAD_MULTI,
27be96f633SPaul Mackerras 	LOAD_FP,
28be96f633SPaul Mackerras 	LOAD_VMX,
29be96f633SPaul Mackerras 	LOAD_VSX,
30be96f633SPaul Mackerras 	STORE,
31be96f633SPaul Mackerras 	STORE_MULTI,
32be96f633SPaul Mackerras 	STORE_FP,
33be96f633SPaul Mackerras 	STORE_VMX,
34be96f633SPaul Mackerras 	STORE_VSX,
35be96f633SPaul Mackerras 	LARX,
36be96f633SPaul Mackerras 	STCX,
37be96f633SPaul Mackerras 	BRANCH,
38be96f633SPaul Mackerras 	MFSPR,
39be96f633SPaul Mackerras 	MTSPR,
40be96f633SPaul Mackerras 	CACHEOP,
41be96f633SPaul Mackerras 	BARRIER,
42be96f633SPaul Mackerras 	SYSCALL,
43be96f633SPaul Mackerras 	MFMSR,
44be96f633SPaul Mackerras 	MTMSR,
45be96f633SPaul Mackerras 	RFI,
46be96f633SPaul Mackerras 	INTERRUPT,
47be96f633SPaul Mackerras 	UNKNOWN
48be96f633SPaul Mackerras };
49be96f633SPaul Mackerras 
50be96f633SPaul Mackerras #define INSTR_TYPE_MASK	0x1f
51be96f633SPaul Mackerras 
5274c68810SRavi Bangoria #define OP_IS_LOAD(type)	((LOAD <= (type) && (type) <= LOAD_VSX) || (type) == LARX)
5374c68810SRavi Bangoria #define OP_IS_STORE(type)	((STORE <= (type) && (type) <= STORE_VSX) || (type) == STCX)
54d120cdbcSPaul Mackerras #define OP_IS_LOAD_STORE(type)	(LOAD <= (type) && (type) <= STCX)
55d120cdbcSPaul Mackerras 
563cdfcbfdSPaul Mackerras /* Compute flags, ORed in with type */
573cdfcbfdSPaul Mackerras #define SETREG		0x20
583cdfcbfdSPaul Mackerras #define SETCC		0x40
593cdfcbfdSPaul Mackerras #define SETXER		0x80
603cdfcbfdSPaul Mackerras 
613cdfcbfdSPaul Mackerras /* Branch flags, ORed in with type */
623cdfcbfdSPaul Mackerras #define SETLK		0x20
633cdfcbfdSPaul Mackerras #define BRTAKEN		0x40
643cdfcbfdSPaul Mackerras #define DECCTR		0x80
653cdfcbfdSPaul Mackerras 
66be96f633SPaul Mackerras /* Load/store flags, ORed in with type */
67be96f633SPaul Mackerras #define SIGNEXT		0x20
68be96f633SPaul Mackerras #define UPDATE		0x40	/* matches bit in opcode 31 instructions */
69be96f633SPaul Mackerras #define BYTEREV		0x80
70d2b65ac6SPaul Mackerras #define FPCONV		0x100
71be96f633SPaul Mackerras 
723cdfcbfdSPaul Mackerras /* Barrier type field, ORed in with type */
733cdfcbfdSPaul Mackerras #define BARRIER_MASK	0xe0
743cdfcbfdSPaul Mackerras #define BARRIER_SYNC	0x00
753cdfcbfdSPaul Mackerras #define BARRIER_ISYNC	0x20
763cdfcbfdSPaul Mackerras #define BARRIER_EIEIO	0x40
773cdfcbfdSPaul Mackerras #define BARRIER_LWSYNC	0x60
783cdfcbfdSPaul Mackerras #define BARRIER_PTESYNC	0x80
793cdfcbfdSPaul Mackerras 
80be96f633SPaul Mackerras /* Cacheop values, ORed in with type */
81be96f633SPaul Mackerras #define CACHEOP_MASK	0x700
82be96f633SPaul Mackerras #define DCBST		0
83be96f633SPaul Mackerras #define DCBF		0x100
84be96f633SPaul Mackerras #define DCBTST		0x200
85be96f633SPaul Mackerras #define DCBT		0x300
86cf87c3f6SPaul Mackerras #define ICBI		0x400
87b2543f7bSPaul Mackerras #define DCBZ		0x500
88be96f633SPaul Mackerras 
89350779a2SPaul Mackerras /* VSX flags values */
90350779a2SPaul Mackerras #define VSX_FPCONV	1	/* do floating point SP/DP conversion */
91350779a2SPaul Mackerras #define VSX_SPLAT	2	/* store loaded value into all elements */
92350779a2SPaul Mackerras #define VSX_LDLEFT	4	/* load VSX register from left */
93350779a2SPaul Mackerras #define VSX_CHECK_VEC	8	/* check MSR_VEC not MSR_VSX for reg >= 32 */
94350779a2SPaul Mackerras 
9550b80a12SJordan Niethe /* Prefixed flag, ORed in with type */
9650b80a12SJordan Niethe #define PREFIXED       0x800
9750b80a12SJordan Niethe 
98be96f633SPaul Mackerras /* Size field in type word */
99d2b65ac6SPaul Mackerras #define SIZE(n)		((n) << 12)
100d2b65ac6SPaul Mackerras #define GETSIZE(w)	((w) >> 12)
101be96f633SPaul Mackerras 
102e6684d07SRavi Bangoria #define GETTYPE(t)	((t) & INSTR_TYPE_MASK)
10350b80a12SJordan Niethe #define GETLENGTH(t)   (((t) & PREFIXED) ? 8 : 4)
104e6684d07SRavi Bangoria 
105be96f633SPaul Mackerras #define MKOP(t, f, s)	((t) | (f) | SIZE(s))
106be96f633SPaul Mackerras 
10768a180a4SBalamuruhan S /* Prefix instruction operands */
10868a180a4SBalamuruhan S #define GET_PREFIX_RA(i)	(((i) >> 16) & 0x1f)
10968a180a4SBalamuruhan S #define GET_PREFIX_R(i)		((i) & (1ul << 20))
11068a180a4SBalamuruhan S 
111*e93ad65eSBalamuruhan S extern s32 patch__exec_instr;
112*e93ad65eSBalamuruhan S 
113be96f633SPaul Mackerras struct instruction_op {
114be96f633SPaul Mackerras 	int type;
115be96f633SPaul Mackerras 	int reg;
116be96f633SPaul Mackerras 	unsigned long val;
117be96f633SPaul Mackerras 	/* For LOAD/STORE/LARX/STCX */
118be96f633SPaul Mackerras 	unsigned long ea;
119be96f633SPaul Mackerras 	int update_reg;
120be96f633SPaul Mackerras 	/* For MFSPR */
121be96f633SPaul Mackerras 	int spr;
1223cdfcbfdSPaul Mackerras 	u32 ccval;
1233cdfcbfdSPaul Mackerras 	u32 xerval;
124350779a2SPaul Mackerras 	u8 element_size;	/* for VSX/VMX loads/stores */
125350779a2SPaul Mackerras 	u8 vsx_flags;
126350779a2SPaul Mackerras };
127350779a2SPaul Mackerras 
128350779a2SPaul Mackerras union vsx_reg {
129350779a2SPaul Mackerras 	u8	b[16];
130350779a2SPaul Mackerras 	u16	h[8];
131350779a2SPaul Mackerras 	u32	w[4];
132350779a2SPaul Mackerras 	unsigned long d[2];
133350779a2SPaul Mackerras 	float	fp[4];
134350779a2SPaul Mackerras 	double	dp[2];
135c22435a5SPaul Mackerras 	__vector128 v;
136be96f633SPaul Mackerras };
137be96f633SPaul Mackerras 
1383cdfcbfdSPaul Mackerras /*
1393cdfcbfdSPaul Mackerras  * Decode an instruction, and return information about it in *op
1403cdfcbfdSPaul Mackerras  * without changing *regs.
1413cdfcbfdSPaul Mackerras  *
1423cdfcbfdSPaul Mackerras  * Return value is 1 if the instruction can be emulated just by
1433cdfcbfdSPaul Mackerras  * updating *regs with the information in *op, -1 if we need the
1443cdfcbfdSPaul Mackerras  * GPRs but *regs doesn't contain the full register set, or 0
1453cdfcbfdSPaul Mackerras  * otherwise.
1463cdfcbfdSPaul Mackerras  */
1473cdfcbfdSPaul Mackerras extern int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
14894afd069SJordan Niethe 			 struct ppc_inst instr);
1493cdfcbfdSPaul Mackerras 
1503cdfcbfdSPaul Mackerras /*
1513cdfcbfdSPaul Mackerras  * Emulate an instruction that can be executed just by updating
1523cdfcbfdSPaul Mackerras  * fields in *regs.
1533cdfcbfdSPaul Mackerras  */
1543cdfcbfdSPaul Mackerras void emulate_update_regs(struct pt_regs *reg, struct instruction_op *op);
1553cdfcbfdSPaul Mackerras 
1563cdfcbfdSPaul Mackerras /*
1573cdfcbfdSPaul Mackerras  * Emulate instructions that cause a transfer of control,
1583cdfcbfdSPaul Mackerras  * arithmetic/logical instructions, loads and stores,
1593cdfcbfdSPaul Mackerras  * cache operations and barriers.
1603cdfcbfdSPaul Mackerras  *
1613cdfcbfdSPaul Mackerras  * Returns 1 if the instruction was emulated successfully,
1623cdfcbfdSPaul Mackerras  * 0 if it could not be emulated, or -1 for an instruction that
1633cdfcbfdSPaul Mackerras  * should not be emulated (rfid, mtmsrd clearing MSR_RI, etc.).
1643cdfcbfdSPaul Mackerras  */
16594afd069SJordan Niethe extern int emulate_step(struct pt_regs *regs, struct ppc_inst instr);
1663cdfcbfdSPaul Mackerras 
167a53d5182SPaul Mackerras /*
168a53d5182SPaul Mackerras  * Emulate a load or store instruction by reading/writing the
169a53d5182SPaul Mackerras  * memory of the current process.  FP/VMX/VSX registers are assumed
170a53d5182SPaul Mackerras  * to hold live values if the appropriate enable bit in regs->msr is
171a53d5182SPaul Mackerras  * set; otherwise this will use the saved values in the thread struct
172a53d5182SPaul Mackerras  * for user-mode accesses.
173a53d5182SPaul Mackerras  */
174a53d5182SPaul Mackerras extern int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op);
175a53d5182SPaul Mackerras 
176350779a2SPaul Mackerras extern void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
177d955189aSPaul Mackerras 			     const void *mem, bool cross_endian);
178d955189aSPaul Mackerras extern void emulate_vsx_store(struct instruction_op *op,
179d955189aSPaul Mackerras 			      const union vsx_reg *reg, void *mem,
180d955189aSPaul Mackerras 			      bool cross_endian);
181b2543f7bSPaul Mackerras extern int emulate_dcbz(unsigned long ea, struct pt_regs *regs);
182