xref: /linux/arch/powerpc/include/asm/sstep.h (revision 777e26f0edf8dab58b8dd474d35d83bde0ac6d76)
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  */
5b8b572e1SStephen Rothwell 
6b8b572e1SStephen Rothwell struct pt_regs;
7b8b572e1SStephen Rothwell 
8b8b572e1SStephen Rothwell /*
9b8b572e1SStephen Rothwell  * We don't allow single-stepping an mtmsrd that would clear
10b8b572e1SStephen Rothwell  * MSR_RI, since that would make the exception unrecoverable.
11b8b572e1SStephen Rothwell  * Since we need to single-step to proceed from a breakpoint,
12b8b572e1SStephen Rothwell  * we don't allow putting a breakpoint on an mtmsrd instruction.
13b8b572e1SStephen Rothwell  * Similarly we don't allow breakpoints on rfid instructions.
14b8b572e1SStephen Rothwell  * These macros tell us if an instruction is a mtmsrd or rfid.
15b8b572e1SStephen Rothwell  * Note that IS_MTMSRD returns true for both an mtmsr (32-bit)
16b8b572e1SStephen Rothwell  * and an mtmsrd (64-bit).
17b8b572e1SStephen Rothwell  */
18*777e26f0SJordan Niethe #define IS_MTMSRD(instr)	((ppc_inst_val(instr) & 0xfc0007be) == 0x7c000124)
19*777e26f0SJordan Niethe #define IS_RFID(instr)		((ppc_inst_val(instr) & 0xfc0007fe) == 0x4c000024)
20*777e26f0SJordan Niethe #define IS_RFI(instr)		((ppc_inst_val(instr) & 0xfc0007fe) == 0x4c000064)
21b8b572e1SStephen Rothwell 
22be96f633SPaul Mackerras enum instruction_type {
23be96f633SPaul Mackerras 	COMPUTE,		/* arith/logical/CR op, etc. */
24d120cdbcSPaul Mackerras 	LOAD,			/* load and store types need to be contiguous */
25be96f633SPaul Mackerras 	LOAD_MULTI,
26be96f633SPaul Mackerras 	LOAD_FP,
27be96f633SPaul Mackerras 	LOAD_VMX,
28be96f633SPaul Mackerras 	LOAD_VSX,
29be96f633SPaul Mackerras 	STORE,
30be96f633SPaul Mackerras 	STORE_MULTI,
31be96f633SPaul Mackerras 	STORE_FP,
32be96f633SPaul Mackerras 	STORE_VMX,
33be96f633SPaul Mackerras 	STORE_VSX,
34be96f633SPaul Mackerras 	LARX,
35be96f633SPaul Mackerras 	STCX,
36be96f633SPaul Mackerras 	BRANCH,
37be96f633SPaul Mackerras 	MFSPR,
38be96f633SPaul Mackerras 	MTSPR,
39be96f633SPaul Mackerras 	CACHEOP,
40be96f633SPaul Mackerras 	BARRIER,
41be96f633SPaul Mackerras 	SYSCALL,
42be96f633SPaul Mackerras 	MFMSR,
43be96f633SPaul Mackerras 	MTMSR,
44be96f633SPaul Mackerras 	RFI,
45be96f633SPaul Mackerras 	INTERRUPT,
46be96f633SPaul Mackerras 	UNKNOWN
47be96f633SPaul Mackerras };
48be96f633SPaul Mackerras 
49be96f633SPaul Mackerras #define INSTR_TYPE_MASK	0x1f
50be96f633SPaul Mackerras 
51d120cdbcSPaul Mackerras #define OP_IS_LOAD_STORE(type)	(LOAD <= (type) && (type) <= STCX)
52d120cdbcSPaul Mackerras 
533cdfcbfdSPaul Mackerras /* Compute flags, ORed in with type */
543cdfcbfdSPaul Mackerras #define SETREG		0x20
553cdfcbfdSPaul Mackerras #define SETCC		0x40
563cdfcbfdSPaul Mackerras #define SETXER		0x80
573cdfcbfdSPaul Mackerras 
583cdfcbfdSPaul Mackerras /* Branch flags, ORed in with type */
593cdfcbfdSPaul Mackerras #define SETLK		0x20
603cdfcbfdSPaul Mackerras #define BRTAKEN		0x40
613cdfcbfdSPaul Mackerras #define DECCTR		0x80
623cdfcbfdSPaul Mackerras 
63be96f633SPaul Mackerras /* Load/store flags, ORed in with type */
64be96f633SPaul Mackerras #define SIGNEXT		0x20
65be96f633SPaul Mackerras #define UPDATE		0x40	/* matches bit in opcode 31 instructions */
66be96f633SPaul Mackerras #define BYTEREV		0x80
67d2b65ac6SPaul Mackerras #define FPCONV		0x100
68be96f633SPaul Mackerras 
693cdfcbfdSPaul Mackerras /* Barrier type field, ORed in with type */
703cdfcbfdSPaul Mackerras #define BARRIER_MASK	0xe0
713cdfcbfdSPaul Mackerras #define BARRIER_SYNC	0x00
723cdfcbfdSPaul Mackerras #define BARRIER_ISYNC	0x20
733cdfcbfdSPaul Mackerras #define BARRIER_EIEIO	0x40
743cdfcbfdSPaul Mackerras #define BARRIER_LWSYNC	0x60
753cdfcbfdSPaul Mackerras #define BARRIER_PTESYNC	0x80
763cdfcbfdSPaul Mackerras 
77be96f633SPaul Mackerras /* Cacheop values, ORed in with type */
78be96f633SPaul Mackerras #define CACHEOP_MASK	0x700
79be96f633SPaul Mackerras #define DCBST		0
80be96f633SPaul Mackerras #define DCBF		0x100
81be96f633SPaul Mackerras #define DCBTST		0x200
82be96f633SPaul Mackerras #define DCBT		0x300
83cf87c3f6SPaul Mackerras #define ICBI		0x400
84b2543f7bSPaul Mackerras #define DCBZ		0x500
85be96f633SPaul Mackerras 
86350779a2SPaul Mackerras /* VSX flags values */
87350779a2SPaul Mackerras #define VSX_FPCONV	1	/* do floating point SP/DP conversion */
88350779a2SPaul Mackerras #define VSX_SPLAT	2	/* store loaded value into all elements */
89350779a2SPaul Mackerras #define VSX_LDLEFT	4	/* load VSX register from left */
90350779a2SPaul Mackerras #define VSX_CHECK_VEC	8	/* check MSR_VEC not MSR_VSX for reg >= 32 */
91350779a2SPaul Mackerras 
92be96f633SPaul Mackerras /* Size field in type word */
93d2b65ac6SPaul Mackerras #define SIZE(n)		((n) << 12)
94d2b65ac6SPaul Mackerras #define GETSIZE(w)	((w) >> 12)
95be96f633SPaul Mackerras 
96e6684d07SRavi Bangoria #define GETTYPE(t)	((t) & INSTR_TYPE_MASK)
97e6684d07SRavi Bangoria 
98be96f633SPaul Mackerras #define MKOP(t, f, s)	((t) | (f) | SIZE(s))
99be96f633SPaul Mackerras 
100be96f633SPaul Mackerras struct instruction_op {
101be96f633SPaul Mackerras 	int type;
102be96f633SPaul Mackerras 	int reg;
103be96f633SPaul Mackerras 	unsigned long val;
104be96f633SPaul Mackerras 	/* For LOAD/STORE/LARX/STCX */
105be96f633SPaul Mackerras 	unsigned long ea;
106be96f633SPaul Mackerras 	int update_reg;
107be96f633SPaul Mackerras 	/* For MFSPR */
108be96f633SPaul Mackerras 	int spr;
1093cdfcbfdSPaul Mackerras 	u32 ccval;
1103cdfcbfdSPaul Mackerras 	u32 xerval;
111350779a2SPaul Mackerras 	u8 element_size;	/* for VSX/VMX loads/stores */
112350779a2SPaul Mackerras 	u8 vsx_flags;
113350779a2SPaul Mackerras };
114350779a2SPaul Mackerras 
115350779a2SPaul Mackerras union vsx_reg {
116350779a2SPaul Mackerras 	u8	b[16];
117350779a2SPaul Mackerras 	u16	h[8];
118350779a2SPaul Mackerras 	u32	w[4];
119350779a2SPaul Mackerras 	unsigned long d[2];
120350779a2SPaul Mackerras 	float	fp[4];
121350779a2SPaul Mackerras 	double	dp[2];
122c22435a5SPaul Mackerras 	__vector128 v;
123be96f633SPaul Mackerras };
124be96f633SPaul Mackerras 
1253cdfcbfdSPaul Mackerras /*
1263cdfcbfdSPaul Mackerras  * Decode an instruction, and return information about it in *op
1273cdfcbfdSPaul Mackerras  * without changing *regs.
1283cdfcbfdSPaul Mackerras  *
1293cdfcbfdSPaul Mackerras  * Return value is 1 if the instruction can be emulated just by
1303cdfcbfdSPaul Mackerras  * updating *regs with the information in *op, -1 if we need the
1313cdfcbfdSPaul Mackerras  * GPRs but *regs doesn't contain the full register set, or 0
1323cdfcbfdSPaul Mackerras  * otherwise.
1333cdfcbfdSPaul Mackerras  */
1343cdfcbfdSPaul Mackerras extern int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
135be96f633SPaul Mackerras 			 unsigned int instr);
1363cdfcbfdSPaul Mackerras 
1373cdfcbfdSPaul Mackerras /*
1383cdfcbfdSPaul Mackerras  * Emulate an instruction that can be executed just by updating
1393cdfcbfdSPaul Mackerras  * fields in *regs.
1403cdfcbfdSPaul Mackerras  */
1413cdfcbfdSPaul Mackerras void emulate_update_regs(struct pt_regs *reg, struct instruction_op *op);
1423cdfcbfdSPaul Mackerras 
1433cdfcbfdSPaul Mackerras /*
1443cdfcbfdSPaul Mackerras  * Emulate instructions that cause a transfer of control,
1453cdfcbfdSPaul Mackerras  * arithmetic/logical instructions, loads and stores,
1463cdfcbfdSPaul Mackerras  * cache operations and barriers.
1473cdfcbfdSPaul Mackerras  *
1483cdfcbfdSPaul Mackerras  * Returns 1 if the instruction was emulated successfully,
1493cdfcbfdSPaul Mackerras  * 0 if it could not be emulated, or -1 for an instruction that
1503cdfcbfdSPaul Mackerras  * should not be emulated (rfid, mtmsrd clearing MSR_RI, etc.).
1513cdfcbfdSPaul Mackerras  */
1523cdfcbfdSPaul Mackerras extern int emulate_step(struct pt_regs *regs, unsigned int instr);
1533cdfcbfdSPaul Mackerras 
154a53d5182SPaul Mackerras /*
155a53d5182SPaul Mackerras  * Emulate a load or store instruction by reading/writing the
156a53d5182SPaul Mackerras  * memory of the current process.  FP/VMX/VSX registers are assumed
157a53d5182SPaul Mackerras  * to hold live values if the appropriate enable bit in regs->msr is
158a53d5182SPaul Mackerras  * set; otherwise this will use the saved values in the thread struct
159a53d5182SPaul Mackerras  * for user-mode accesses.
160a53d5182SPaul Mackerras  */
161a53d5182SPaul Mackerras extern int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op);
162a53d5182SPaul Mackerras 
163350779a2SPaul Mackerras extern void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
164d955189aSPaul Mackerras 			     const void *mem, bool cross_endian);
165d955189aSPaul Mackerras extern void emulate_vsx_store(struct instruction_op *op,
166d955189aSPaul Mackerras 			      const union vsx_reg *reg, void *mem,
167d955189aSPaul Mackerras 			      bool cross_endian);
168b2543f7bSPaul Mackerras extern int emulate_dcbz(unsigned long ea, struct pt_regs *regs);
169