|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Copyright (c) 2007 Cray Inc.
|
|
Packit |
577717 |
* Contributed by Steve Kaufmann <sbk@cray.com> based on code from
|
|
Packit |
577717 |
* Copyright (c) 2001-2006 Hewlett-Packard Development Company, L.P.
|
|
Packit |
577717 |
* Contributed by Stephane Eranian <eranian@hpl.hp.com>
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
Packit |
577717 |
* of this software and associated documentation files (the "Software"), to deal
|
|
Packit |
577717 |
* in the Software without restriction, including without limitation the rights
|
|
Packit |
577717 |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
Packit |
577717 |
* of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
Packit |
577717 |
* subject to the following conditions:
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The above copyright notice and this permission notice shall be included in all
|
|
Packit |
577717 |
* copies or substantial portions of the Software.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
Packit |
577717 |
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
Packit |
577717 |
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
Packit |
577717 |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
Packit |
577717 |
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
|
Packit |
577717 |
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <perfmon/pfmlib.h>
|
|
Packit |
577717 |
#include <perfmon/pfmlib_crayx2.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "pfmlib_priv.h"
|
|
Packit |
577717 |
#include "pfmlib_crayx2_priv.h"
|
|
Packit |
577717 |
#include "crayx2_events.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define CRAYX2_NO_REDUNDANT 0 /* if>0 an error if chip:ctr:ev repeated */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
typedef enum {
|
|
Packit |
577717 |
CTR_REDUNDANT = -2, /* event on counter repeated */
|
|
Packit |
577717 |
CTR_CONFLICT = -1, /* event on counter not the same as previous */
|
|
Packit |
577717 |
CTR_OK = 0 /* event on counter open */
|
|
Packit |
577717 |
} counter_use_t;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_crayx2_get_event_code (unsigned int i, unsigned int cnt, int *code)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if (cnt != PFMLIB_CNT_FIRST && cnt > crayx2_support.num_cnt) {
|
|
Packit |
577717 |
DPRINT ("return: count %d exceeded #counters\n", cnt);
|
|
Packit |
577717 |
return PFMLIB_ERR_INVAL;
|
|
Packit |
577717 |
} else if (i >= crayx2_support.pme_count) {
|
|
Packit |
577717 |
DPRINT ("return: event index %d exceeded #events\n", i);
|
|
Packit |
577717 |
return PFMLIB_ERR_INVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
*code = crayx2_pe[i].pme_code;
|
|
Packit |
577717 |
DPRINT ("return: event code is %#x\n", *code);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static char *
|
|
Packit |
577717 |
pfm_crayx2_get_event_name (unsigned int i)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if (i >= crayx2_support.pme_count) {
|
|
Packit |
577717 |
DPRINT ("return: event index %d exceeded #events\n", i);
|
|
Packit |
577717 |
return NULL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
DPRINT ("return: event name '%s'\n", crayx2_pe[i].pme_name);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return (char *) crayx2_pe[i].pme_name;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void
|
|
Packit |
577717 |
pfm_crayx2_get_event_counters (unsigned int j, pfmlib_regmask_t *counters)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset (counters, 0, sizeof (*counters));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
DPRINT ("event counters for %d counters\n", PMU_CRAYX2_NUM_COUNTERS);
|
|
Packit |
577717 |
for (i=0; i
|
|
Packit |
577717 |
pfm_regmask_set (counters, i);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_crayx2_chip_use (uint32_t used[ ], unsigned int n)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i, u = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for (i=0; i
|
|
Packit |
577717 |
u += pfmlib_popcnt (used[i]);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
DPRINT ("number of counters used on chip %d\n", u);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return u;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static counter_use_t
|
|
Packit |
577717 |
pfm_crayx2_counter_use (unsigned int ctr, unsigned int event, uint32_t *used, uint64_t *evmsk)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
counter_use_t ret = CTR_OK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (*used & (1 << ctr)) {
|
|
Packit |
577717 |
if (event == PFM_EVENT_GET (*evmsk, ctr)) {
|
|
Packit |
577717 |
ret = CTR_REDUNDANT;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
ret = CTR_CONFLICT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
*evmsk |= PFM_EVENT_SET (ctr, event);
|
|
Packit |
577717 |
*used |= (1 << ctr);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ret;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_crayx2_dispatch_events (pfmlib_input_param_t *inp, void *model_in, pfmlib_output_param_t *outp, void *model_out)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int i, npmcs = 0, npmds = 0, base_pmc = 0;
|
|
Packit |
577717 |
uint32_t Pused[PME_CRAYX2_CPU_CHIPS];
|
|
Packit |
577717 |
uint32_t Cused[PME_CRAYX2_CACHE_CHIPS];
|
|
Packit |
577717 |
uint32_t Mused[PME_CRAYX2_MEMORY_CHIPS];
|
|
Packit |
577717 |
uint64_t Pevents = 0, Cevents = 0, Mevents = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
DPRINT ("dispatching event info to the PMCs and PMDs\n");
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* NOTES:
|
|
Packit |
577717 |
* Multiplexing is not supported on X2.
|
|
Packit |
577717 |
* The priviledge level is ignored for the C and M chips.
|
|
Packit |
577717 |
* The priviledge level is ignored per event.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (PFMLIB_DEBUG ( )) {
|
|
Packit |
577717 |
int j;
|
|
Packit |
577717 |
DPRINT ("input: pfp_event_count %d pfp_dfl_plm %#x pfp_flags %#x\n", inp->pfp_event_count, inp->pfp_dfl_plm, inp->pfp_flags);
|
|
Packit |
577717 |
for (i=0; i<inp->pfp_event_count; i++) {
|
|
Packit |
577717 |
DPRINT (" %3d: event %3d plm %#3x flags %#8lx num_masks %d\n", i, inp->pfp_events[i].event, inp->pfp_events[i].plm, inp->pfp_events[i].flags, inp->pfp_events[i].num_masks);
|
|
Packit |
577717 |
for (j=0; j<inp->pfp_events[i].num_masks; j++) {
|
|
Packit |
577717 |
DPRINT (" unit-mask-%2d: %d\n", j, inp->pfp_events[i].unit_masks[j]);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Better have at least one event specified and not exceed limit.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if (inp->pfp_event_count == 0) {
|
|
Packit |
577717 |
DPRINT ("return: event count is 0\n");
|
|
Packit |
577717 |
return PFMLIB_ERR_INVAL;
|
|
Packit |
577717 |
} else if (inp->pfp_event_count > PMU_CRAYX2_NUM_COUNTERS) {
|
|
Packit |
577717 |
DPRINT ("return: event count exceeds max %d\n", PMU_CRAYX2_NUM_COUNTERS);
|
|
Packit |
577717 |
return PFMLIB_ERR_TOOMANY;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset (Pused, 0, sizeof(Pused));
|
|
Packit |
577717 |
memset (Cused, 0, sizeof(Cused));
|
|
Packit |
577717 |
memset (Mused, 0, sizeof(Mused));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Loop through the input parameters describing the events.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
for (i=0; i<inp->pfp_event_count; i++) {
|
|
Packit |
577717 |
unsigned int code, chip, ctr, ev, chipno;
|
|
Packit |
577717 |
counter_use_t ret;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Acquire details describing this event code:
|
|
Packit |
577717 |
* o which substrate/chip it is on
|
|
Packit |
577717 |
* o which counter on the chip
|
|
Packit |
577717 |
* o which event on the counter
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
code = inp->pfp_events[i].event;
|
|
Packit |
577717 |
chip = crayx2_pe[code].pme_chip;
|
|
Packit |
577717 |
ctr = crayx2_pe[code].pme_ctr;
|
|
Packit |
577717 |
ev = crayx2_pe[code].pme_event;
|
|
Packit |
577717 |
chipno = crayx2_pe[code].pme_chipno;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
DPRINT ("%3d: code %3d chip %1d ctr %2d ev %1d chipno %2d\n", code, i, chip, ctr, ev, chipno);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* These priviledge levels are not recognized.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if (inp->pfp_events[i].plm != 0) {
|
|
Packit |
577717 |
DPRINT ("%3d: priviledge level %#x per event not allowed\n", i, inp->pfp_events[i].plm);
|
|
Packit |
577717 |
return PFMLIB_ERR_INVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* No masks exist.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if (inp->pfp_events[i].num_masks > 0) {
|
|
Packit |
577717 |
DPRINT ("too many masks for event\n");
|
|
Packit |
577717 |
return PFMLIB_ERR_TOOMANY;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* The event code. Set-up the event selection mask for
|
|
Packit |
577717 |
* the PMC of the respective chip. Check if more than
|
|
Packit |
577717 |
* one event on the same counter is selected.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if (chip == PME_CRAYX2_CHIP_CPU) {
|
|
Packit |
577717 |
ret = pfm_crayx2_counter_use (ctr, ev, &Pused[chipno], &Pevents);
|
|
Packit |
577717 |
} else if (chip == PME_CRAYX2_CHIP_CACHE) {
|
|
Packit |
577717 |
ret = pfm_crayx2_counter_use (ctr, ev, &Cused[chipno], &Cevents);
|
|
Packit |
577717 |
} else if (chip == PME_CRAYX2_CHIP_MEMORY) {
|
|
Packit |
577717 |
ret = pfm_crayx2_counter_use (ctr, ev, &Mused[chipno], &Mevents);
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
DPRINT ("return: invalid chip\n");
|
|
Packit |
577717 |
return PFMLIB_ERR_INVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Each chip's counter can only count one event.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if (ret == CTR_CONFLICT) {
|
|
Packit |
577717 |
DPRINT ("return: ctr conflict\n");
|
|
Packit |
577717 |
return PFMLIB_ERR_EVTINCOMP;
|
|
Packit |
577717 |
} else if (ret == CTR_REDUNDANT) {
|
|
Packit |
577717 |
#if (CRAYX2_NO_REDUNDANT != 0)
|
|
Packit |
577717 |
DPRINT ("return: ctr redundant\n");
|
|
Packit |
577717 |
return PFMLIB_ERR_EVTMANY;
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
DPRINT ("warning: ctr redundant\n");
|
|
Packit |
577717 |
#endif /* CRAYX2_NO_REDUNDANT */
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Set up the output PMDs.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
outp->pfp_pmds[npmds].reg_num = crayx2_pe[code].pme_base + ctr + chipno*crayx2_pe[code].pme_nctrs;
|
|
Packit |
577717 |
outp->pfp_pmds[npmds].reg_addr = 0;
|
|
Packit |
577717 |
outp->pfp_pmds[npmds].reg_alt_addr = 0;
|
|
Packit |
577717 |
outp->pfp_pmds[npmds].reg_value = 0;
|
|
Packit |
577717 |
npmds++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
outp->pfp_pmd_count = npmds;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (PFMLIB_DEBUG ( )) {
|
|
Packit |
577717 |
DPRINT ("P event mask %#16lx\n", Pevents);
|
|
Packit |
577717 |
DPRINT ("C event mask %#16lx\n", Cevents);
|
|
Packit |
577717 |
DPRINT ("M event mask %#16lx\n", Mevents);
|
|
Packit |
577717 |
DPRINT ("PMDs: pmd_count %d\n", outp->pfp_pmd_count);
|
|
Packit |
577717 |
for (i=0; i<outp->pfp_pmd_count; i++) {
|
|
Packit |
577717 |
DPRINT (" %3d: reg_value %3lld reg_num %3d reg_addr %#16llx\n", i, outp->pfp_pmds[i].reg_value, outp->pfp_pmds[i].reg_num, outp->pfp_pmds[i].reg_addr);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Set up the PMC basics for the chips that will be doing
|
|
Packit |
577717 |
* some counting.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if (pfm_crayx2_chip_use (Pused, PME_CRAYX2_CPU_CHIPS) > 0) {
|
|
Packit |
577717 |
uint64_t Pctrl = PFM_CPU_START;
|
|
Packit |
577717 |
uint64_t Pen = PFM_ENABLE_RW;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (inp->pfp_dfl_plm & (PFM_PLM0 | PFM_PLM1)) {
|
|
Packit |
577717 |
Pen |= PFM_ENABLE_KERNEL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (inp->pfp_dfl_plm & PFM_PLM2) {
|
|
Packit |
577717 |
Pen |= PFM_ENABLE_EXL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (inp->pfp_dfl_plm & PFM_PLM3) {
|
|
Packit |
577717 |
Pen |= PFM_ENABLE_USER;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* First of three CPU PMC registers.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
base_pmc = PMU_CRAYX2_CPU_PMC_BASE;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_value = Pctrl;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_num = base_pmc + PMC_CONTROL;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_addr = 0;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_alt_addr = 0;
|
|
Packit |
577717 |
npmcs++;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_value = Pevents;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_num = base_pmc + PMC_EVENTS;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_addr = 0;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_alt_addr = 0;
|
|
Packit |
577717 |
npmcs++;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_value = Pen;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_num = base_pmc + PMC_ENABLE;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_addr = 0;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_alt_addr = 0;
|
|
Packit |
577717 |
npmcs++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (pfm_crayx2_chip_use (Cused, PME_CRAYX2_CACHE_CHIPS) > 0) {
|
|
Packit |
577717 |
uint64_t Cctrl = PFM_CACHE_START;
|
|
Packit |
577717 |
uint64_t Cen = PFM_ENABLE_RW; /* domains N/A */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Second of three Cache PMC registers.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
base_pmc = PMU_CRAYX2_CACHE_PMC_BASE;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_value = Cctrl;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_num = base_pmc + PMC_CONTROL;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_addr = 0;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_alt_addr = 0;
|
|
Packit |
577717 |
npmcs++;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_value = Cevents;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_num = base_pmc + PMC_EVENTS;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_addr = 0;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_alt_addr = 0;
|
|
Packit |
577717 |
npmcs++;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_value = Cen;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_num = base_pmc + PMC_ENABLE;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_addr = 0;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_alt_addr = 0;
|
|
Packit |
577717 |
npmcs++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (pfm_crayx2_chip_use (Mused, PME_CRAYX2_MEMORY_CHIPS) > 0) {
|
|
Packit |
577717 |
uint64_t Mctrl = PFM_MEM_START;
|
|
Packit |
577717 |
uint64_t Men = PFM_ENABLE_RW; /* domains N/A */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Third of three Memory PMC registers.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
base_pmc = PMU_CRAYX2_MEMORY_PMC_BASE;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_value = Mctrl;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_num = base_pmc + PMC_CONTROL;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_addr = 0;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_alt_addr = 0;
|
|
Packit |
577717 |
npmcs++;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_value = Mevents;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_num = base_pmc + PMC_EVENTS;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_addr = 0;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_alt_addr = 0;
|
|
Packit |
577717 |
npmcs++;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_value = Men;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_num = base_pmc + PMC_ENABLE;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_addr = 0;
|
|
Packit |
577717 |
outp->pfp_pmcs[npmcs].reg_alt_addr = 0;
|
|
Packit |
577717 |
npmcs++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
outp->pfp_pmc_count = npmcs;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (PFMLIB_DEBUG ( )) {
|
|
Packit |
577717 |
DPRINT ("PMCs: pmc_count %d\n", outp->pfp_pmc_count);
|
|
Packit |
577717 |
for (i=0; i<outp->pfp_pmc_count; i++) {
|
|
Packit |
577717 |
DPRINT (" %3d: reg_value %#16llx reg_num %3d reg_addr %#16llx\n", i, outp->pfp_pmcs[i].reg_value, outp->pfp_pmcs[i].reg_num, outp->pfp_pmcs[i].reg_addr);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_crayx2_pmu_detect (void)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
char buffer[128];
|
|
Packit |
577717 |
int ret;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
DPRINT ("detect the PMU attributes\n");
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ret = __pfm_getcpuinfo_attr ("vendor_id", buffer, sizeof(buffer));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (ret != 0 || strcasecmp (buffer, "Cray") != 0) {
|
|
Packit |
577717 |
DPRINT ("return: no 'Cray' vendor_id\n");
|
|
Packit |
577717 |
return PFMLIB_ERR_NOTSUPP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ret = __pfm_getcpuinfo_attr ("type", buffer, sizeof(buffer));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (ret != 0 || strcasecmp (buffer, "craynv2") != 0) {
|
|
Packit |
577717 |
DPRINT ("return: no 'craynv2' type\n");
|
|
Packit |
577717 |
return PFMLIB_ERR_NOTSUPP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
DPRINT ("Cray X2 nv2 found\n");
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void
|
|
Packit |
577717 |
pfm_crayx2_get_impl_pmcs (pfmlib_regmask_t *impl_pmcs)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
DPRINT ("entered with PMC_COUNT %d\n", PMU_CRAYX2_PMC_COUNT);
|
|
Packit |
577717 |
for (i=0; i
|
|
Packit |
577717 |
pfm_regmask_set (impl_pmcs, i);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void
|
|
Packit |
577717 |
pfm_crayx2_get_impl_pmds (pfmlib_regmask_t *impl_pmds)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
DPRINT ("entered with PMD_COUNT %d\n", PMU_CRAYX2_PMD_COUNT);
|
|
Packit |
577717 |
for (i=0; i
|
|
Packit |
577717 |
pfm_regmask_set (impl_pmds, i);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void
|
|
Packit |
577717 |
pfm_crayx2_get_impl_counters (pfmlib_regmask_t *impl_counters)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
DPRINT ("entered with NUM_COUNTERS %d\n", PMU_CRAYX2_NUM_COUNTERS);
|
|
Packit |
577717 |
for (i=0; i
|
|
Packit |
577717 |
pfm_regmask_set (impl_counters, i);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void
|
|
Packit |
577717 |
pfm_crayx2_get_hw_counter_width (unsigned int *width)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
*width = PMU_CRAYX2_COUNTER_WIDTH;
|
|
Packit |
577717 |
DPRINT ("return: width set to %d\n", *width);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_crayx2_get_event_desc (unsigned int ev, char **str)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
const char *s = crayx2_pe[ev].pme_desc;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
*str = (s == NULL ? NULL : strdup (s));
|
|
Packit |
577717 |
DPRINT ("return: event description is '%s'\n", (s == NULL ? "" : s));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static unsigned int
|
|
Packit |
577717 |
pfm_crayx2_get_num_event_masks (unsigned int ev)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
DPRINT ("return: #event masks is %d\n", crayx2_pe[ev].pme_numasks);
|
|
Packit |
577717 |
return crayx2_pe[ev].pme_numasks;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static char *
|
|
Packit |
577717 |
pfm_crayx2_get_event_mask_name (unsigned int ev, unsigned int midx)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
DPRINT ("return: event mask name is '%s'\n", crayx2_pe[ev].pme_umasks[midx].pme_uname);
|
|
Packit |
577717 |
return (char *) crayx2_pe[ev].pme_umasks[midx].pme_uname;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_crayx2_get_event_mask_code (unsigned int ev, unsigned int midx, unsigned int *code)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
*code = crayx2_pe[ev].pme_umasks[midx].pme_ucode;
|
|
Packit |
577717 |
DPRINT ("return: event mask code is %#x\n", *code);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_crayx2_get_event_mask_desc (unsigned int ev, unsigned int midx, char **str)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
const char *s = crayx2_pe[ev].pme_umasks[midx].pme_udesc;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
*str = (s == NULL ? NULL : strdup (s));
|
|
Packit |
577717 |
DPRINT ("return: event mask description is '%s'\n", (s == NULL ? "" : s));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_crayx2_get_cycle_event (pfmlib_event_t *e)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
e->event = PME_CRAYX2_CYCLES;
|
|
Packit |
577717 |
DPRINT ("return: event code for cycles %#x\n", e->event);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
pfm_crayx2_get_inst_retired (pfmlib_event_t *e)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
e->event = PME_CRAYX2_INSTR_GRADUATED;
|
|
Packit |
577717 |
DPRINT ("return: event code for retired instr %#x\n", e->event);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PFMLIB_SUCCESS;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Register the constants and the access functions.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
pfm_pmu_support_t crayx2_support = {
|
|
Packit |
577717 |
.pmu_name = PMU_CRAYX2_NAME,
|
|
Packit |
577717 |
.pmu_type = PFMLIB_CRAYX2_PMU,
|
|
Packit |
577717 |
.pme_count = PME_CRAYX2_EVENT_COUNT,
|
|
Packit |
577717 |
.pmc_count = PMU_CRAYX2_PMC_COUNT,
|
|
Packit |
577717 |
.pmd_count = PMU_CRAYX2_PMD_COUNT,
|
|
Packit |
577717 |
.num_cnt = PMU_CRAYX2_NUM_COUNTERS,
|
|
Packit |
577717 |
.get_event_code = pfm_crayx2_get_event_code,
|
|
Packit |
577717 |
.get_event_name = pfm_crayx2_get_event_name,
|
|
Packit |
577717 |
.get_event_counters = pfm_crayx2_get_event_counters,
|
|
Packit |
577717 |
.dispatch_events = pfm_crayx2_dispatch_events,
|
|
Packit |
577717 |
.pmu_detect = pfm_crayx2_pmu_detect,
|
|
Packit |
577717 |
.get_impl_pmcs = pfm_crayx2_get_impl_pmcs,
|
|
Packit |
577717 |
.get_impl_pmds = pfm_crayx2_get_impl_pmds,
|
|
Packit |
577717 |
.get_impl_counters = pfm_crayx2_get_impl_counters,
|
|
Packit |
577717 |
.get_hw_counter_width = pfm_crayx2_get_hw_counter_width,
|
|
Packit |
577717 |
.get_event_desc = pfm_crayx2_get_event_desc,
|
|
Packit |
577717 |
.get_num_event_masks = pfm_crayx2_get_num_event_masks,
|
|
Packit |
577717 |
.get_event_mask_name = pfm_crayx2_get_event_mask_name,
|
|
Packit |
577717 |
.get_event_mask_code = pfm_crayx2_get_event_mask_code,
|
|
Packit |
577717 |
.get_event_mask_desc = pfm_crayx2_get_event_mask_desc,
|
|
Packit |
577717 |
.get_cycle_event = pfm_crayx2_get_cycle_event,
|
|
Packit |
577717 |
.get_inst_retired_event = pfm_crayx2_get_inst_retired
|
|
Packit |
577717 |
};
|