1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  *  Copyright 2007 Sony Corporation
4  */
5 
6 #ifndef _ASM_POWERPC_EMULATED_OPS_H
7 #define _ASM_POWERPC_EMULATED_OPS_H
8 
9 #include <linux/atomic.h>
10 #include <linux/perf_event.h>
11 
12 
13 #ifdef CONFIG_PPC_EMULATED_STATS
14 
15 struct ppc_emulated_entry {
16 	const char *name;
17 	atomic_t val;
18 };
19 
20 extern struct ppc_emulated {
21 #ifdef CONFIG_ALTIVEC
22 	struct ppc_emulated_entry altivec;
23 #endif
24 	struct ppc_emulated_entry dcba;
25 	struct ppc_emulated_entry dcbz;
26 	struct ppc_emulated_entry fp_pair;
27 	struct ppc_emulated_entry isel;
28 	struct ppc_emulated_entry mcrxr;
29 	struct ppc_emulated_entry mfpvr;
30 	struct ppc_emulated_entry multiple;
31 	struct ppc_emulated_entry popcntb;
32 	struct ppc_emulated_entry spe;
33 	struct ppc_emulated_entry string;
34 	struct ppc_emulated_entry sync;
35 	struct ppc_emulated_entry unaligned;
36 #ifdef CONFIG_MATH_EMULATION
37 	struct ppc_emulated_entry math;
38 #endif
39 #ifdef CONFIG_VSX
40 	struct ppc_emulated_entry vsx;
41 #endif
42 #ifdef CONFIG_PPC64
43 	struct ppc_emulated_entry mfdscr;
44 	struct ppc_emulated_entry mtdscr;
45 	struct ppc_emulated_entry lq_stq;
46 	struct ppc_emulated_entry lxvw4x;
47 	struct ppc_emulated_entry lxvh8x;
48 	struct ppc_emulated_entry lxvd2x;
49 	struct ppc_emulated_entry lxvb16x;
50 #endif
51 } ppc_emulated;
52 
53 extern u32 ppc_warn_emulated;
54 
55 extern void ppc_warn_emulated_print(const char *type);
56 
57 #define __PPC_WARN_EMULATED(type)					 \
58 	do {								 \
59 		atomic_inc(&ppc_emulated.type.val);			 \
60 		if (ppc_warn_emulated)					 \
61 			ppc_warn_emulated_print(ppc_emulated.type.name); \
62 	} while (0)
63 
64 #else /* !CONFIG_PPC_EMULATED_STATS */
65 
66 #define __PPC_WARN_EMULATED(type)	do { } while (0)
67 
68 #endif /* !CONFIG_PPC_EMULATED_STATS */
69 
70 #define PPC_WARN_EMULATED(type, regs)					\
71 	do {								\
72 		perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,		\
73 			1, regs, 0);					\
74 		__PPC_WARN_EMULATED(type);				\
75 	} while (0)
76 
77 #define PPC_WARN_ALIGNMENT(type, regs)					\
78 	do {								\
79 		perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS,		\
80 			1, regs, regs->dar);				\
81 		__PPC_WARN_EMULATED(type);				\
82 	} while (0)
83 
84 #endif /* _ASM_POWERPC_EMULATED_OPS_H */
85