|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Copyright (C) 2007 David S. Miller (davem@davemloft.net)
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Based upon gen_powerpc code which is:
|
|
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_sparc.c
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Support for libpfm for Sparc 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 |
/* private headers */
|
|
Packit |
577717 |
#include "pfmlib_priv.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "pfmlib_sparc_priv.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "ultra12_events.h"
|
|
Packit |
577717 |
#include "ultra3_events.h"
|
|
Packit |
577717 |
#include "ultra3i_events.h"
|
|
Packit |
577717 |
#include "ultra3plus_events.h"
|
|
Packit |
577717 |
#include "ultra4plus_events.h"
|
|
Packit |
577717 |
#include "niagara1_events.h"
|
|
Packit |
577717 |
#include "niagara2_events.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static char *get_event_name(int event)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
switch (sparc_support.pmu_type) {
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA12_PMU:
|
|
Packit |
577717 |
return ultra12_pe[event].pme_name;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3_PMU:
|
|
Packit |
577717 |
return ultra3_pe[event].pme_name;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3I_PMU:
|
|
Packit |
577717 |
return ultra3i_pe[event].pme_name;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3PLUS_PMU:
|
|
Packit |
577717 |
return ultra3plus_pe[event].pme_name;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA4PLUS_PMU:
|
|
Packit |
577717 |
return ultra4plus_pe[event].pme_name;
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA1_PMU:
|
|
Packit |
577717 |
return niagara1_pe[event].pme_name;
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA2_PMU:
|
|
Packit |
577717 |
return niagara2_pe[event].pme_name;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return (char *)-1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static char *get_event_desc(int event)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
switch (sparc_support.pmu_type) {
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA12_PMU:
|
|
Packit |
577717 |
return ultra12_pe[event].pme_desc;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3_PMU:
|
|
Packit |
577717 |
return ultra3_pe[event].pme_desc;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3I_PMU:
|
|
Packit |
577717 |
return ultra3i_pe[event].pme_desc;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3PLUS_PMU:
|
|
Packit |
577717 |
return ultra3plus_pe[event].pme_desc;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA4PLUS_PMU:
|
|
Packit |
577717 |
return ultra4plus_pe[event].pme_desc;
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA1_PMU:
|
|
Packit |
577717 |
return niagara1_pe[event].pme_desc;
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA2_PMU:
|
|
Packit |
577717 |
return niagara2_pe[event].pme_desc;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return (char *)-1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static char get_ctrl(int event)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
switch (sparc_support.pmu_type) {
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA12_PMU:
|
|
Packit |
577717 |
return ultra12_pe[event].pme_ctrl;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3_PMU:
|
|
Packit |
577717 |
return ultra3_pe[event].pme_ctrl;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3I_PMU:
|
|
Packit |
577717 |
return ultra3i_pe[event].pme_ctrl;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3PLUS_PMU:
|
|
Packit |
577717 |
return ultra3plus_pe[event].pme_ctrl;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA4PLUS_PMU:
|
|
Packit |
577717 |
return ultra4plus_pe[event].pme_ctrl;
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA1_PMU:
|
|
Packit |
577717 |
return niagara1_pe[event].pme_ctrl;
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA2_PMU:
|
|
Packit |
577717 |
return niagara2_pe[event].pme_ctrl;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return 0xff;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int get_val(int event)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
switch (sparc_support.pmu_type) {
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA12_PMU:
|
|
Packit |
577717 |
return ultra12_pe[event].pme_val;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3_PMU:
|
|
Packit |
577717 |
return ultra3_pe[event].pme_val;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3I_PMU:
|
|
Packit |
577717 |
return ultra3i_pe[event].pme_val;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3PLUS_PMU:
|
|
Packit |
577717 |
return ultra3plus_pe[event].pme_val;
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA4PLUS_PMU:
|
|
Packit |
577717 |
return ultra4plus_pe[event].pme_val;
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA1_PMU:
|
|
Packit |
577717 |
return niagara1_pe[event].pme_val;
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA2_PMU:
|
|
Packit |
577717 |
return niagara2_pe[event].pme_val;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return -1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int pfm_sparc_get_event_code(unsigned int event,
|
|
Packit |
577717 |
unsigned int pmd,
|
|
Packit |
577717 |
int *code)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
*code = get_val(event);
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static char *pfm_sparc_get_event_name(unsigned int event)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return get_event_name(event);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static char *pfm_sparc_get_event_mask_name(unsigned int event,
|
|
Packit |
577717 |
unsigned int mask)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
pme_sparc_mask_entry_t *e;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (sparc_support.pmu_type != PFMLIB_SPARC_NIAGARA2_PMU)
|
|
Packit |
577717 |
return "";
|
|
Packit |
577717 |
|
|
Packit |
577717 |
e = &niagara2_pe[event];
|
|
Packit |
577717 |
return e->pme_masks[mask].mask_name;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void pfm_sparc_get_event_counters(unsigned int event,
|
|
Packit |
577717 |
pfmlib_regmask_t *counters)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if (sparc_support.pmu_type == PFMLIB_SPARC_NIAGARA2_PMU) {
|
|
Packit |
577717 |
counters->bits[0] = (1 << 0) | (1 << 1);
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
char ctrl = get_ctrl(event);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
counters->bits[0] = 0;
|
|
Packit |
577717 |
if (ctrl & PME_CTRL_S0)
|
|
Packit |
577717 |
counters->bits[0] |= (1 << 0);
|
|
Packit |
577717 |
if (ctrl & PME_CTRL_S1)
|
|
Packit |
577717 |
counters->bits[0] |= (1 << 1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static unsigned int pfm_sparc_get_num_event_masks(unsigned int event)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if (sparc_support.pmu_type != PFMLIB_SPARC_NIAGARA2_PMU)
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
return (event == 0 ? 0 : EVENT_MASK_BITS);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Bits common to all PCR implementations */
|
|
Packit |
577717 |
#define PCR_PRIV (0x1UL << 0)
|
|
Packit |
577717 |
#define PCR_SYS_TRACE (0x1UL << 1)
|
|
Packit |
577717 |
#define PCR_USER_TRACE (0x1UL << 2)
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* The S0 and S1 fields determine which events are monitored in
|
|
Packit |
577717 |
* the assosciated PIC (PIC0 vs. PIC1 respectively). For ultra12
|
|
Packit |
577717 |
* these fields are 4 bits, on ultra3/3i/3+/4+ they are 6 bits.
|
|
Packit |
577717 |
* For Niagara-1 there is only S0 and it is 3 bits in size.
|
|
Packit |
577717 |
* Niagara-1's PIC1 is hard-coded to record retired instructions.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
#define PCR_S0_SHIFT 4
|
|
Packit |
577717 |
#define PCR_S0 (0x1fUL << PCR_S0_SHIFT)
|
|
Packit |
577717 |
#define PCR_S1_SHIFT 11
|
|
Packit |
577717 |
#define PCR_S1 (0x1fUL << PCR_S1_SHIFT)
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Niagara-2 specific PCR bits. It supports event masking. */
|
|
Packit |
577717 |
#define PCR_N2_HYP_TRACE (0x1UL << 3)
|
|
Packit |
577717 |
#define PCR_N2_TOE0 (0x1UL << 4)
|
|
Packit |
577717 |
#define PCR_N2_TOE1 (0x1UL << 5)
|
|
Packit |
577717 |
#define PCR_N2_SL0_SHIFT 14
|
|
Packit |
577717 |
#define PCR_N2_SL0 (0xf << PCR_N2_SL0_SHIFT)
|
|
Packit |
577717 |
#define PCR_N2_MASK0_SHIFT 6
|
|
Packit |
577717 |
#define PCR_N2_MASK0 (0xff << PCR_N2_MASK0_SHIFT)
|
|
Packit |
577717 |
#define PCR_N2_SL1_SHIFT 27
|
|
Packit |
577717 |
#define PCR_N2_SL1 (0xf << PCR_N2_SL1_SHIFT)
|
|
Packit |
577717 |
#define PCR_N2_MASK1_SHIFT 19
|
|
Packit |
577717 |
#define PCR_N2_MASK1 (0xff << PCR_N2_MASK1_SHIFT)
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int pfm_sparc_dispatch_events(pfmlib_input_param_t *input,
|
|
Packit |
577717 |
void *model_input,
|
|
Packit |
577717 |
pfmlib_output_param_t *output,
|
|
Packit |
577717 |
void *model_output)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned long long pcr, vals[2];
|
|
Packit |
577717 |
unsigned int plm, i;
|
|
Packit |
577717 |
int niagara2;
|
|
Packit |
577717 |
char ctrls[2];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (input->pfp_event_count > 2)
|
|
Packit |
577717 |
return PFMLIB_ERR_TOOMANY;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
plm = ((input->pfp_events[0].plm != 0) ?
|
|
Packit |
577717 |
input->pfp_events[0].plm :
|
|
Packit |
577717 |
input->pfp_dfl_plm);
|
|
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 |
niagara2 = 0;
|
|
Packit |
577717 |
if (sparc_support.pmu_type == PFMLIB_SPARC_NIAGARA2_PMU)
|
|
Packit |
577717 |
niagara2 = 1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
pcr = 0;
|
|
Packit |
577717 |
if (plm & PFM_PLM3)
|
|
Packit |
577717 |
pcr |= PCR_USER_TRACE;
|
|
Packit |
577717 |
if (plm & PFM_PLM0)
|
|
Packit |
577717 |
pcr |= PCR_SYS_TRACE;
|
|
Packit |
577717 |
if (niagara2 && (plm & PFM_PLM1))
|
|
Packit |
577717 |
pcr |= PCR_N2_HYP_TRACE;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for (i = 0; i < input->pfp_event_count; i++) {
|
|
Packit |
577717 |
pfmlib_event_t *e = &input->pfp_events[i];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ctrls[i] = get_ctrl(e->event);
|
|
Packit |
577717 |
vals[i] = get_val(e->event);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (i == 1) {
|
|
Packit |
577717 |
if ((ctrls[0] & ctrls[1]) == 0)
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (ctrls[0] == (PME_CTRL_S0|PME_CTRL_S1)) {
|
|
Packit |
577717 |
if (ctrls[1] == (PME_CTRL_S0|PME_CTRL_S1)) {
|
|
Packit |
577717 |
ctrls[0] = PME_CTRL_S0;
|
|
Packit |
577717 |
ctrls[1] = PME_CTRL_S1;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
ctrls[0] &= ~ctrls[1];
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
} else if (ctrls[1] == (PME_CTRL_S0|PME_CTRL_S1)) {
|
|
Packit |
577717 |
ctrls[1] &= ~ctrls[0];
|
|
Packit |
577717 |
} else
|
|
Packit |
577717 |
return PFMLIB_ERR_INVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (input->pfp_event_count == 1) {
|
|
Packit |
577717 |
if (ctrls[0] == (PME_CTRL_S0|PME_CTRL_S1))
|
|
Packit |
577717 |
ctrls[0] = PME_CTRL_S0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for (i = 0; i < input->pfp_event_count; i++) {
|
|
Packit |
577717 |
unsigned long long val = vals[i];
|
|
Packit |
577717 |
char ctrl = ctrls[i];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
switch (ctrl) {
|
|
Packit |
577717 |
case PME_CTRL_S0:
|
|
Packit |
577717 |
output->pfp_pmds[i].reg_num = 0;
|
|
Packit |
577717 |
pcr |= (val <<
|
|
Packit |
577717 |
(niagara2 ?
|
|
Packit |
577717 |
PCR_N2_SL0_SHIFT :
|
|
Packit |
577717 |
PCR_S0_SHIFT));
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PME_CTRL_S1:
|
|
Packit |
577717 |
output->pfp_pmds[i].reg_num = 1;
|
|
Packit |
577717 |
pcr |= (val <<
|
|
Packit |
577717 |
(niagara2 ?
|
|
Packit |
577717 |
PCR_N2_SL1_SHIFT :
|
|
Packit |
577717 |
PCR_S1_SHIFT));
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
return PFMLIB_ERR_INVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (niagara2) {
|
|
Packit |
577717 |
pfmlib_event_t *e = &input->pfp_events[i];
|
|
Packit |
577717 |
unsigned int j, shift;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (ctrl == PME_CTRL_S0) {
|
|
Packit |
577717 |
pcr |= PCR_N2_TOE0;
|
|
Packit |
577717 |
shift = PCR_N2_MASK0_SHIFT;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
pcr |= PCR_N2_TOE1;
|
|
Packit |
577717 |
shift = PCR_N2_MASK1_SHIFT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
for (j = 0; j < e->num_masks; j++) {
|
|
Packit |
577717 |
unsigned int mask;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
mask = e->unit_masks[j];
|
|
Packit |
577717 |
if (mask >= EVENT_MASK_BITS)
|
|
Packit |
577717 |
return PFMLIB_ERR_INVAL;
|
|
Packit |
577717 |
pcr |= (1ULL << (shift + mask));
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
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_reserved1 = 0;
|
|
Packit |
577717 |
output->pfp_pmd_count = i + 1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
output->pfp_pmcs[0].reg_value = pcr;
|
|
Packit |
577717 |
output->pfp_pmcs[0].reg_addr = 0;
|
|
Packit |
577717 |
output->pfp_pmcs[0].reg_num = 0;
|
|
Packit |
577717 |
output->pfp_pmcs[0].reg_reserved1 = 0;
|
|
Packit |
577717 |
output->pfp_pmc_count = 1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int pmu_name_to_pmu_type(char *name)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if (!strcmp(name, "ultra12"))
|
|
Packit |
577717 |
return PFMLIB_SPARC_ULTRA12_PMU;
|
|
Packit |
577717 |
if (!strcmp(name, "ultra3"))
|
|
Packit |
577717 |
return PFMLIB_SPARC_ULTRA3_PMU;
|
|
Packit |
577717 |
if (!strcmp(name, "ultra3i"))
|
|
Packit |
577717 |
return PFMLIB_SPARC_ULTRA3I_PMU;
|
|
Packit |
577717 |
if (!strcmp(name, "ultra3+"))
|
|
Packit |
577717 |
return PFMLIB_SPARC_ULTRA3PLUS_PMU;
|
|
Packit |
577717 |
if (!strcmp(name, "ultra4+"))
|
|
Packit |
577717 |
return PFMLIB_SPARC_ULTRA4PLUS_PMU;
|
|
Packit |
577717 |
if (!strcmp(name, "niagara2"))
|
|
Packit |
577717 |
return PFMLIB_SPARC_NIAGARA2_PMU;
|
|
Packit |
577717 |
if (!strcmp(name, "niagara"))
|
|
Packit |
577717 |
return PFMLIB_SPARC_NIAGARA1_PMU;
|
|
Packit |
577717 |
return -1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int pfm_sparc_pmu_detect(void)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int ret, pmu_type, pme_count;
|
|
Packit |
577717 |
char buffer[32];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ret = __pfm_getcpuinfo_attr("pmu", buffer, sizeof(buffer));
|
|
Packit |
577717 |
if (ret == -1)
|
|
Packit |
577717 |
return PFMLIB_ERR_NOTSUPP;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
pmu_type = pmu_name_to_pmu_type(buffer);
|
|
Packit |
577717 |
if (pmu_type == -1)
|
|
Packit |
577717 |
return PFMLIB_ERR_NOTSUPP;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
switch (pmu_type) {
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
return PFMLIB_ERR_NOTSUPP;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA12_PMU:
|
|
Packit |
577717 |
pme_count = PME_ULTRA12_EVENT_COUNT;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3_PMU:
|
|
Packit |
577717 |
pme_count = PME_ULTRA3_EVENT_COUNT;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3I_PMU:
|
|
Packit |
577717 |
pme_count = PME_ULTRA3I_EVENT_COUNT;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3PLUS_PMU:
|
|
Packit |
577717 |
pme_count = PME_ULTRA3PLUS_EVENT_COUNT;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA4PLUS_PMU:
|
|
Packit |
577717 |
pme_count = PME_ULTRA4PLUS_EVENT_COUNT;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA1_PMU:
|
|
Packit |
577717 |
pme_count = PME_NIAGARA1_EVENT_COUNT;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA2_PMU:
|
|
Packit |
577717 |
pme_count = PME_NIAGARA2_EVENT_COUNT;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
sparc_support.pmu_type = pmu_type;
|
|
Packit |
577717 |
sparc_support.pmu_name = strdup(buffer);
|
|
Packit |
577717 |
sparc_support.pme_count = pme_count;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void pfm_sparc_get_impl_pmcs(pfmlib_regmask_t *impl_pmcs)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
impl_pmcs->bits[0] = 0x1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void pfm_sparc_get_impl_pmds(pfmlib_regmask_t *impl_pmds)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
impl_pmds->bits[0] = 0x3;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void pfm_sparc_get_impl_counters(pfmlib_regmask_t *impl_counters)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
pfm_sparc_get_impl_pmds(impl_counters);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void pfm_sparc_get_hw_counter_width(unsigned int *width)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
*width = 32;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int pfm_sparc_get_event_desc(unsigned int event, char **desc)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
*desc = strdup(get_event_desc(event));
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int pfm_sparc_get_event_mask_desc(unsigned int event,
|
|
Packit |
577717 |
unsigned int mask, char **desc)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if (sparc_support.pmu_type != PFMLIB_SPARC_NIAGARA2_PMU) {
|
|
Packit |
577717 |
*desc = strdup("");
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
pme_sparc_mask_entry_t *e;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
e = &niagara2_pe[event];
|
|
Packit |
577717 |
*desc = strdup(e->pme_masks[mask].mask_desc);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int pfm_sparc_get_event_mask_code(unsigned int event,
|
|
Packit |
577717 |
unsigned int mask, unsigned int *code)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if (sparc_support.pmu_type != PFMLIB_SPARC_NIAGARA2_PMU)
|
|
Packit |
577717 |
*code = 0;
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
*code = mask;
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_sparc_get_cycle_event(pfmlib_event_t *e)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
switch (sparc_support.pmu_type) {
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA12_PMU:
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3_PMU:
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3I_PMU:
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3PLUS_PMU:
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA4PLUS_PMU:
|
|
Packit |
577717 |
e->event = 0;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA1_PMU:
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA2_PMU:
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
return PFMLIB_ERR_NOTSUPP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_sparc_get_inst_retired(pfmlib_event_t *e)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
switch (sparc_support.pmu_type) {
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA12_PMU:
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3_PMU:
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3I_PMU:
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA3PLUS_PMU:
|
|
Packit |
577717 |
case PFMLIB_SPARC_ULTRA4PLUS_PMU:
|
|
Packit |
577717 |
e->event = 1;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA1_PMU:
|
|
Packit |
577717 |
e->event = 0;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PFMLIB_SPARC_NIAGARA2_PMU:
|
|
Packit |
577717 |
e->event = 1;
|
|
Packit |
577717 |
e->num_masks = EVENT_MASK_BITS;
|
|
Packit |
577717 |
for (i = 0; i < e->num_masks; i++)
|
|
Packit |
577717 |
e->unit_masks[i] = i;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
return PFMLIB_ERR_NOTSUPP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* sparc_support
|
|
Packit |
577717 |
**/
|
|
Packit |
577717 |
pfm_pmu_support_t sparc_support = {
|
|
Packit |
577717 |
/* the next 3 fields are initialized in pfm_sparc_pmu_detect */
|
|
Packit |
577717 |
.pmu_name = NULL,
|
|
Packit |
577717 |
.pmu_type = PFMLIB_UNKNOWN_PMU,
|
|
Packit |
577717 |
.pme_count = 0,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
.pmd_count = 2,
|
|
Packit |
577717 |
.pmc_count = 1,
|
|
Packit |
577717 |
.num_cnt = 2,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
.get_event_code = pfm_sparc_get_event_code,
|
|
Packit |
577717 |
.get_event_name = pfm_sparc_get_event_name,
|
|
Packit |
577717 |
.get_event_mask_name = pfm_sparc_get_event_mask_name,
|
|
Packit |
577717 |
.get_event_counters = pfm_sparc_get_event_counters,
|
|
Packit |
577717 |
.get_num_event_masks = pfm_sparc_get_num_event_masks,
|
|
Packit |
577717 |
.dispatch_events = pfm_sparc_dispatch_events,
|
|
Packit |
577717 |
.pmu_detect = pfm_sparc_pmu_detect,
|
|
Packit |
577717 |
.get_impl_pmcs = pfm_sparc_get_impl_pmcs,
|
|
Packit |
577717 |
.get_impl_pmds = pfm_sparc_get_impl_pmds,
|
|
Packit |
577717 |
.get_impl_counters = pfm_sparc_get_impl_counters,
|
|
Packit |
577717 |
.get_hw_counter_width = pfm_sparc_get_hw_counter_width,
|
|
Packit |
577717 |
.get_event_desc = pfm_sparc_get_event_desc,
|
|
Packit |
577717 |
.get_event_mask_desc = pfm_sparc_get_event_mask_desc,
|
|
Packit |
577717 |
.get_event_mask_code = pfm_sparc_get_event_mask_code,
|
|
Packit |
577717 |
.get_cycle_event = pfm_sparc_get_cycle_event,
|
|
Packit |
577717 |
.get_inst_retired_event = pfm_sparc_get_inst_retired
|
|
Packit |
577717 |
};
|