Commit 619f1e75 authored by Anton Blanchard's avatar Anton Blanchard Committed by Linus Torvalds

[PATCH] ppc64: POWER4 oprofile update

POWER4 oprofile updates from Carl Love.

- Create mmcr0, mmcr1, mmcra oprofilefs files.
- Use kernel and user profile disable bits. (Some modifications by me)
Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f3abb77d
...@@ -90,6 +90,14 @@ static int op_ppc64_create_files(struct super_block *sb, struct dentry *root) ...@@ -90,6 +90,14 @@ static int op_ppc64_create_files(struct super_block *sb, struct dentry *root)
{ {
int i; int i;
/*
* There is one mmcr0, mmcr1 and mmcra for setting the events for
* all of the counters.
*/
oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0);
oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1);
oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra);
for (i = 0; i < model->num_counters; ++i) { for (i = 0; i < model->num_counters; ++i) {
struct dentry *dir; struct dentry *dir;
char buf[3]; char buf[3];
...@@ -112,6 +120,10 @@ static int op_ppc64_create_files(struct super_block *sb, struct dentry *root) ...@@ -112,6 +120,10 @@ static int op_ppc64_create_files(struct super_block *sb, struct dentry *root)
oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel); oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user); oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
/* Default to tracing both kernel and user */
sys.enable_kernel = 1;
sys.enable_user = 1;
return 0; return 0;
} }
......
...@@ -19,6 +19,12 @@ ...@@ -19,6 +19,12 @@
/* freeze counters. set to 1 on a perfmon exception */ /* freeze counters. set to 1 on a perfmon exception */
#define MMCR0_FC (1UL << (31 - 0)) #define MMCR0_FC (1UL << (31 - 0))
/* freeze in supervisor state */
#define MMCR0_KERNEL_DISABLE (1UL << (31 - 1))
/* freeze in problem state */
#define MMCR0_PROBLEM_DISABLE (1UL << (31 - 2))
/* freeze counters while MSR mark = 1 */ /* freeze counters while MSR mark = 1 */
#define MMCR0_FCM1 (1UL << (31 - 3)) #define MMCR0_FCM1 (1UL << (31 - 3))
...@@ -28,15 +34,15 @@ ...@@ -28,15 +34,15 @@
/* freeze counters on enabled condition or event */ /* freeze counters on enabled condition or event */
#define MMCR0_FCECE (1UL << (31 - 6)) #define MMCR0_FCECE (1UL << (31 - 6))
/* performance monitor alert has occurred, set to 0 after handling exception */
#define MMCR0_PMAO (1UL << (31 - 24))
/* PMC1 count enable*/ /* PMC1 count enable*/
#define MMCR0_PMC1INTCONTROL (1UL << (31 - 16)) #define MMCR0_PMC1INTCONTROL (1UL << (31 - 16))
/* PMCn count enable*/ /* PMCn count enable*/
#define MMCR0_PMCNINTCONTROL (1UL << (31 - 17)) #define MMCR0_PMCNINTCONTROL (1UL << (31 - 17))
/* performance monitor alert has occurred, set to 0 after handling exception */
#define MMCR0_PMAO (1UL << (31 - 24))
/* state of MSR HV when SIAR set */ /* state of MSR HV when SIAR set */
#define MMCRA_SIHV (1UL << (63 - 35)) #define MMCRA_SIHV (1UL << (63 - 35))
...@@ -60,6 +66,9 @@ struct op_counter_config { ...@@ -60,6 +66,9 @@ struct op_counter_config {
/* System-wide configuration as set via oprofilefs. */ /* System-wide configuration as set via oprofilefs. */
struct op_system_config { struct op_system_config {
unsigned long mmcr0;
unsigned long mmcr1;
unsigned long mmcra;
unsigned long enable_kernel; unsigned long enable_kernel;
unsigned long enable_user; unsigned long enable_user;
}; };
......
...@@ -27,6 +27,11 @@ static int num_counters; ...@@ -27,6 +27,11 @@ static int num_counters;
static int oprofile_running; static int oprofile_running;
static int mmcra_has_sihv; static int mmcra_has_sihv;
/* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */
static u32 mmcr0_val;
static u64 mmcr1_val;
static u32 mmcra_val;
static void power4_reg_setup(struct op_counter_config *ctr, static void power4_reg_setup(struct op_counter_config *ctr,
struct op_system_config *sys, struct op_system_config *sys,
int num_ctrs) int num_ctrs)
...@@ -45,18 +50,36 @@ static void power4_reg_setup(struct op_counter_config *ctr, ...@@ -45,18 +50,36 @@ static void power4_reg_setup(struct op_counter_config *ctr,
if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA_SIHV) if (cur_cpu_spec->cpu_features & CPU_FTR_MMCRA_SIHV)
mmcra_has_sihv = 1; mmcra_has_sihv = 1;
/*
* The performance counter event settings are given in the mmcr0,
* mmcr1 and mmcra values passed from the user in the
* op_system_config structure (sys variable).
*/
mmcr0_val = sys->mmcr0;
mmcr1_val = sys->mmcr1;
mmcra_val = sys->mmcra;
for (i = 0; i < num_counters; ++i) for (i = 0; i < num_counters; ++i)
reset_value[i] = 0x80000000UL - ctr[i].count; reset_value[i] = 0x80000000UL - ctr[i].count;
/* XXX setup user and kernel profiling */ /* setup user and kernel profiling */
if (sys->enable_kernel)
mmcr0_val &= ~MMCR0_KERNEL_DISABLE;
else
mmcr0_val |= MMCR0_KERNEL_DISABLE;
if (sys->enable_user)
mmcr0_val &= ~MMCR0_PROBLEM_DISABLE;
else
mmcr0_val |= MMCR0_PROBLEM_DISABLE;
} }
extern void ppc64_enable_pmcs(void); extern void ppc64_enable_pmcs(void);
static void power4_cpu_setup(void *unused) static void power4_cpu_setup(void *unused)
{ {
unsigned int mmcr0 = mfspr(SPRN_MMCR0); unsigned int mmcr0 = mmcr0_val;
unsigned long mmcra = mfspr(SPRN_MMCRA); unsigned long mmcra = mmcra_val;
ppc64_enable_pmcs(); ppc64_enable_pmcs();
...@@ -68,6 +91,8 @@ static void power4_cpu_setup(void *unused) ...@@ -68,6 +91,8 @@ static void power4_cpu_setup(void *unused)
mmcr0 |= MMCR0_PMC1INTCONTROL|MMCR0_PMCNINTCONTROL; mmcr0 |= MMCR0_PMC1INTCONTROL|MMCR0_PMCNINTCONTROL;
mtspr(SPRN_MMCR0, mmcr0); mtspr(SPRN_MMCR0, mmcr0);
mtspr(SPRN_MMCR1, mmcr1_val);
mmcra |= MMCRA_SAMPLE_ENABLE; mmcra |= MMCRA_SAMPLE_ENABLE;
mtspr(SPRN_MMCRA, mmcra); mtspr(SPRN_MMCRA, mmcra);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment