|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Copyright (C) IBM Corporation, 2007. All rights reserved.
|
|
Packit |
577717 |
* Contributed by Corey Ashford (cjashfor@us.ibm.com)
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
Packit |
577717 |
* copy of this software and associated documentation files (the "Software"),
|
|
Packit |
577717 |
* to deal in the Software without restriction, including without limitation
|
|
Packit |
577717 |
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
Packit |
577717 |
* and/or sell copies of the Software, and to permit persons to whom the
|
|
Packit |
577717 |
* Software is furnished to do so, subject to the following conditions:
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The above copyright notice and this permission notice shall be included in
|
|
Packit |
577717 |
* all copies or substantial portions of the Software.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
Packit |
577717 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
Packit |
577717 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
Packit |
577717 |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
Packit |
577717 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
Packit |
577717 |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
Packit |
577717 |
* IN THE SOFTWARE.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* pfmlib_gen_powerpc.c
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Support for libpfm for the PowerPC970, POWER4,4+,5,5+,6 processors.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifndef _GNU_SOURCE
|
|
Packit |
577717 |
#define _GNU_SOURCE /* for getline */
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <stdlib.h>
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
#include <limits.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* private headers */
|
|
Packit |
577717 |
#include "powerpc_reg.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "pfmlib_priv.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "pfmlib_power_priv.h"
|
|
Packit |
577717 |
#include "pfmlib_ppc970_priv.h"
|
|
Packit |
577717 |
#include "pfmlib_ppc970mp_priv.h"
|
|
Packit |
577717 |
#include "pfmlib_power4_priv.h"
|
|
Packit |
577717 |
#include "pfmlib_power5_priv.h"
|
|
Packit |
577717 |
#include "pfmlib_power5+_priv.h"
|
|
Packit |
577717 |
#include "pfmlib_power6_priv.h"
|
|
Packit |
577717 |
#include "pfmlib_power7_priv.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "ppc970_events.h"
|
|
Packit |
577717 |
#include "ppc970mp_events.h"
|
|
Packit |
577717 |
#include "power4_events.h"
|
|
Packit |
577717 |
#include "power5_events.h"
|
|
Packit |
577717 |
#include "power5+_events.h"
|
|
Packit |
577717 |
#include "power6_events.h"
|
|
Packit |
577717 |
#include "power7_events.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define FIRST_POWER_PMU PFMLIB_PPC970_PMU
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static const int num_group_vec[] = {
|
|
Packit |
577717 |
[PFMLIB_PPC970_PMU - FIRST_POWER_PMU] = PPC970_NUM_GROUP_VEC,
|
|
Packit |
577717 |
[PFMLIB_PPC970MP_PMU - FIRST_POWER_PMU] = PPC970MP_NUM_GROUP_VEC,
|
|
Packit |
577717 |
[PFMLIB_POWER4_PMU - FIRST_POWER_PMU] = POWER4_NUM_GROUP_VEC,
|
|
Packit |
577717 |
[PFMLIB_POWER5_PMU - FIRST_POWER_PMU] = POWER5_NUM_GROUP_VEC,
|
|
Packit |
577717 |
[PFMLIB_POWER5p_PMU - FIRST_POWER_PMU] = POWER5p_NUM_GROUP_VEC,
|
|
Packit |
577717 |
[PFMLIB_POWER6_PMU - FIRST_POWER_PMU] = POWER6_NUM_GROUP_VEC,
|
|
Packit |
577717 |
[PFMLIB_POWER7_PMU - FIRST_POWER_PMU] = POWER7_NUM_GROUP_VEC
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static const int event_count[] = {
|
|
Packit |
577717 |
[PFMLIB_PPC970_PMU - FIRST_POWER_PMU] = PPC970_PME_EVENT_COUNT,
|
|
Packit |
577717 |
[PFMLIB_PPC970MP_PMU - FIRST_POWER_PMU] = PPC970MP_PME_EVENT_COUNT,
|
|
Packit |
577717 |
[PFMLIB_POWER5_PMU - FIRST_POWER_PMU] = POWER5_PME_EVENT_COUNT,
|
|
Packit |
577717 |
[PFMLIB_POWER5p_PMU - FIRST_POWER_PMU] = POWER5p_PME_EVENT_COUNT,
|
|
Packit |
577717 |
[PFMLIB_POWER6_PMU - FIRST_POWER_PMU] = POWER6_PME_EVENT_COUNT,
|
|
Packit |
577717 |
[PFMLIB_POWER7_PMU - FIRST_POWER_PMU] = POWER7_PME_EVENT_COUNT
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
unsigned *pmd_priv_vec;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static unsigned long long mmcr0_fc5_6_mask;
|
|
Packit |
577717 |
static unsigned long long *mmcr0_counter_mask;
|
|
Packit |
577717 |
static unsigned long long *mmcr1_counter_mask;
|
|
Packit |
577717 |
static unsigned long long *mmcr0_counter_off_val;
|
|
Packit |
577717 |
static unsigned long long *mmcr1_counter_off_val;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static const pme_power_entry_t *pe;
|
|
Packit |
577717 |
static const pmg_power_group_t *groups;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline int get_num_event_counters() {
|
|
Packit |
577717 |
return gen_powerpc_support.pmd_count;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline int get_num_control_regs() {
|
|
Packit |
577717 |
return gen_powerpc_support.pmc_count;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline const unsigned long long *get_group_vector(int event) {
|
|
Packit |
577717 |
return pe[event].pme_group_vector;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline int get_event_id(int event, int counter) {
|
|
Packit |
577717 |
return pe[event].pme_event_ids[counter];
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline char *get_event_name(int event) {
|
|
Packit |
577717 |
return pe[event].pme_name;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline char *get_long_desc(int event) {
|
|
Packit |
577717 |
return pe[event].pme_long_desc;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline int get_group_event_id(int group, int counter) {
|
|
Packit |
577717 |
return groups[group].pmg_event_ids[counter];
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline unsigned long long get_mmcr0(int group) {
|
|
Packit |
577717 |
return groups[group].pmg_mmcr0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline unsigned long long get_mmcr1(int group) {
|
|
Packit |
577717 |
return groups[group].pmg_mmcr1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline unsigned long long get_mmcra(int group) {
|
|
Packit |
577717 |
return groups[group].pmg_mmcra;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_get_event_code
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Return the event-select value for the specified event as
|
|
Packit |
577717 |
* needed for the specified PMD counter.
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
static int pfm_gen_powerpc_get_event_code(unsigned int event,
|
|
Packit |
577717 |
unsigned int pmd,
|
|
Packit |
577717 |
int *code)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if (event < event_count[gen_powerpc_support.pmu_type - FIRST_POWER_PMU]) {
|
|
Packit |
577717 |
*code = pe[event].pme_code;
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
} else
|
|
Packit |
577717 |
return PFMLIB_ERR_INVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_get_event_name
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Return the name of the specified event.
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
static char *pfm_gen_powerpc_get_event_name(unsigned int event)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return get_event_name(event);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_get_event_mask_name
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Return the name of the specified event-mask.
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
static char *pfm_gen_powerpc_get_event_mask_name(unsigned int event, unsigned int mask)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return "";
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_get_event_counters
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Fill in the 'counters' bitmask with all possible PMDs that could be
|
|
Packit |
577717 |
* used to count the specified event.
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
static void pfm_gen_powerpc_get_event_counters(unsigned int event,
|
|
Packit |
577717 |
pfmlib_regmask_t *counters)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
counters->bits[0] = 0;
|
|
Packit |
577717 |
for (i = 0; i < get_num_event_counters(); i++) {
|
|
Packit |
577717 |
if (get_event_id(event, i) != -1) {
|
|
Packit |
577717 |
counters->bits[0] |= (1 << i);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_get_num_event_masks
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Count the number of available event-masks for the specified event.
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
static unsigned int pfm_gen_powerpc_get_num_event_masks(unsigned int event)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/* POWER arch doesn't use event masks */
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void remove_group(unsigned long long *group_vec, int group)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
group_vec[group / 64] &= ~(1ULL << (group % 64));
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void intersect_groups(unsigned long long *result, const unsigned long long *operand)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for (i = 0; i < num_group_vec[gen_powerpc_support.pmu_type - FIRST_POWER_PMU]; i++) {
|
|
Packit |
577717 |
result[i] &= operand[i];
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int first_group(unsigned long long *group_vec)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i, bit;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for (i = 0; i < num_group_vec[gen_powerpc_support.pmu_type - FIRST_POWER_PMU]; i++) {
|
|
Packit |
577717 |
bit = ffsll(group_vec[i]);
|
|
Packit |
577717 |
if (bit) {
|
|
Packit |
577717 |
return (bit - 1) + (i * 64);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/* There were no groups */
|
|
Packit |
577717 |
return -1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static unsigned gq_pmd_priv_vec[8] = {
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static unsigned gr_pmd_priv_vec[6] = {
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static unsigned gs_pmd_priv_vec[6] = {
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0f0e,
|
|
Packit |
577717 |
0x0800,
|
|
Packit |
577717 |
0x0800,
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* These masks are used on the PPC970*, and POWER4,4+ chips */
|
|
Packit |
577717 |
static unsigned long long power4_mmcr0_counter_mask[POWER4_NUM_EVENT_COUNTERS] = {
|
|
Packit |
577717 |
0x1fUL << (63 - 55), /* PMC1 */
|
|
Packit |
577717 |
0x1fUL << (63 - 62), /* PMC2 */
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
static unsigned long long power4_mmcr1_counter_mask[POWER4_NUM_EVENT_COUNTERS] = {
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0x1fUL << (63 - 36), /* PMC3 */
|
|
Packit |
577717 |
0x1fUL << (63 - 41), /* PMC4 */
|
|
Packit |
577717 |
0x1fUL << (63 - 46), /* PMC5 */
|
|
Packit |
577717 |
0x1fUL << (63 - 51), /* PMC6 */
|
|
Packit |
577717 |
0x1fUL << (63 - 56), /* PMC7 */
|
|
Packit |
577717 |
0x1fUL << (63 - 61) /* PMC8 */
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static unsigned long long power4_mmcr0_counter_off_val[POWER4_NUM_EVENT_COUNTERS] = {
|
|
Packit |
577717 |
0, /* PMC1 */
|
|
Packit |
577717 |
0, /* PMC2 */
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
static unsigned long long power4_mmcr1_counter_off_val[POWER4_NUM_EVENT_COUNTERS] = {
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0, /* PMC3 */
|
|
Packit |
577717 |
0, /* PMC4 */
|
|
Packit |
577717 |
0, /* PMC5 */
|
|
Packit |
577717 |
0, /* PMC6 */
|
|
Packit |
577717 |
0, /* PMC7 */
|
|
Packit |
577717 |
0 /* PMC8 */
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static unsigned long long ppc970_mmcr0_counter_off_val[POWER4_NUM_EVENT_COUNTERS] = {
|
|
Packit |
577717 |
0x8UL << (63 - 55), /* PMC1 */
|
|
Packit |
577717 |
0x8UL << (63 - 62), /* PMC2 */
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
static unsigned long long ppc970_mmcr1_counter_off_val[POWER4_NUM_EVENT_COUNTERS] = {
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0x8UL << (63 - 36), /* PMC3 */
|
|
Packit |
577717 |
0x8UL << (63 - 41), /* PMC4 */
|
|
Packit |
577717 |
0x8UL << (63 - 46), /* PMC5 */
|
|
Packit |
577717 |
0x8UL << (63 - 51), /* PMC6 */
|
|
Packit |
577717 |
0x8UL << (63 - 56), /* PMC7 */
|
|
Packit |
577717 |
0x8UL << (63 - 61) /* PMC8 */
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* These masks are used on POWER5,5+,5++,6,7 */
|
|
Packit |
577717 |
static unsigned long long power5_mmcr0_counter_mask[POWER5_NUM_EVENT_COUNTERS] = {
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
static unsigned long long power5_mmcr1_counter_mask[POWER5_NUM_EVENT_COUNTERS] = {
|
|
Packit |
577717 |
0xffUL << (63 - 39), /* PMC1 */
|
|
Packit |
577717 |
0xffUL << (63 - 47), /* PMC2 */
|
|
Packit |
577717 |
0xffUL << (63 - 55), /* PMC3 */
|
|
Packit |
577717 |
0xffUL << (63 - 63), /* PMC4 */
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static unsigned long long power5_mmcr0_counter_off_val[POWER5_NUM_EVENT_COUNTERS] = {
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static unsigned long long power5_mmcr1_counter_off_val[POWER5_NUM_EVENT_COUNTERS] = {
|
|
Packit |
577717 |
0, /* PMC1 */
|
|
Packit |
577717 |
0, /* PMC2 */
|
|
Packit |
577717 |
0, /* PMC3 */
|
|
Packit |
577717 |
0, /* PMC4 */
|
|
Packit |
577717 |
0,
|
|
Packit |
577717 |
0
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_dispatch_events
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Examine each desired event specified in "input" and find an appropriate
|
|
Packit |
577717 |
* set of PMCs and PMDs to count them.
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
static int pfm_gen_powerpc_dispatch_events(pfmlib_input_param_t *input,
|
|
Packit |
577717 |
void *model_input,
|
|
Packit |
577717 |
pfmlib_output_param_t *output,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void *model_output)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/* model_input and model_output are unused on POWER */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int i, j, group;
|
|
Packit |
577717 |
int counters_used = 0;
|
|
Packit |
577717 |
unsigned long long mmcr0_val, mmcr1_val;
|
|
Packit |
577717 |
unsigned long long group_vector[num_group_vec[gen_powerpc_support.pmu_type - FIRST_POWER_PMU]];
|
|
Packit |
577717 |
unsigned int plm;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
plm = (input->pfp_events[0].plm != 0) ? input->pfp_events[0].plm : input->pfp_dfl_plm;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Verify that all of the privilege level masks are identical, as
|
|
Packit |
577717 |
* we cannot have mixed levels on POWER
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for (i = 1; i < input->pfp_event_count; i++) {
|
|
Packit |
577717 |
if (input->pfp_events[i].plm == 0) {
|
|
Packit |
577717 |
/* it's ok if the default is the same as plm */
|
|
Packit |
577717 |
if (plm != input->pfp_dfl_plm)
|
|
Packit |
577717 |
return PFMLIB_ERR_NOASSIGN;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
if (plm != input->pfp_events[i].plm)
|
|
Packit |
577717 |
return PFMLIB_ERR_NOASSIGN;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* start by setting all of the groups as available */
|
|
Packit |
577717 |
memset(group_vector, 0xff, sizeof(unsigned long long) * num_group_vec[gen_powerpc_support.pmu_type - FIRST_POWER_PMU]);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for (i = 0; i < input->pfp_event_count; i++) {
|
|
Packit |
577717 |
mmcr0_val |= mmcr0_counter_off_val[i];
|
|
Packit |
577717 |
intersect_groups(group_vector, get_group_vector(input->pfp_events[i].event));
|
|
Packit |
577717 |
mmcr1_val |= mmcr1_counter_off_val[i];
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
group = first_group(group_vector);
|
|
Packit |
577717 |
while (group != -1) {
|
|
Packit |
577717 |
/* find out if the the privilege levels are compatible with each counter */
|
|
Packit |
577717 |
for (i = 0; i < input->pfp_event_count; i++) {
|
|
Packit |
577717 |
/* find event counter in group */
|
|
Packit |
577717 |
for (j = 0; j < get_num_event_counters(); j++) {
|
|
Packit |
577717 |
if (get_event_id(input->pfp_events[i].event,j) == get_group_event_id(group, j)) {
|
|
Packit |
577717 |
/* found counter */
|
|
Packit |
577717 |
if (input->pfp_events[i].plm != 0) {
|
|
Packit |
577717 |
if (! (pmd_priv_vec[j] & (1 << input->pfp_events[0].plm))) {
|
|
Packit |
577717 |
remove_group(group_vector, group);
|
|
Packit |
577717 |
group = first_group(group_vector);
|
|
Packit |
577717 |
goto try_next_group;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
if (! (pmd_priv_vec[j] & (1 << input->pfp_dfl_plm))) {
|
|
Packit |
577717 |
remove_group(group_vector, group);
|
|
Packit |
577717 |
group = first_group(group_vector);
|
|
Packit |
577717 |
goto try_next_group;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/* We located this counter and its privilege checks out ok. */
|
|
Packit |
577717 |
counters_used |= (1 << j);
|
|
Packit |
577717 |
output->pfp_pmds[i].reg_value = 0;
|
|
Packit |
577717 |
output->pfp_pmds[i].reg_addr = 0;
|
|
Packit |
577717 |
output->pfp_pmds[i].reg_alt_addr = 0;
|
|
Packit |
577717 |
output->pfp_pmds[i].reg_num = j + 1;
|
|
Packit |
577717 |
output->pfp_pmds[i].reg_reserved1 = 0;
|
|
Packit |
577717 |
output->pfp_pmd_count = i + 1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Find the next counter */
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (j == get_num_event_counters()) {
|
|
Packit |
577717 |
printf ("libpfm: Internal error. Unable to find counter in group.\n");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Success! We found a group (group) that meets the
|
|
Packit |
577717 |
* privilege constraints
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
try_next_group: ;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (group == -1)
|
|
Packit |
577717 |
/* We did not find a group that meets the constraints */
|
|
Packit |
577717 |
return PFMLIB_ERR_NOASSIGN;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* We now have a group that meets the constraints */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
mmcr0_val = get_mmcr0(group);
|
|
Packit |
577717 |
mmcr1_val = get_mmcr1(group);
|
|
Packit |
577717 |
for (i = 0; i < get_num_event_counters(); i++) {
|
|
Packit |
577717 |
if (! (counters_used & (1 << i))) {
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* This counter is not used, so set that
|
|
Packit |
577717 |
* selector to its off value.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
mmcr0_val &= ~mmcr0_counter_mask[i];
|
|
Packit |
577717 |
mmcr0_val |= mmcr0_counter_off_val[i];
|
|
Packit |
577717 |
mmcr1_val &= ~mmcr1_counter_mask[i];
|
|
Packit |
577717 |
mmcr1_val |= mmcr1_counter_off_val[i];
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* As a special case for PMC5 and PMC6 on POWER5/5+, freeze these
|
|
Packit |
577717 |
* two counters if neither are used. Note that the
|
|
Packit |
577717 |
* mmcr0_fc5_6_mask is zero for all processors except POWER5/5+
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if ((counters_used & ((1 << (5 - 1)) | (1 << (6 - 1)))) == 0)
|
|
Packit |
577717 |
mmcr0_val |= mmcr0_fc5_6_mask;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Enable counter "exception on negative" and performance monitor
|
|
Packit |
577717 |
* exceptions
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
mmcr0_val |= MMCR0_PMXE | MMCR0_PMC1CE | MMCR0_PMCjCE;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Start with the counters frozen in every state, then selectively
|
|
Packit |
577717 |
enable them */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
mmcr0_val |= MMCR0_FCP | MMCR0_FCS | MMCR0_FCHV;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (plm & PFM_PLM3) {
|
|
Packit |
577717 |
/* user */
|
|
Packit |
577717 |
mmcr0_val &= ~MMCR0_FCP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (plm & PFM_PLM0) {
|
|
Packit |
577717 |
/* kernel */
|
|
Packit |
577717 |
mmcr0_val &= ~MMCR0_FCS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (plm & PFM_PLM1) {
|
|
Packit |
577717 |
/* hypervisor */
|
|
Packit |
577717 |
mmcr0_val &= ~MMCR0_FCHV;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/* PFM_PLM2 is not supported */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
output->pfp_pmcs[0].reg_value = mmcr0_val;
|
|
Packit |
577717 |
output->pfp_pmcs[0].reg_addr = 0;
|
|
Packit |
577717 |
output->pfp_pmcs[0].reg_alt_addr = 0;
|
|
Packit |
577717 |
output->pfp_pmcs[0].reg_num = 0;
|
|
Packit |
577717 |
output->pfp_pmcs[0].reg_reserved1 = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
output->pfp_pmcs[1].reg_value = mmcr1_val;
|
|
Packit |
577717 |
output->pfp_pmcs[1].reg_addr = 0;
|
|
Packit |
577717 |
output->pfp_pmcs[1].reg_alt_addr = 0;
|
|
Packit |
577717 |
output->pfp_pmcs[1].reg_num = 1;
|
|
Packit |
577717 |
output->pfp_pmcs[1].reg_reserved1 = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
output->pfp_pmcs[2].reg_value = get_mmcra(group);
|
|
Packit |
577717 |
output->pfp_pmcs[2].reg_addr = 0;
|
|
Packit |
577717 |
output->pfp_pmcs[2].reg_alt_addr = 0;
|
|
Packit |
577717 |
output->pfp_pmcs[2].reg_num = 2;
|
|
Packit |
577717 |
output->pfp_pmcs[2].reg_reserved1 = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* We always use the same number of control regs */
|
|
Packit |
577717 |
output->pfp_pmc_count = get_num_control_regs();
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_pmu_detect
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Determine which POWER processor, if any, we are running on.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* These should be defined in more recent versions of
|
|
Packit |
577717 |
* /usr/include/asm-ppc64/reg.h. It isn't pretty to have these here, but
|
|
Packit |
577717 |
* maybe we can remove them someday.
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int pfm_gen_powerpc_pmu_detect(void)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if (__is_processor(PV_970) || __is_processor(PV_970FX) || __is_processor(PV_970GX)) {
|
|
Packit |
577717 |
gen_powerpc_support.pmu_type = PFMLIB_PPC970_PMU;
|
|
Packit |
577717 |
gen_powerpc_support.pmu_name = "PPC970";
|
|
Packit |
577717 |
gen_powerpc_support.pme_count = PPC970_PME_EVENT_COUNT;
|
|
Packit |
577717 |
gen_powerpc_support.pmd_count = PPC970_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
gen_powerpc_support.pmc_count = PPC970_NUM_CONTROL_REGS;
|
|
Packit |
577717 |
gen_powerpc_support.num_cnt = PPC970_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
mmcr0_fc5_6_mask = 0;
|
|
Packit |
577717 |
mmcr0_counter_mask = power4_mmcr0_counter_mask;
|
|
Packit |
577717 |
mmcr1_counter_mask = power4_mmcr1_counter_mask;
|
|
Packit |
577717 |
mmcr0_counter_off_val = ppc970_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = ppc970_mmcr1_counter_off_val;
|
|
Packit |
577717 |
pmd_priv_vec = gq_pmd_priv_vec;
|
|
Packit |
577717 |
pe = ppc970_pe;
|
|
Packit |
577717 |
groups = ppc970_groups;
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (__is_processor(PV_970MP)) {
|
|
Packit |
577717 |
gen_powerpc_support.pmu_type = PFMLIB_PPC970MP_PMU;
|
|
Packit |
577717 |
gen_powerpc_support.pmu_name = "PPC970MP";
|
|
Packit |
577717 |
gen_powerpc_support.pme_count = PPC970MP_PME_EVENT_COUNT;
|
|
Packit |
577717 |
gen_powerpc_support.pmd_count = PPC970MP_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
gen_powerpc_support.pmc_count = PPC970MP_NUM_CONTROL_REGS;
|
|
Packit |
577717 |
gen_powerpc_support.num_cnt = PPC970MP_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
mmcr0_fc5_6_mask = 0;
|
|
Packit |
577717 |
mmcr0_counter_mask = power4_mmcr0_counter_mask;
|
|
Packit |
577717 |
mmcr1_counter_mask = power4_mmcr1_counter_mask;
|
|
Packit |
577717 |
mmcr0_counter_off_val = ppc970_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = ppc970_mmcr1_counter_off_val;
|
|
Packit |
577717 |
pmd_priv_vec = gq_pmd_priv_vec;
|
|
Packit |
577717 |
pe = ppc970mp_pe;
|
|
Packit |
577717 |
groups = ppc970mp_groups;
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
|
|
Packit |
577717 |
gen_powerpc_support.pmu_type = PFMLIB_PPC970_PMU;
|
|
Packit |
577717 |
gen_powerpc_support.pmu_name = "POWER4";
|
|
Packit |
577717 |
gen_powerpc_support.pme_count = POWER4_PME_EVENT_COUNT;
|
|
Packit |
577717 |
gen_powerpc_support.pmd_count = POWER4_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
gen_powerpc_support.pmc_count = POWER4_NUM_CONTROL_REGS;
|
|
Packit |
577717 |
gen_powerpc_support.num_cnt = POWER4_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
mmcr0_fc5_6_mask = 0;
|
|
Packit |
577717 |
mmcr0_counter_mask = power4_mmcr0_counter_mask;
|
|
Packit |
577717 |
mmcr1_counter_mask = power4_mmcr1_counter_mask;
|
|
Packit |
577717 |
mmcr0_counter_off_val = ppc970_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = ppc970_mmcr1_counter_off_val;
|
|
Packit |
577717 |
mmcr0_counter_off_val = power4_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = power4_mmcr1_counter_off_val;
|
|
Packit |
577717 |
pmd_priv_vec = gq_pmd_priv_vec;
|
|
Packit |
577717 |
pe = power4_pe;
|
|
Packit |
577717 |
groups = power4_groups;
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (__is_processor(PV_POWER5)) {
|
|
Packit |
577717 |
gen_powerpc_support.pmu_type = PFMLIB_POWER5_PMU;
|
|
Packit |
577717 |
gen_powerpc_support.pmu_name = "POWER5";
|
|
Packit |
577717 |
gen_powerpc_support.pme_count = POWER5_PME_EVENT_COUNT;
|
|
Packit |
577717 |
gen_powerpc_support.pmd_count = POWER5_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
gen_powerpc_support.pmc_count = POWER5_NUM_CONTROL_REGS;
|
|
Packit |
577717 |
gen_powerpc_support.num_cnt = POWER5_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
mmcr0_fc5_6_mask = MMCR0_FC5_6;
|
|
Packit |
577717 |
mmcr0_counter_off_val = ppc970_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = ppc970_mmcr1_counter_off_val;
|
|
Packit |
577717 |
mmcr0_counter_mask = power5_mmcr0_counter_mask;
|
|
Packit |
577717 |
mmcr1_counter_mask = power5_mmcr1_counter_mask;
|
|
Packit |
577717 |
mmcr0_counter_off_val = power5_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = power5_mmcr1_counter_off_val;
|
|
Packit |
577717 |
pmd_priv_vec = gr_pmd_priv_vec;
|
|
Packit |
577717 |
pe = power5_pe;
|
|
Packit |
577717 |
groups = power5_groups;
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (__is_processor(PV_POWER5p)) {
|
|
Packit |
577717 |
gen_powerpc_support.pmu_type = PFMLIB_POWER5p_PMU;
|
|
Packit |
577717 |
gen_powerpc_support.pmu_name = "POWER5+";
|
|
Packit |
577717 |
gen_powerpc_support.pme_count = POWER5p_PME_EVENT_COUNT;
|
|
Packit |
577717 |
gen_powerpc_support.pmd_count = POWER5p_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
gen_powerpc_support.pmc_count = POWER5p_NUM_CONTROL_REGS;
|
|
Packit |
577717 |
mmcr0_counter_off_val = power4_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = power4_mmcr1_counter_off_val;
|
|
Packit |
577717 |
gen_powerpc_support.num_cnt = POWER5p_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
mmcr0_counter_mask = power5_mmcr0_counter_mask;
|
|
Packit |
577717 |
mmcr1_counter_mask = power5_mmcr1_counter_mask;
|
|
Packit |
577717 |
mmcr0_counter_off_val = power5_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = power5_mmcr1_counter_off_val;
|
|
Packit |
577717 |
if (PVR_VER(mfspr(SPRN_PVR)) >= 0x300) {
|
|
Packit |
577717 |
/* this is a newer, GS model POWER5+ */
|
|
Packit |
577717 |
mmcr0_fc5_6_mask = 0;
|
|
Packit |
577717 |
pmd_priv_vec = gs_pmd_priv_vec;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
mmcr0_fc5_6_mask = MMCR0_FC5_6;
|
|
Packit |
577717 |
pmd_priv_vec = gr_pmd_priv_vec;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
mmcr0_counter_off_val = power5_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = power5_mmcr1_counter_off_val;
|
|
Packit |
577717 |
pe = power5p_pe;
|
|
Packit |
577717 |
groups = power5p_groups;
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (__is_processor(PV_POWER6)) {
|
|
Packit |
577717 |
gen_powerpc_support.pmu_type = PFMLIB_POWER6_PMU;
|
|
Packit |
577717 |
gen_powerpc_support.pmu_name = "POWER6";
|
|
Packit |
577717 |
gen_powerpc_support.pme_count = POWER6_PME_EVENT_COUNT;
|
|
Packit |
577717 |
gen_powerpc_support.pmd_count = POWER6_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
gen_powerpc_support.pmc_count = POWER6_NUM_CONTROL_REGS;
|
|
Packit |
577717 |
gen_powerpc_support.num_cnt = POWER6_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
mmcr0_fc5_6_mask = 0;
|
|
Packit |
577717 |
mmcr0_counter_mask = power5_mmcr0_counter_mask;
|
|
Packit |
577717 |
mmcr1_counter_mask = power5_mmcr1_counter_mask;
|
|
Packit |
577717 |
mmcr0_counter_off_val = power5_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = power5_mmcr1_counter_off_val;
|
|
Packit |
577717 |
mmcr0_counter_off_val = power5_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = power5_mmcr1_counter_off_val;
|
|
Packit |
577717 |
pmd_priv_vec = gs_pmd_priv_vec;
|
|
Packit |
577717 |
pe = power6_pe;
|
|
Packit |
577717 |
groups = power6_groups;
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (__is_processor(PV_POWER7)) {
|
|
Packit |
577717 |
gen_powerpc_support.pmu_type = PFMLIB_POWER7_PMU;
|
|
Packit |
577717 |
gen_powerpc_support.pmu_name = "POWER7";
|
|
Packit |
577717 |
gen_powerpc_support.pme_count = POWER7_PME_EVENT_COUNT;
|
|
Packit |
577717 |
gen_powerpc_support.pmd_count = POWER7_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
gen_powerpc_support.pmc_count = POWER7_NUM_CONTROL_REGS;
|
|
Packit |
577717 |
gen_powerpc_support.num_cnt = POWER7_NUM_EVENT_COUNTERS;
|
|
Packit |
577717 |
mmcr0_fc5_6_mask = 0;
|
|
Packit |
577717 |
mmcr0_counter_mask = power5_mmcr0_counter_mask;
|
|
Packit |
577717 |
mmcr1_counter_mask = power5_mmcr1_counter_mask;
|
|
Packit |
577717 |
mmcr0_counter_off_val = power5_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = power5_mmcr1_counter_off_val;
|
|
Packit |
577717 |
mmcr0_counter_off_val = power5_mmcr0_counter_off_val;
|
|
Packit |
577717 |
mmcr1_counter_off_val = power5_mmcr1_counter_off_val;
|
|
Packit |
577717 |
pmd_priv_vec = gr_pmd_priv_vec;
|
|
Packit |
577717 |
pe = power7_pe;
|
|
Packit |
577717 |
groups = power7_groups;
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PFMLIB_ERR_NOTSUPP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_get_impl_pmcs
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Set the appropriate bit in the impl_pmcs bitmask for each PMC that's
|
|
Packit |
577717 |
* available on power4.
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
static void pfm_gen_powerpc_get_impl_pmcs(pfmlib_regmask_t *impl_pmcs)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
impl_pmcs->bits[0] = (0xffffffff >> (32 - get_num_control_regs()));
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_get_impl_pmds
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
|
|
Packit |
577717 |
* Set the appropriate bit in the impl_pmcs bitmask for each PMD that's
|
|
Packit |
577717 |
* available.
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
static void pfm_gen_powerpc_get_impl_pmds(pfmlib_regmask_t *impl_pmds)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
impl_pmds->bits[0] = (0xffffffff >> (32 - get_num_event_counters()));
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_get_impl_counters
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Set the appropriate bit in the impl_counters bitmask for each counter
|
|
Packit |
577717 |
* that's available on power4.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* For now, all PMDs are counters, so just call get_impl_pmds().
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
static void pfm_gen_powerpc_get_impl_counters(pfmlib_regmask_t *impl_counters)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
pfm_gen_powerpc_get_impl_pmds(impl_counters);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_get_hw_counter_width
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Return the number of usable bits in the PMD counters.
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
static void pfm_gen_powerpc_get_hw_counter_width(unsigned int *width)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
*width = 64;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_get_event_desc
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Return the description for the specified event (if it has one).
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
static int pfm_gen_powerpc_get_event_desc(unsigned int event, char **desc)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
*desc = strdup(get_long_desc(event));
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* pfm_gen_powerpc_get_event_mask_desc
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Return the description for the specified event-mask (if it has one).
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
static int pfm_gen_powerpc_get_event_mask_desc(unsigned int event,
|
|
Packit |
577717 |
unsigned int mask, char **desc)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
*desc = strdup("");
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int pfm_gen_powerpc_get_event_mask_code(unsigned int event,
|
|
Packit |
577717 |
unsigned int mask, unsigned int *code)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
*code = 0;
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_gen_powerpc_get_cycle_event(pfmlib_event_t *e)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
switch (gen_powerpc_support.pmu_type) {
|
|
Packit |
577717 |
case PFMLIB_PPC970_PMU:
|
|
Packit |
577717 |
e->event = PPC970_PME_PM_CYC;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PFMLIB_PPC970MP_PMU:
|
|
Packit |
577717 |
e->event = PPC970MP_PME_PM_CYC;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PFMLIB_POWER4_PMU:
|
|
Packit |
577717 |
e->event = POWER4_PME_PM_CYC;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PFMLIB_POWER5_PMU:
|
|
Packit |
577717 |
e->event = POWER5_PME_PM_CYC;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PFMLIB_POWER5p_PMU:
|
|
Packit |
577717 |
e->event = POWER5p_PME_PM_RUN_CYC;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PFMLIB_POWER6_PMU:
|
|
Packit |
577717 |
e->event = POWER6_PME_PM_RUN_CYC;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PFMLIB_POWER7_PMU:
|
|
Packit |
577717 |
e->event = POWER7_PME_PM_RUN_CYC;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
/* perhaps gen_powerpc_suport.pmu_type wasn't initialized? */
|
|
Packit |
577717 |
return PFMLIB_ERR_NOINIT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
e->num_masks = 0;
|
|
Packit |
577717 |
e->unit_masks[0] = 0;
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_gen_powerpc_get_inst_retired(pfmlib_event_t *e)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
switch (gen_powerpc_support.pmu_type) {
|
|
Packit |
577717 |
case PFMLIB_PPC970_PMU:
|
|
Packit |
577717 |
e->event = PPC970_PME_PM_INST_CMPL;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PFMLIB_PPC970MP_PMU:
|
|
Packit |
577717 |
e->event = PPC970MP_PME_PM_INST_CMPL;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PFMLIB_POWER4_PMU:
|
|
Packit |
577717 |
e->event = POWER4_PME_PM_INST_CMPL;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PFMLIB_POWER5_PMU:
|
|
Packit |
577717 |
e->event = POWER5_PME_PM_INST_CMPL;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PFMLIB_POWER5p_PMU:
|
|
Packit |
577717 |
e->event = POWER5p_PME_PM_INST_CMPL;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PFMLIB_POWER6_PMU:
|
|
Packit |
577717 |
e->event = POWER6_PME_PM_INST_CMPL;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PFMLIB_POWER7_PMU:
|
|
Packit |
577717 |
e->event = POWER7_PME_PM_INST_CMPL;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
/* perhaps gen_powerpc_suport.pmu_type wasn't initialized? */
|
|
Packit |
577717 |
return PFMLIB_ERR_NOINIT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
e->num_masks = 0;
|
|
Packit |
577717 |
e->unit_masks[0] = 0;
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* gen_powerpc_support
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
pfm_pmu_support_t gen_powerpc_support = {
|
|
Packit |
577717 |
/* the next 6 fields are initialized in pfm_gen_powerpc_pmu_detect */
|
|
Packit |
577717 |
.pmu_name = NULL,
|
|
Packit |
577717 |
.pmu_type = PFMLIB_UNKNOWN_PMU,
|
|
Packit |
577717 |
.pme_count = 0,
|
|
Packit |
577717 |
.pmd_count = 0,
|
|
Packit |
577717 |
.pmc_count = 0,
|
|
Packit |
577717 |
.num_cnt = 0,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
.get_event_code = pfm_gen_powerpc_get_event_code,
|
|
Packit |
577717 |
.get_event_name = pfm_gen_powerpc_get_event_name,
|
|
Packit |
577717 |
.get_event_mask_name = pfm_gen_powerpc_get_event_mask_name,
|
|
Packit |
577717 |
.get_event_counters = pfm_gen_powerpc_get_event_counters,
|
|
Packit |
577717 |
.get_num_event_masks = pfm_gen_powerpc_get_num_event_masks,
|
|
Packit |
577717 |
.dispatch_events = pfm_gen_powerpc_dispatch_events,
|
|
Packit |
577717 |
.pmu_detect = pfm_gen_powerpc_pmu_detect,
|
|
Packit |
577717 |
.get_impl_pmcs = pfm_gen_powerpc_get_impl_pmcs,
|
|
Packit |
577717 |
.get_impl_pmds = pfm_gen_powerpc_get_impl_pmds,
|
|
Packit |
577717 |
.get_impl_counters = pfm_gen_powerpc_get_impl_counters,
|
|
Packit |
577717 |
.get_hw_counter_width = pfm_gen_powerpc_get_hw_counter_width,
|
|
Packit |
577717 |
.get_event_desc = pfm_gen_powerpc_get_event_desc,
|
|
Packit |
577717 |
.get_event_mask_desc = pfm_gen_powerpc_get_event_mask_desc,
|
|
Packit |
577717 |
.get_event_mask_code = pfm_gen_powerpc_get_event_mask_code,
|
|
Packit |
577717 |
.get_cycle_event = pfm_gen_powerpc_get_cycle_event,
|
|
Packit |
577717 |
.get_inst_retired_event = pfm_gen_powerpc_get_inst_retired
|
|
Packit |
577717 |
};
|