1/*
2 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
3 *
4 * Based on alpha version.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#ifndef _ASM_POWERPC_OPROFILE_IMPL_H
13#define _ASM_POWERPC_OPROFILE_IMPL_H
14#ifdef __KERNEL__
15
16#define OP_MAX_COUNTER 8
17
18/* Per-counter configuration as set via oprofilefs.  */
19struct op_counter_config {
20	unsigned long enabled;
21	unsigned long event;
22	unsigned long count;
23	/* Classic doesn't support per-counter user/kernel selection */
24	unsigned long kernel;
25	unsigned long user;
26	unsigned long unit_mask;
27};
28
29/* System-wide configuration as set via oprofilefs.  */
30struct op_system_config {
31#ifdef CONFIG_PPC64
32	unsigned long mmcr0;
33	unsigned long mmcr1;
34	unsigned long mmcra;
35#ifdef CONFIG_OPROFILE_CELL
36	/* Register for oprofile user tool to check cell kernel profiling
37	 * support.
38	 */
39	unsigned long cell_support;
40#endif
41#endif
42	unsigned long enable_kernel;
43	unsigned long enable_user;
44};
45
46/* Per-arch configuration */
47struct op_powerpc_model {
48	int (*reg_setup) (struct op_counter_config *,
49			   struct op_system_config *,
50			   int num_counters);
51	int  (*cpu_setup) (struct op_counter_config *);
52	int  (*start) (struct op_counter_config *);
53	int  (*global_start) (struct op_counter_config *);
54	void (*stop) (void);
55	void (*global_stop) (void);
56	int (*sync_start)(void);
57	int (*sync_stop)(void);
58	void (*handle_interrupt) (struct pt_regs *,
59				  struct op_counter_config *);
60	int num_counters;
61};
62
63extern struct op_powerpc_model op_model_fsl_emb;
64extern struct op_powerpc_model op_model_power4;
65extern struct op_powerpc_model op_model_7450;
66extern struct op_powerpc_model op_model_cell;
67extern struct op_powerpc_model op_model_pa6t;
68
69
70/* All the classic PPC parts use these */
71static inline unsigned int classic_ctr_read(unsigned int i)
72{
73	switch(i) {
74	case 0:
75		return mfspr(SPRN_PMC1);
76	case 1:
77		return mfspr(SPRN_PMC2);
78	case 2:
79		return mfspr(SPRN_PMC3);
80	case 3:
81		return mfspr(SPRN_PMC4);
82	case 4:
83		return mfspr(SPRN_PMC5);
84	case 5:
85		return mfspr(SPRN_PMC6);
86
87/* No PPC32 chip has more than 6 so far */
88#ifdef CONFIG_PPC64
89	case 6:
90		return mfspr(SPRN_PMC7);
91	case 7:
92		return mfspr(SPRN_PMC8);
93#endif
94	default:
95		return 0;
96	}
97}
98
99static inline void classic_ctr_write(unsigned int i, unsigned int val)
100{
101	switch(i) {
102	case 0:
103		mtspr(SPRN_PMC1, val);
104		break;
105	case 1:
106		mtspr(SPRN_PMC2, val);
107		break;
108	case 2:
109		mtspr(SPRN_PMC3, val);
110		break;
111	case 3:
112		mtspr(SPRN_PMC4, val);
113		break;
114	case 4:
115		mtspr(SPRN_PMC5, val);
116		break;
117	case 5:
118		mtspr(SPRN_PMC6, val);
119		break;
120
121/* No PPC32 chip has more than 6, yet */
122#ifdef CONFIG_PPC64
123	case 6:
124		mtspr(SPRN_PMC7, val);
125		break;
126	case 7:
127		mtspr(SPRN_PMC8, val);
128		break;
129#endif
130	default:
131		break;
132	}
133}
134
135
136extern void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth);
137
138#endif /* __KERNEL__ */
139#endif /* _ASM_POWERPC_OPROFILE_IMPL_H */
140