|
Packit Service |
a1973e |
/****************************/
|
|
Packit Service |
a1973e |
/* THIS IS OPEN SOURCE CODE */
|
|
Packit Service |
a1973e |
/****************************/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/*
|
|
Packit Service |
a1973e |
* File: linux-memory.c
|
|
Packit Service |
a1973e |
* Author: Kevin London
|
|
Packit Service |
a1973e |
* london@cs.utk.edu
|
|
Packit Service |
a1973e |
* Mods: Dan Terpstra
|
|
Packit Service |
a1973e |
* terpstra@eecs.utk.edu
|
|
Packit Service |
a1973e |
* cache and TLB info exported to a separate file
|
|
Packit Service |
a1973e |
* which is not OS or driver dependent
|
|
Packit Service |
a1973e |
* Mods: Vince Weaver
|
|
Packit Service |
a1973e |
* vweaver1@eecs.utk.edu
|
|
Packit Service |
a1973e |
* Merge all of the various copies of linux-related
|
|
Packit Service |
a1973e |
* memory detection info this file.
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#include <dirent.h>
|
|
Packit Service |
a1973e |
#include <fcntl.h>
|
|
Packit Service |
a1973e |
#include <string.h>
|
|
Packit Service |
a1973e |
#include <errno.h>
|
|
Packit Service |
a1973e |
#include <ctype.h>
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#include "papi.h"
|
|
Packit Service |
a1973e |
#include "papi_internal.h"
|
|
Packit Service |
a1973e |
#include "papi_memory.h" /* papi_calloc() */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#include "x86_cpuid_info.h"
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#include "linux-lock.h"
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* 2.6.19 has this:
|
|
Packit Service |
a1973e |
VmPeak: 4588 kB
|
|
Packit Service |
a1973e |
VmSize: 4584 kB
|
|
Packit Service |
a1973e |
VmLck: 0 kB
|
|
Packit Service |
a1973e |
VmHWM: 1548 kB
|
|
Packit Service |
a1973e |
VmRSS: 1548 kB
|
|
Packit Service |
a1973e |
VmData: 312 kB
|
|
Packit Service |
a1973e |
VmStk: 88 kB
|
|
Packit Service |
a1973e |
VmExe: 684 kB
|
|
Packit Service |
a1973e |
VmLib: 1360 kB
|
|
Packit Service |
a1973e |
VmPTE: 20 kB
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_linux_get_dmem_info( PAPI_dmem_info_t * d )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
char fn[PATH_MAX], tmp[PATH_MAX];
|
|
Packit Service |
a1973e |
FILE *f;
|
|
Packit Service |
a1973e |
int ret;
|
|
Packit Service |
a1973e |
long long sz = 0, lck = 0, res = 0, shr = 0, stk = 0, txt = 0, dat =
|
|
Packit Service |
a1973e |
0, dum = 0, lib = 0, hwm = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
sprintf( fn, "/proc/%ld/status", ( long ) getpid( ) );
|
|
Packit Service |
a1973e |
f = fopen( fn, "r" );
|
|
Packit Service |
a1973e |
if ( f == NULL ) {
|
|
Packit Service |
a1973e |
PAPIERROR( "fopen(%s): %s\n", fn, strerror( errno ) );
|
|
Packit Service |
a1973e |
return PAPI_ESYS;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
while ( 1 ) {
|
|
Packit Service |
a1973e |
if ( fgets( tmp, PATH_MAX, f ) == NULL )
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
if ( strspn( tmp, "VmSize:" ) == strlen( "VmSize:" ) ) {
|
|
Packit Service |
a1973e |
sscanf( tmp + strlen( "VmSize:" ), "%lld", &sz );
|
|
Packit Service |
a1973e |
d->size = sz;
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if ( strspn( tmp, "VmHWM:" ) == strlen( "VmHWM:" ) ) {
|
|
Packit Service |
a1973e |
sscanf( tmp + strlen( "VmHWM:" ), "%lld", &hwm );
|
|
Packit Service |
a1973e |
d->high_water_mark = hwm;
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if ( strspn( tmp, "VmLck:" ) == strlen( "VmLck:" ) ) {
|
|
Packit Service |
a1973e |
sscanf( tmp + strlen( "VmLck:" ), "%lld", &lck );
|
|
Packit Service |
a1973e |
d->locked = lck;
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if ( strspn( tmp, "VmRSS:" ) == strlen( "VmRSS:" ) ) {
|
|
Packit Service |
a1973e |
sscanf( tmp + strlen( "VmRSS:" ), "%lld", &res );
|
|
Packit Service |
a1973e |
d->resident = res;
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if ( strspn( tmp, "VmData:" ) == strlen( "VmData:" ) ) {
|
|
Packit Service |
a1973e |
sscanf( tmp + strlen( "VmData:" ), "%lld", &dat );
|
|
Packit Service |
a1973e |
d->heap = dat;
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if ( strspn( tmp, "VmStk:" ) == strlen( "VmStk:" ) ) {
|
|
Packit Service |
a1973e |
sscanf( tmp + strlen( "VmStk:" ), "%lld", &stk );
|
|
Packit Service |
a1973e |
d->stack = stk;
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if ( strspn( tmp, "VmExe:" ) == strlen( "VmExe:" ) ) {
|
|
Packit Service |
a1973e |
sscanf( tmp + strlen( "VmExe:" ), "%lld", &txt );
|
|
Packit Service |
a1973e |
d->text = txt;
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if ( strspn( tmp, "VmLib:" ) == strlen( "VmLib:" ) ) {
|
|
Packit Service |
a1973e |
sscanf( tmp + strlen( "VmLib:" ), "%lld", &lib );
|
|
Packit Service |
a1973e |
d->library = lib;
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
fclose( f );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
sprintf( fn, "/proc/%ld/statm", ( long ) getpid( ) );
|
|
Packit Service |
a1973e |
f = fopen( fn, "r" );
|
|
Packit Service |
a1973e |
if ( f == NULL ) {
|
|
Packit Service |
a1973e |
PAPIERROR( "fopen(%s): %s\n", fn, strerror( errno ) );
|
|
Packit Service |
a1973e |
return PAPI_ESYS;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
ret =
|
|
Packit Service |
a1973e |
fscanf( f, "%lld %lld %lld %lld %lld %lld %lld", &dum, &dum, &shr, &dum,
|
|
Packit Service |
a1973e |
&dum, &dat, &dum );
|
|
Packit Service |
a1973e |
if ( ret != 7 ) {
|
|
Packit Service |
a1973e |
PAPIERROR( "fscanf(7 items): %d\n", ret );
|
|
Packit Service |
a1973e |
fclose(f);
|
|
Packit Service |
a1973e |
return PAPI_ESYS;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
d->pagesize = getpagesize( );
|
|
Packit Service |
a1973e |
d->shared = ( shr * d->pagesize ) / 1024;
|
|
Packit Service |
a1973e |
fclose( f );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/*
|
|
Packit Service |
a1973e |
* Architecture-specific cache detection code
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#if defined(__i386__)||defined(__x86_64__)
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
x86_get_memory_info( PAPI_hw_info_t * hw_info )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int retval = PAPI_OK;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
switch ( hw_info->vendor ) {
|
|
Packit Service |
a1973e |
case PAPI_VENDOR_AMD:
|
|
Packit Service |
a1973e |
case PAPI_VENDOR_INTEL:
|
|
Packit Service |
a1973e |
retval = _x86_cache_info( &hw_info->mem_hierarchy );
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
default:
|
|
Packit Service |
a1973e |
PAPIERROR( "Unknown vendor in memory information call for x86." );
|
|
Packit Service |
a1973e |
return PAPI_ENOIMPL;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
return retval;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#if defined(__ia64__)
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
get_number( char *buf )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
char numbers[] = "0123456789";
|
|
Packit Service |
a1973e |
int num;
|
|
Packit Service |
a1973e |
char *tmp, *end;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
tmp = strpbrk( buf, numbers );
|
|
Packit Service |
a1973e |
if ( tmp != NULL ) {
|
|
Packit Service |
a1973e |
end = tmp;
|
|
Packit Service |
a1973e |
while ( isdigit( *end ) )
|
|
Packit Service |
a1973e |
end++;
|
|
Packit Service |
a1973e |
*end = '\0';
|
|
Packit Service |
a1973e |
num = atoi( tmp );
|
|
Packit Service |
a1973e |
return num;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
PAPIERROR( "Number could not be parsed from %s", buf );
|
|
Packit Service |
a1973e |
return -1;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
fline( FILE * fp, char *rline )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
char *tmp, *end, c;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
tmp = rline;
|
|
Packit Service |
a1973e |
end = &rline[1023];
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset( rline, '\0', 1024 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
do {
|
|
Packit Service |
a1973e |
if ( feof( fp ) )
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
c = getc( fp );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
while ( isspace( c ) || c == '\n' || c == '\r' );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ungetc( c, fp );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( ;; ) {
|
|
Packit Service |
a1973e |
if ( feof( fp ) ) {
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
c = getc( fp );
|
|
Packit Service |
a1973e |
if ( c == '\n' || c == '\r' )
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
*tmp++ = c;
|
|
Packit Service |
a1973e |
if ( tmp == end ) {
|
|
Packit Service |
a1973e |
*tmp = '\0';
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
ia64_get_memory_info( PAPI_hw_info_t * hw_info )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int retval = 0;
|
|
Packit Service |
a1973e |
FILE *f;
|
|
Packit Service |
a1973e |
int clevel = 0, cindex = -1;
|
|
Packit Service |
a1973e |
char buf[1024];
|
|
Packit Service |
a1973e |
int num, i, j;
|
|
Packit Service |
a1973e |
PAPI_mh_info_t *meminfo = &hw_info->mem_hierarchy;
|
|
Packit Service |
a1973e |
PAPI_mh_level_t *L = hw_info->mem_hierarchy.level;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
f = fopen( "/proc/pal/cpu0/cache_info", "r" );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !f ) {
|
|
Packit Service |
a1973e |
PAPIERROR( "fopen(/proc/pal/cpu0/cache_info) returned < 0" );
|
|
Packit Service |
a1973e |
return PAPI_ESYS;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
while ( !feof( f ) ) {
|
|
Packit Service |
a1973e |
fline( f, buf );
|
|
Packit Service |
a1973e |
if ( buf[0] == '\0' )
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
if ( !strncmp( buf, "Data Cache", 10 ) ) {
|
|
Packit Service |
a1973e |
cindex = 1;
|
|
Packit Service |
a1973e |
clevel = get_number( buf );
|
|
Packit Service |
a1973e |
L[clevel - 1].cache[cindex].type = PAPI_MH_TYPE_DATA;
|
|
Packit Service |
a1973e |
} else if ( !strncmp( buf, "Instruction Cache", 17 ) ) {
|
|
Packit Service |
a1973e |
cindex = 0;
|
|
Packit Service |
a1973e |
clevel = get_number( buf );
|
|
Packit Service |
a1973e |
L[clevel - 1].cache[cindex].type = PAPI_MH_TYPE_INST;
|
|
Packit Service |
a1973e |
} else if ( !strncmp( buf, "Data/Instruction Cache", 22 ) ) {
|
|
Packit Service |
a1973e |
cindex = 0;
|
|
Packit Service |
a1973e |
clevel = get_number( buf );
|
|
Packit Service |
a1973e |
L[clevel - 1].cache[cindex].type = PAPI_MH_TYPE_UNIFIED;
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
if ( ( clevel == 0 || clevel > 3 ) && cindex >= 0 ) {
|
|
Packit Service |
a1973e |
PAPIERROR
|
|
Packit Service |
a1973e |
( "Cache type could not be recognized, please send /proc/pal/cpu0/cache_info" );
|
|
Packit Service |
a1973e |
return PAPI_EBUG;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !strncmp( buf, "Size", 4 ) ) {
|
|
Packit Service |
a1973e |
num = get_number( buf );
|
|
Packit Service |
a1973e |
L[clevel - 1].cache[cindex].size = num;
|
|
Packit Service |
a1973e |
} else if ( !strncmp( buf, "Associativity", 13 ) ) {
|
|
Packit Service |
a1973e |
num = get_number( buf );
|
|
Packit Service |
a1973e |
L[clevel - 1].cache[cindex].associativity = num;
|
|
Packit Service |
a1973e |
} else if ( !strncmp( buf, "Line size", 9 ) ) {
|
|
Packit Service |
a1973e |
num = get_number( buf );
|
|
Packit Service |
a1973e |
L[clevel - 1].cache[cindex].line_size = num;
|
|
Packit Service |
a1973e |
L[clevel - 1].cache[cindex].num_lines =
|
|
Packit Service |
a1973e |
L[clevel - 1].cache[cindex].size / num;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
fclose( f );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
f = fopen( "/proc/pal/cpu0/vm_info", "r" );
|
|
Packit Service |
a1973e |
/* No errors on fopen as I am not sure this is always on the systems */
|
|
Packit Service |
a1973e |
if ( f != NULL ) {
|
|
Packit Service |
a1973e |
cindex = -1;
|
|
Packit Service |
a1973e |
clevel = 0;
|
|
Packit Service |
a1973e |
while ( !feof( f ) ) {
|
|
Packit Service |
a1973e |
fline( f, buf );
|
|
Packit Service |
a1973e |
if ( buf[0] == '\0' )
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
if ( !strncmp( buf, "Data Translation", 16 ) ) {
|
|
Packit Service |
a1973e |
cindex = 1;
|
|
Packit Service |
a1973e |
clevel = get_number( buf );
|
|
Packit Service |
a1973e |
L[clevel - 1].tlb[cindex].type = PAPI_MH_TYPE_DATA;
|
|
Packit Service |
a1973e |
} else if ( !strncmp( buf, "Instruction Translation", 23 ) ) {
|
|
Packit Service |
a1973e |
cindex = 0;
|
|
Packit Service |
a1973e |
clevel = get_number( buf );
|
|
Packit Service |
a1973e |
L[clevel - 1].tlb[cindex].type = PAPI_MH_TYPE_INST;
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
if ( ( clevel == 0 || clevel > 2 ) && cindex >= 0 ) {
|
|
Packit Service |
a1973e |
PAPIERROR
|
|
Packit Service |
a1973e |
( "TLB type could not be recognized, send /proc/pal/cpu0/vm_info" );
|
|
Packit Service |
a1973e |
return PAPI_EBUG;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !strncmp( buf, "Number of entries", 17 ) ) {
|
|
Packit Service |
a1973e |
num = get_number( buf );
|
|
Packit Service |
a1973e |
L[clevel - 1].tlb[cindex].num_entries = num;
|
|
Packit Service |
a1973e |
} else if ( !strncmp( buf, "Associativity", 13 ) ) {
|
|
Packit Service |
a1973e |
num = get_number( buf );
|
|
Packit Service |
a1973e |
L[clevel - 1].tlb[cindex].associativity = num;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
fclose( f );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Compute and store the number of levels of hierarchy actually used */
|
|
Packit Service |
a1973e |
for ( i = 0; i < PAPI_MH_MAX_LEVELS; i++ ) {
|
|
Packit Service |
a1973e |
for ( j = 0; j < 2; j++ ) {
|
|
Packit Service |
a1973e |
if ( L[i].tlb[j].type != PAPI_MH_TYPE_EMPTY ||
|
|
Packit Service |
a1973e |
L[i].cache[j].type != PAPI_MH_TYPE_EMPTY )
|
|
Packit Service |
a1973e |
meminfo->levels = i + 1;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
return retval;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#if defined(__powerpc__)
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
PAPI_mh_info_t sys_mem_info[] = {
|
|
Packit Service |
a1973e |
{2, // 970 begin
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
{ // level 1 begins
|
|
Packit Service |
a1973e |
{ // tlb's begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_UNIFIED, 1024, 4, 0}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // caches begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_INST, 65536, 128, 512, 1}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_DATA, 32768, 128, 256, 2}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // level 2 begins
|
|
Packit Service |
a1973e |
{ // tlb's begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // caches begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_UNIFIED, 524288, 128, 4096, 8}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1, -1}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
, // 970 end
|
|
Packit Service |
a1973e |
{3,
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
{ // level 1 begins
|
|
Packit Service |
a1973e |
{ // tlb's begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_UNIFIED, 1024, 4, 0}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // caches begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_INST, 65536, 128, 512, 2}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_DATA, 32768, 128, 256, 4}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // level 2 begins
|
|
Packit Service |
a1973e |
{ // tlb's begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // caches begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_UNIFIED, 1966080, 128, 15360, 10}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1, -1}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // level 3 begins
|
|
Packit Service |
a1973e |
{ // tlb's begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // caches begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_UNIFIED, 37748736, 256, 147456, 12}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1, -1}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
, // POWER5 end
|
|
Packit Service |
a1973e |
{3,
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
{ // level 1 begins
|
|
Packit Service |
a1973e |
{ // tlb's begin
|
|
Packit Service |
a1973e |
/// POWER6 has an ERAT (Effective to Real Address
|
|
Packit Service |
a1973e |
/// Translation) instead of a TLB. For the purposes of this
|
|
Packit Service |
a1973e |
/// data, we will treat it like a TLB.
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_INST, 128, 2, 0}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_DATA, 128, 128, 0}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // caches begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_INST, 65536, 128, 512, 4}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_DATA, 65536, 128, 512, 8}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // level 2 begins
|
|
Packit Service |
a1973e |
{ // tlb's begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // caches begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_UNIFIED, 4194304, 128, 16384, 8}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1, -1}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // level 3 begins
|
|
Packit Service |
a1973e |
{ // tlb's begin
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{ // caches begin
|
|
Packit Service |
a1973e |
/// POWER6 has a 2 slice L3 cache. Each slice is 16MB, so
|
|
Packit Service |
a1973e |
/// combined they are 32MB and usable by each core. For
|
|
Packit Service |
a1973e |
/// this reason, we will treat it as a single 32MB cache.
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_UNIFIED, 33554432, 128, 262144, 16}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
{PAPI_MH_TYPE_EMPTY, -1, -1, -1, -1}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
, // POWER6 end
|
|
Packit Service |
a1973e |
{3,
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
[0] = { // level 1 begins
|
|
Packit Service |
a1973e |
.tlb = {
|
|
Packit Service |
a1973e |
/// POWER7 has an ERAT (Effective to Real Address
|
|
Packit Service |
a1973e |
/// Translation) instead of a TLB. For the purposes of this
|
|
Packit Service |
a1973e |
/// data, we will treat it like a TLB.
|
|
Packit Service |
a1973e |
[0] = { .type = PAPI_MH_TYPE_INST,
|
|
Packit Service |
a1973e |
.num_entries = 64, .page_size = 0, .associativity = 2 }
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { .type = PAPI_MH_TYPE_DATA,
|
|
Packit Service |
a1973e |
.num_entries = 64, .page_size = 0,
|
|
Packit Service |
a1973e |
.associativity = SHRT_MAX }
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
.cache = { // level 1 caches begin
|
|
Packit Service |
a1973e |
[0] = { .type = PAPI_MH_TYPE_INST | PAPI_MH_TYPE_PSEUDO_LRU,
|
|
Packit Service |
a1973e |
.size = 32768, .line_size = 128, .num_lines = 64,
|
|
Packit Service |
a1973e |
.associativity = 4 }
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { .type = PAPI_MH_TYPE_DATA | PAPI_MH_TYPE_WT | PAPI_MH_TYPE_LRU,
|
|
Packit Service |
a1973e |
.size = 32768, .line_size = 128, .num_lines = 32,
|
|
Packit Service |
a1973e |
.associativity = 8 }
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { // level 2 begins
|
|
Packit Service |
a1973e |
.tlb = {
|
|
Packit Service |
a1973e |
[0] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
|
|
Packit Service |
a1973e |
.page_size = -1, .associativity = -1 }
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
|
|
Packit Service |
a1973e |
.page_size = -1, .associativity = -1 }
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
.cache = {
|
|
Packit Service |
a1973e |
[0] = { .type = PAPI_MH_TYPE_UNIFIED | PAPI_MH_TYPE_PSEUDO_LRU,
|
|
Packit Service |
a1973e |
.size = 524288, .line_size = 128, .num_lines = 256,
|
|
Packit Service |
a1973e |
.associativity = 8 }
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
|
|
Packit Service |
a1973e |
.num_lines = -1, .associativity = -1 }
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[2] = { // level 3 begins
|
|
Packit Service |
a1973e |
.tlb = {
|
|
Packit Service |
a1973e |
[0] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
|
|
Packit Service |
a1973e |
.page_size = -1, .associativity = -1 }
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
|
|
Packit Service |
a1973e |
.page_size = -1, .associativity = -1 }
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
.cache = {
|
|
Packit Service |
a1973e |
[0] = { .type = PAPI_MH_TYPE_UNIFIED | PAPI_MH_TYPE_PSEUDO_LRU,
|
|
Packit Service |
a1973e |
.size = 4194304, .line_size = 128, .num_lines = 4096,
|
|
Packit Service |
a1973e |
.associativity = 8 }
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
|
|
Packit Service |
a1973e |
.num_lines = -1, .associativity = -1 }
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}, // POWER7 end
|
|
Packit Service |
a1973e |
{3,
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
[0] = { // level 1 begins
|
|
Packit Service |
a1973e |
.tlb = {
|
|
Packit Service |
a1973e |
/// POWER8 has an ERAT (Effective to Real Address
|
|
Packit Service |
a1973e |
/// Translation) instead of a TLB. For the purposes of this
|
|
Packit Service |
a1973e |
/// data, we will treat it like a TLB.
|
|
Packit Service |
a1973e |
[0] = { .type = PAPI_MH_TYPE_INST,
|
|
Packit Service |
a1973e |
.num_entries = 72, .page_size = 0,
|
|
Packit Service |
a1973e |
.associativity = SHRT_MAX }
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { .type = PAPI_MH_TYPE_DATA,
|
|
Packit Service |
a1973e |
.num_entries = 48, .page_size = 0,
|
|
Packit Service |
a1973e |
.associativity = SHRT_MAX }
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
.cache = { // level 1 caches begin
|
|
Packit Service |
a1973e |
[0] = { .type = PAPI_MH_TYPE_INST | PAPI_MH_TYPE_PSEUDO_LRU,
|
|
Packit Service |
a1973e |
.size = 32768, .line_size = 128, .num_lines = 64,
|
|
Packit Service |
a1973e |
.associativity = 8 }
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { .type = PAPI_MH_TYPE_DATA | PAPI_MH_TYPE_WT | PAPI_MH_TYPE_LRU,
|
|
Packit Service |
a1973e |
.size = 65536, .line_size = 128, .num_lines = 512,
|
|
Packit Service |
a1973e |
.associativity = 8 }
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { // level 2 begins
|
|
Packit Service |
a1973e |
.tlb = {
|
|
Packit Service |
a1973e |
[0] = { .type = PAPI_MH_TYPE_UNIFIED, .num_entries = 2048,
|
|
Packit Service |
a1973e |
.page_size = 0, .associativity = 4 }
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
|
|
Packit Service |
a1973e |
.page_size = -1, .associativity = -1 }
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
.cache = {
|
|
Packit Service |
a1973e |
[0] = { .type = PAPI_MH_TYPE_UNIFIED | PAPI_MH_TYPE_PSEUDO_LRU,
|
|
Packit Service |
a1973e |
.size = 262144, .line_size = 128, .num_lines = 256,
|
|
Packit Service |
a1973e |
.associativity = 8 }
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
|
|
Packit Service |
a1973e |
.num_lines = -1, .associativity = -1 }
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[2] = { // level 3 begins
|
|
Packit Service |
a1973e |
.tlb = {
|
|
Packit Service |
a1973e |
[0] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
|
|
Packit Service |
a1973e |
.page_size = -1, .associativity = -1 }
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { .type = PAPI_MH_TYPE_EMPTY, .num_entries = -1,
|
|
Packit Service |
a1973e |
.page_size = -1, .associativity = -1 }
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
.cache = {
|
|
Packit Service |
a1973e |
[0] = { .type = PAPI_MH_TYPE_UNIFIED | PAPI_MH_TYPE_PSEUDO_LRU,
|
|
Packit Service |
a1973e |
.size = 8388608, .line_size = 128, .num_lines = 65536,
|
|
Packit Service |
a1973e |
.associativity = 8 }
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
[1] = { .type = PAPI_MH_TYPE_EMPTY, .size = -1, .line_size = -1,
|
|
Packit Service |
a1973e |
.num_lines = -1, .associativity = -1 }
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
,
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
} // POWER8 end
|
|
Packit Service |
a1973e |
};
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#define SPRN_PVR 0x11F /* Processor Version Register */
|
|
Packit Service |
a1973e |
#define PVR_PROCESSOR_SHIFT 16
|
|
Packit Service |
a1973e |
static unsigned int
|
|
Packit Service |
a1973e |
mfpvr( void )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
unsigned long pvr;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
asm( "mfspr %0,%1": "=r"( pvr ):"i"( SPRN_PVR ) );
|
|
Packit Service |
a1973e |
return pvr;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
ppc64_get_memory_info( PAPI_hw_info_t * hw_info )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
unsigned int pvr = mfpvr( ) >> PVR_PROCESSOR_SHIFT;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int index;
|
|
Packit Service |
a1973e |
switch ( pvr ) {
|
|
Packit Service |
a1973e |
case 0x39: /* PPC970 */
|
|
Packit Service |
a1973e |
case 0x3C: /* PPC970FX */
|
|
Packit Service |
a1973e |
case 0x44: /* PPC970MP */
|
|
Packit Service |
a1973e |
case 0x45: /* PPC970GX */
|
|
Packit Service |
a1973e |
index = 0;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 0x3A: /* POWER5 */
|
|
Packit Service |
a1973e |
case 0x3B: /* POWER5+ */
|
|
Packit Service |
a1973e |
index = 1;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 0x3E: /* POWER6 */
|
|
Packit Service |
a1973e |
index = 2;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 0x3F: /* POWER7 */
|
|
Packit Service |
a1973e |
index = 3;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 0x4b: /* POWER8 */
|
|
Packit Service |
a1973e |
case 0x4e: /* POWER9 */
|
|
Packit Service |
a1973e |
index = 4;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
default:
|
|
Packit Service |
a1973e |
index = -1;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( index != -1 ) {
|
|
Packit Service |
a1973e |
int cache_level;
|
|
Packit Service |
a1973e |
PAPI_mh_info_t sys_mh_inf = sys_mem_info[index];
|
|
Packit Service |
a1973e |
PAPI_mh_info_t *mh_inf = &hw_info->mem_hierarchy;
|
|
Packit Service |
a1973e |
mh_inf->levels = sys_mh_inf.levels;
|
|
Packit Service |
a1973e |
PAPI_mh_level_t *level = mh_inf->level;
|
|
Packit Service |
a1973e |
PAPI_mh_level_t sys_mh_level;
|
|
Packit Service |
a1973e |
for ( cache_level = 0; cache_level < sys_mh_inf.levels; cache_level++ ) {
|
|
Packit Service |
a1973e |
sys_mh_level = sys_mh_inf.level[cache_level];
|
|
Packit Service |
a1973e |
int cache_idx;
|
|
Packit Service |
a1973e |
for ( cache_idx = 0; cache_idx < 2; cache_idx++ ) {
|
|
Packit Service |
a1973e |
// process TLB info
|
|
Packit Service |
a1973e |
PAPI_mh_tlb_info_t curr_tlb = sys_mh_level.tlb[cache_idx];
|
|
Packit Service |
a1973e |
int type = curr_tlb.type;
|
|
Packit Service |
a1973e |
if ( type != PAPI_MH_TYPE_EMPTY ) {
|
|
Packit Service |
a1973e |
level[cache_level].tlb[cache_idx].type = type;
|
|
Packit Service |
a1973e |
level[cache_level].tlb[cache_idx].associativity =
|
|
Packit Service |
a1973e |
curr_tlb.associativity;
|
|
Packit Service |
a1973e |
level[cache_level].tlb[cache_idx].num_entries =
|
|
Packit Service |
a1973e |
curr_tlb.num_entries;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
for ( cache_idx = 0; cache_idx < 2; cache_idx++ ) {
|
|
Packit Service |
a1973e |
// process cache info
|
|
Packit Service |
a1973e |
PAPI_mh_cache_info_t curr_cache = sys_mh_level.cache[cache_idx];
|
|
Packit Service |
a1973e |
int type = curr_cache.type;
|
|
Packit Service |
a1973e |
if ( type != PAPI_MH_TYPE_EMPTY ) {
|
|
Packit Service |
a1973e |
level[cache_level].cache[cache_idx].type = type;
|
|
Packit Service |
a1973e |
level[cache_level].cache[cache_idx].associativity =
|
|
Packit Service |
a1973e |
curr_cache.associativity;
|
|
Packit Service |
a1973e |
level[cache_level].cache[cache_idx].size = curr_cache.size;
|
|
Packit Service |
a1973e |
level[cache_level].cache[cache_idx].line_size =
|
|
Packit Service |
a1973e |
curr_cache.line_size;
|
|
Packit Service |
a1973e |
level[cache_level].cache[cache_idx].num_lines =
|
|
Packit Service |
a1973e |
curr_cache.num_lines;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
return 0;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#if defined(__sparc__)
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
sparc_sysfs_cpu_attr( char *name, char **result )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
const char *path_base = "/sys/devices/system/cpu/";
|
|
Packit Service |
a1973e |
char path_buf[PATH_MAX];
|
|
Packit Service |
a1973e |
char val_buf[32];
|
|
Packit Service |
a1973e |
DIR *sys_cpu;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
sys_cpu = opendir( path_base );
|
|
Packit Service |
a1973e |
if ( sys_cpu ) {
|
|
Packit Service |
a1973e |
struct dirent *cpu;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
while ( ( cpu = readdir( sys_cpu ) ) != NULL ) {
|
|
Packit Service |
a1973e |
int fd;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( strncmp( "cpu", cpu->d_name, 3 ) )
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
strcpy( path_buf, path_base );
|
|
Packit Service |
a1973e |
strcat( path_buf, cpu->d_name );
|
|
Packit Service |
a1973e |
strcat( path_buf, "/" );
|
|
Packit Service |
a1973e |
strcat( path_buf, name );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
fd = open( path_buf, O_RDONLY );
|
|
Packit Service |
a1973e |
if ( fd < 0 )
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( read( fd, val_buf, 32 ) < 0 )
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
close( fd );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
*result = strdup( val_buf );
|
|
Packit Service |
a1973e |
return 0;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
closedir( sys_cpu );
|
|
Packit Service |
a1973e |
return -1;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
sparc_cpu_attr( char *name, unsigned long long *val )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
char *buf;
|
|
Packit Service |
a1973e |
int r;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
r = sparc_sysfs_cpu_attr( name, &buf );
|
|
Packit Service |
a1973e |
if ( r == -1 )
|
|
Packit Service |
a1973e |
return -1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
sscanf( buf, "%llu", val );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
free( buf );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return 0;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static char *
|
|
Packit Service |
a1973e |
search_cpu_info( FILE * f, char *search_str, char *line )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
/* This code courtesy of our friends in Germany. Thanks Rudolph Berrend\
|
|
Packit Service |
a1973e |
orf! */
|
|
Packit Service |
a1973e |
/* See the home page for the German version of PAPI. */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
char *s;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
while ( fgets( line, 256, f ) != NULL ) {
|
|
Packit Service |
a1973e |
if ( strstr( line, search_str ) != NULL ) {
|
|
Packit Service |
a1973e |
/* ignore all characters in line up to : */
|
|
Packit Service |
a1973e |
for ( s = line; *s && ( *s != ':' ); ++s );
|
|
Packit Service |
a1973e |
if ( *s )
|
|
Packit Service |
a1973e |
return s;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
return NULL;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* End stolen code */
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
sparc_get_memory_info( PAPI_hw_info_t * hw_info )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
unsigned long long cache_size, cache_line_size;
|
|
Packit Service |
a1973e |
/* unsigned long long cycles_per_second; */
|
|
Packit Service |
a1973e |
char maxargs[PAPI_HUGE_STR_LEN];
|
|
Packit Service |
a1973e |
/* PAPI_mh_tlb_info_t *tlb; */
|
|
Packit Service |
a1973e |
PAPI_mh_level_t *level;
|
|
Packit Service |
a1973e |
char *s, *t;
|
|
Packit Service |
a1973e |
FILE *f;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* First, fix up the cpu vendor/model/etc. values */
|
|
Packit Service |
a1973e |
strcpy( hw_info->vendor_string, "Sun" );
|
|
Packit Service |
a1973e |
hw_info->vendor = PAPI_VENDOR_SUN;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
f = fopen( "/proc/cpuinfo", "r" );
|
|
Packit Service |
a1973e |
if ( !f )
|
|
Packit Service |
a1973e |
return PAPI_ESYS;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
rewind( f );
|
|
Packit Service |
a1973e |
s = search_cpu_info( f, "cpu", maxargs );
|
|
Packit Service |
a1973e |
if ( !s ) {
|
|
Packit Service |
a1973e |
fclose( f );
|
|
Packit Service |
a1973e |
return PAPI_ESYS;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
t = strchr( s + 2, '\n' );
|
|
Packit Service |
a1973e |
if ( !t ) {
|
|
Packit Service |
a1973e |
fclose( f );
|
|
Packit Service |
a1973e |
return PAPI_ESYS;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
*t = '\0';
|
|
Packit Service |
a1973e |
strcpy( hw_info->model_string, s + 2 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
fclose( f );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/*
|
|
Packit Service |
a1973e |
if ( sparc_sysfs_cpu_attr( "clock_tick", &s ) == -1 )
|
|
Packit Service |
a1973e |
return PAPI_ESYS;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
sscanf( s, "%llu", &cycles_per_second );
|
|
Packit Service |
a1973e |
free( s );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
hw_info->mhz = cycles_per_second / 1000000;
|
|
Packit Service |
a1973e |
hw_info->clock_mhz = hw_info->mhz;
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Now fetch the cache info */
|
|
Packit Service |
a1973e |
hw_info->mem_hierarchy.levels = 3;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
level = &hw_info->mem_hierarchy.level[0];
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
sparc_cpu_attr( "l1_icache_size", &cache_size );
|
|
Packit Service |
a1973e |
sparc_cpu_attr( "l1_icache_line_size", &cache_line_size );
|
|
Packit Service |
a1973e |
level[0].cache[0].type = PAPI_MH_TYPE_INST;
|
|
Packit Service |
a1973e |
level[0].cache[0].size = cache_size;
|
|
Packit Service |
a1973e |
level[0].cache[0].line_size = cache_line_size;
|
|
Packit Service |
a1973e |
level[0].cache[0].num_lines = cache_size / cache_line_size;
|
|
Packit Service |
a1973e |
level[0].cache[0].associativity = 1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
sparc_cpu_attr( "l1_dcache_size", &cache_size );
|
|
Packit Service |
a1973e |
sparc_cpu_attr( "l1_dcache_line_size", &cache_line_size );
|
|
Packit Service |
a1973e |
level[0].cache[1].type = PAPI_MH_TYPE_DATA | PAPI_MH_TYPE_WT;
|
|
Packit Service |
a1973e |
level[0].cache[1].size = cache_size;
|
|
Packit Service |
a1973e |
level[0].cache[1].line_size = cache_line_size;
|
|
Packit Service |
a1973e |
level[0].cache[1].num_lines = cache_size / cache_line_size;
|
|
Packit Service |
a1973e |
level[0].cache[1].associativity = 1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
sparc_cpu_attr( "l2_cache_size", &cache_size );
|
|
Packit Service |
a1973e |
sparc_cpu_attr( "l2_cache_line_size", &cache_line_size );
|
|
Packit Service |
a1973e |
level[1].cache[0].type = PAPI_MH_TYPE_DATA | PAPI_MH_TYPE_WB;
|
|
Packit Service |
a1973e |
level[1].cache[0].size = cache_size;
|
|
Packit Service |
a1973e |
level[1].cache[0].line_size = cache_line_size;
|
|
Packit Service |
a1973e |
level[1].cache[0].num_lines = cache_size / cache_line_size;
|
|
Packit Service |
a1973e |
level[1].cache[0].associativity = 1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#if 0
|
|
Packit Service |
a1973e |
tlb = &hw_info->mem_hierarchy.level[0].tlb[0];
|
|
Packit Service |
a1973e |
switch ( _perfmon2_pfm_pmu_type ) {
|
|
Packit Service |
a1973e |
case PFMLIB_SPARC_ULTRA12_PMU:
|
|
Packit Service |
a1973e |
tlb[0].type = PAPI_MH_TYPE_INST | PAPI_MH_TYPE_PSEUDO_LRU;
|
|
Packit Service |
a1973e |
tlb[0].num_entries = 64;
|
|
Packit Service |
a1973e |
tlb[0].associativity = SHRT_MAX;
|
|
Packit Service |
a1973e |
tlb[1].type = PAPI_MH_TYPE_DATA | PAPI_MH_TYPE_PSEUDO_LRU;
|
|
Packit Service |
a1973e |
tlb[1].num_entries = 64;
|
|
Packit Service |
a1973e |
tlb[1].associativity = SHRT_MAX;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
case PFMLIB_SPARC_ULTRA3_PMU:
|
|
Packit Service |
a1973e |
case PFMLIB_SPARC_ULTRA3I_PMU:
|
|
Packit Service |
a1973e |
case PFMLIB_SPARC_ULTRA3PLUS_PMU:
|
|
Packit Service |
a1973e |
case PFMLIB_SPARC_ULTRA4PLUS_PMU:
|
|
Packit Service |
a1973e |
level[0].cache[0].associativity = 4;
|
|
Packit Service |
a1973e |
level[0].cache[1].associativity = 4;
|
|
Packit Service |
a1973e |
level[1].cache[0].associativity = 4;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
tlb[0].type = PAPI_MH_TYPE_DATA | PAPI_MH_TYPE_PSEUDO_LRU;
|
|
Packit Service |
a1973e |
tlb[0].num_entries = 16;
|
|
Packit Service |
a1973e |
tlb[0].associativity = SHRT_MAX;
|
|
Packit Service |
a1973e |
tlb[1].type = PAPI_MH_TYPE_INST | PAPI_MH_TYPE_PSEUDO_LRU;
|
|
Packit Service |
a1973e |
tlb[1].num_entries = 16;
|
|
Packit Service |
a1973e |
tlb[1].associativity = SHRT_MAX;
|
|
Packit Service |
a1973e |
tlb[2].type = PAPI_MH_TYPE_DATA;
|
|
Packit Service |
a1973e |
tlb[2].num_entries = 1024;
|
|
Packit Service |
a1973e |
tlb[2].associativity = 2;
|
|
Packit Service |
a1973e |
tlb[3].type = PAPI_MH_TYPE_INST;
|
|
Packit Service |
a1973e |
tlb[3].num_entries = 128;
|
|
Packit Service |
a1973e |
tlb[3].associativity = 2;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
case PFMLIB_SPARC_NIAGARA1:
|
|
Packit Service |
a1973e |
level[0].cache[0].associativity = 4;
|
|
Packit Service |
a1973e |
level[0].cache[1].associativity = 4;
|
|
Packit Service |
a1973e |
level[1].cache[0].associativity = 12;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
tlb[0].type = PAPI_MH_TYPE_INST | PAPI_MH_TYPE_PSEUDO_LRU;
|
|
Packit Service |
a1973e |
tlb[0].num_entries = 64;
|
|
Packit Service |
a1973e |
tlb[0].associativity = SHRT_MAX;
|
|
Packit Service |
a1973e |
tlb[1].type = PAPI_MH_TYPE_DATA | PAPI_MH_TYPE_PSEUDO_LRU;
|
|
Packit Service |
a1973e |
tlb[1].num_entries = 64;
|
|
Packit Service |
a1973e |
tlb[1].associativity = SHRT_MAX;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
case PFMLIB_SPARC_NIAGARA2:
|
|
Packit Service |
a1973e |
level[0].cache[0].associativity = 8;
|
|
Packit Service |
a1973e |
level[0].cache[1].associativity = 4;
|
|
Packit Service |
a1973e |
level[1].cache[0].associativity = 16;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
tlb[0].type = PAPI_MH_TYPE_INST | PAPI_MH_TYPE_PSEUDO_LRU;
|
|
Packit Service |
a1973e |
tlb[0].num_entries = 64;
|
|
Packit Service |
a1973e |
tlb[0].associativity = SHRT_MAX;
|
|
Packit Service |
a1973e |
tlb[1].type = PAPI_MH_TYPE_DATA | PAPI_MH_TYPE_PSEUDO_LRU;
|
|
Packit Service |
a1973e |
tlb[1].num_entries = 128;
|
|
Packit Service |
a1973e |
tlb[1].associativity = SHRT_MAX;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
return 0;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Fallback Linux code to read the cache info from /sys */
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
generic_get_memory_info( PAPI_hw_info_t *hw_info )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int type=0,level,result;
|
|
Packit Service |
a1973e |
int size,line_size,associativity,sets;
|
|
Packit Service |
a1973e |
DIR *dir;
|
|
Packit Service |
a1973e |
FILE *fff;
|
|
Packit Service |
a1973e |
char filename[BUFSIZ],type_string[BUFSIZ];
|
|
Packit Service |
a1973e |
struct dirent *d;
|
|
Packit Service |
a1973e |
int max_level=0;
|
|
Packit Service |
a1973e |
int level_count=0,last_level=-1,level_index=0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
PAPI_mh_level_t *L = hw_info->mem_hierarchy.level;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* open Linux cache dir */
|
|
Packit Service |
a1973e |
/* assume all CPUs same as cpu0. */
|
|
Packit Service |
a1973e |
/* Not necessarily a good assumption */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
dir=opendir("/sys/devices/system/cpu/cpu0/cache");
|
|
Packit Service |
a1973e |
if (dir==NULL) {
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
while(1) {
|
|
Packit Service |
a1973e |
d = readdir(dir);
|
|
Packit Service |
a1973e |
if (d==NULL) break;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (strncmp(d->d_name, "index", 5)) continue;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
MEMDBG("Found %s\n",d->d_name);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/*************/
|
|
Packit Service |
a1973e |
/* Get level */
|
|
Packit Service |
a1973e |
/*************/
|
|
Packit Service |
a1973e |
sprintf(filename,
|
|
Packit Service |
a1973e |
"/sys/devices/system/cpu/cpu0/cache/%s/level",
|
|
Packit Service |
a1973e |
d->d_name);
|
|
Packit Service |
a1973e |
fff=fopen(filename,"r");
|
|
Packit Service |
a1973e |
if (fff==NULL) {
|
|
Packit Service |
a1973e |
MEMDBG("Cannot open level.\n");
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
result=fscanf(fff,"%d",&level);
|
|
Packit Service |
a1973e |
fclose(fff);
|
|
Packit Service |
a1973e |
if (result!=1) {
|
|
Packit Service |
a1973e |
MEMDBG("Could not read cache level\n");
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Index arrays from 0 */
|
|
Packit Service |
a1973e |
level_index=level-1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (level!=last_level) {
|
|
Packit Service |
a1973e |
level_count=0;
|
|
Packit Service |
a1973e |
last_level=level;
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
level_count++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (level_count>=PAPI_MH_MAX_LEVELS) {
|
|
Packit Service |
a1973e |
MEMDBG("Exceeded maximum levels %d\n",
|
|
Packit Service |
a1973e |
PAPI_MH_MAX_LEVELS);
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/************/
|
|
Packit Service |
a1973e |
/* Get type */
|
|
Packit Service |
a1973e |
/************/
|
|
Packit Service |
a1973e |
sprintf(filename,
|
|
Packit Service |
a1973e |
"/sys/devices/system/cpu/cpu0/cache/%s/type",d->d_name);
|
|
Packit Service |
a1973e |
fff=fopen(filename,"r");
|
|
Packit Service |
a1973e |
if (fff==NULL) {
|
|
Packit Service |
a1973e |
MEMDBG("Cannot open type\n");
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
result=fscanf(fff,"%s",type_string);
|
|
Packit Service |
a1973e |
fclose(fff);
|
|
Packit Service |
a1973e |
if (result!=1) {
|
|
Packit Service |
a1973e |
MEMDBG("Could not read cache type\n");
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if (!strcmp(type_string,"Data")) {
|
|
Packit Service |
a1973e |
type=PAPI_MH_TYPE_DATA;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if (!strcmp(type_string,"Instruction")) {
|
|
Packit Service |
a1973e |
type=PAPI_MH_TYPE_INST;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if (!strcmp(type_string,"Unified")) {
|
|
Packit Service |
a1973e |
type=PAPI_MH_TYPE_UNIFIED;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
L[level_index].cache[level_count].type=type;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/*************/
|
|
Packit Service |
a1973e |
/* Get Size */
|
|
Packit Service |
a1973e |
/*************/
|
|
Packit Service |
a1973e |
sprintf(filename,
|
|
Packit Service |
a1973e |
"/sys/devices/system/cpu/cpu0/cache/%s/size",d->d_name);
|
|
Packit Service |
a1973e |
fff=fopen(filename,"r");
|
|
Packit Service |
a1973e |
if (fff==NULL) {
|
|
Packit Service |
a1973e |
MEMDBG("Cannot open size\n");
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
result=fscanf(fff,"%d",&size);
|
|
Packit Service |
a1973e |
fclose(fff);
|
|
Packit Service |
a1973e |
if (result!=1) {
|
|
Packit Service |
a1973e |
MEMDBG("Could not read cache size\n");
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Linux reports in kB, PAPI expects in Bytes */
|
|
Packit Service |
a1973e |
L[level_index].cache[level_count].size=size*1024;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/*************/
|
|
Packit Service |
a1973e |
/* Line Size */
|
|
Packit Service |
a1973e |
/*************/
|
|
Packit Service |
a1973e |
sprintf(filename,
|
|
Packit Service |
a1973e |
"/sys/devices/system/cpu/cpu0/cache/%s/coherency_line_size",
|
|
Packit Service |
a1973e |
d->d_name);
|
|
Packit Service |
a1973e |
fff=fopen(filename,"r");
|
|
Packit Service |
a1973e |
if (fff==NULL) {
|
|
Packit Service |
a1973e |
MEMDBG("Cannot open linesize\n");
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
result=fscanf(fff,"%d",&line_size);
|
|
Packit Service |
a1973e |
fclose(fff);
|
|
Packit Service |
a1973e |
if (result!=1) {
|
|
Packit Service |
a1973e |
MEMDBG("Could not read cache line-size\n");
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
L[level_index].cache[level_count].line_size=line_size;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/*********************/
|
|
Packit Service |
a1973e |
/* Get Associativity */
|
|
Packit Service |
a1973e |
/*********************/
|
|
Packit Service |
a1973e |
sprintf(filename,
|
|
Packit Service |
a1973e |
"/sys/devices/system/cpu/cpu0/cache/%s/ways_of_associativity",
|
|
Packit Service |
a1973e |
d->d_name);
|
|
Packit Service |
a1973e |
fff=fopen(filename,"r");
|
|
Packit Service |
a1973e |
if (fff==NULL) {
|
|
Packit Service |
a1973e |
MEMDBG("Cannot open associativity\n");
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
result=fscanf(fff,"%d",&associativity);
|
|
Packit Service |
a1973e |
fclose(fff);
|
|
Packit Service |
a1973e |
if (result!=1) {
|
|
Packit Service |
a1973e |
MEMDBG("Could not read cache associativity\n");
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
L[level_index].cache[level_count].associativity=associativity;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/************/
|
|
Packit Service |
a1973e |
/* Get Sets */
|
|
Packit Service |
a1973e |
/************/
|
|
Packit Service |
a1973e |
sprintf(filename,
|
|
Packit Service |
a1973e |
"/sys/devices/system/cpu/cpu0/cache/%s/number_of_sets",
|
|
Packit Service |
a1973e |
d->d_name);
|
|
Packit Service |
a1973e |
fff=fopen(filename,"r");
|
|
Packit Service |
a1973e |
if (fff==NULL) {
|
|
Packit Service |
a1973e |
MEMDBG("Cannot open sets\n");
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
result=fscanf(fff,"%d",&sets;;
|
|
Packit Service |
a1973e |
fclose(fff);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (result!=1) {
|
|
Packit Service |
a1973e |
MEMDBG("Could not read cache sets\n");
|
|
Packit Service |
a1973e |
goto unrecoverable_error;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
L[level_index].cache[level_count].num_lines=sets;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (((size*1024)/line_size/associativity)!=sets) {
|
|
Packit Service |
a1973e |
MEMDBG("Warning! sets %d != expected %d\n",
|
|
Packit Service |
a1973e |
sets,((size*1024)/line_size/associativity));
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
MEMDBG("\tL%d %s cache\n",level,type_string);
|
|
Packit Service |
a1973e |
MEMDBG("\t%d kilobytes\n",size);
|
|
Packit Service |
a1973e |
MEMDBG("\t%d byte linesize\n",line_size);
|
|
Packit Service |
a1973e |
MEMDBG("\t%d-way associative\n",associativity);
|
|
Packit Service |
a1973e |
MEMDBG("\t%d lines\n",sets);
|
|
Packit Service |
a1973e |
MEMDBG("\tUnknown inclusivity\n");
|
|
Packit Service |
a1973e |
MEMDBG("\tUnknown replacement algorithm\n");
|
|
Packit Service |
a1973e |
MEMDBG("\tUnknown if victim cache\n");
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (level>max_level) max_level=level;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (level>=PAPI_MAX_MEM_HIERARCHY_LEVELS) {
|
|
Packit Service |
a1973e |
MEMDBG("Exceeded maximum cache level %d\n",
|
|
Packit Service |
a1973e |
PAPI_MAX_MEM_HIERARCHY_LEVELS);
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
hw_info->mem_hierarchy.levels = max_level;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
unrecoverable_error:
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Just say we have no cache */
|
|
Packit Service |
a1973e |
hw_info->mem_hierarchy.levels = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return 0;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_linux_get_memory_info( PAPI_hw_info_t * hwinfo, int cpu_type )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
( void ) cpu_type; /*unused */
|
|
Packit Service |
a1973e |
int retval = PAPI_OK;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#if defined(__i386__)||defined(__x86_64__)
|
|
Packit Service |
a1973e |
x86_get_memory_info( hwinfo );
|
|
Packit Service |
a1973e |
#elif defined(__ia64__)
|
|
Packit Service |
a1973e |
ia64_get_memory_info( hwinfo );
|
|
Packit Service |
a1973e |
#elif defined(__powerpc__)
|
|
Packit Service |
a1973e |
ppc64_get_memory_info( hwinfo );
|
|
Packit Service |
a1973e |
#elif defined(__sparc__)
|
|
Packit Service |
a1973e |
sparc_get_memory_info( hwinfo );
|
|
Packit Service |
a1973e |
#elif defined(__arm__)
|
|
Packit Service |
a1973e |
#warning "WARNING! linux_get_memory_info() does nothing on ARM32!"
|
|
Packit Service |
a1973e |
generic_get_memory_info (hwinfo);
|
|
Packit Service |
a1973e |
#else
|
|
Packit Service |
a1973e |
generic_get_memory_info (hwinfo);
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return retval;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_linux_update_shlib_info( papi_mdi_t *mdi )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
char fname[PAPI_HUGE_STR_LEN];
|
|
Packit Service |
a1973e |
unsigned long t_index = 0, d_index = 0, b_index = 0, counting = 1;
|
|
Packit Service |
a1973e |
char buf[PAPI_HUGE_STR_LEN + PAPI_HUGE_STR_LEN], perm[5], dev[16];
|
|
Packit Service |
a1973e |
char mapname[PAPI_HUGE_STR_LEN], lastmapname[PAPI_HUGE_STR_LEN];
|
|
Packit Service |
a1973e |
unsigned long begin = 0, end = 0, size = 0, inode = 0, foo = 0;
|
|
Packit Service |
a1973e |
PAPI_address_map_t *tmp = NULL;
|
|
Packit Service |
a1973e |
FILE *f;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset( fname, 0x0, sizeof ( fname ) );
|
|
Packit Service |
a1973e |
memset( buf, 0x0, sizeof ( buf ) );
|
|
Packit Service |
a1973e |
memset( perm, 0x0, sizeof ( perm ) );
|
|
Packit Service |
a1973e |
memset( dev, 0x0, sizeof ( dev ) );
|
|
Packit Service |
a1973e |
memset( mapname, 0x0, sizeof ( mapname ) );
|
|
Packit Service |
a1973e |
memset( lastmapname, 0x0, sizeof ( lastmapname ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
sprintf( fname, "/proc/%ld/maps", ( long ) mdi->pid );
|
|
Packit Service |
a1973e |
f = fopen( fname, "r" );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !f ) {
|
|
Packit Service |
a1973e |
PAPIERROR( "fopen(%s) returned < 0", fname );
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
again:
|
|
Packit Service |
a1973e |
while ( !feof( f ) ) {
|
|
Packit Service |
a1973e |
begin = end = size = inode = foo = 0;
|
|
Packit Service |
a1973e |
if ( fgets( buf, sizeof ( buf ), f ) == 0 )
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
/* If mapname is null in the string to be scanned, we need to detect that */
|
|
Packit Service |
a1973e |
if ( strlen( mapname ) )
|
|
Packit Service |
a1973e |
strcpy( lastmapname, mapname );
|
|
Packit Service |
a1973e |
else
|
|
Packit Service |
a1973e |
lastmapname[0] = '\0';
|
|
Packit Service |
a1973e |
/* If mapname is null in the string to be scanned, we need to detect that */
|
|
Packit Service |
a1973e |
mapname[0] = '\0';
|
|
Packit Service |
a1973e |
sscanf( buf, "%lx-%lx %4s %lx %s %ld %s", &begin, &end, perm, &foo, dev,
|
|
Packit Service |
a1973e |
&inode, mapname );
|
|
Packit Service |
a1973e |
size = end - begin;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* the permission string looks like "rwxp", where each character can
|
|
Packit Service |
a1973e |
* be either the letter, or a hyphen. The final character is either
|
|
Packit Service |
a1973e |
* p for private or s for shared. */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( counting ) {
|
|
Packit Service |
a1973e |
if ( ( perm[2] == 'x' ) && ( perm[0] == 'r' ) && ( inode != 0 ) ) {
|
|
Packit Service |
a1973e |
if ( strcmp( mdi->exe_info.fullname, mapname )
|
|
Packit Service |
a1973e |
== 0 ) {
|
|
Packit Service |
a1973e |
mdi->exe_info.address_info.text_start =
|
|
Packit Service |
a1973e |
( caddr_t ) begin;
|
|
Packit Service |
a1973e |
mdi->exe_info.address_info.text_end =
|
|
Packit Service |
a1973e |
( caddr_t ) ( begin + size );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
t_index++;
|
|
Packit Service |
a1973e |
} else if ( ( perm[0] == 'r' ) && ( perm[1] == 'w' ) &&
|
|
Packit Service |
a1973e |
( inode != 0 )
|
|
Packit Service |
a1973e |
&&
|
|
Packit Service |
a1973e |
( strcmp
|
|
Packit Service |
a1973e |
( mdi->exe_info.fullname,
|
|
Packit Service |
a1973e |
mapname ) == 0 ) ) {
|
|
Packit Service |
a1973e |
mdi->exe_info.address_info.data_start =
|
|
Packit Service |
a1973e |
( caddr_t ) begin;
|
|
Packit Service |
a1973e |
mdi->exe_info.address_info.data_end =
|
|
Packit Service |
a1973e |
( caddr_t ) ( begin + size );
|
|
Packit Service |
a1973e |
d_index++;
|
|
Packit Service |
a1973e |
} else if ( ( perm[0] == 'r' ) && ( perm[1] == 'w' ) &&
|
|
Packit Service |
a1973e |
( inode == 0 )
|
|
Packit Service |
a1973e |
&&
|
|
Packit Service |
a1973e |
( strcmp
|
|
Packit Service |
a1973e |
( mdi->exe_info.fullname,
|
|
Packit Service |
a1973e |
lastmapname ) == 0 ) ) {
|
|
Packit Service |
a1973e |
mdi->exe_info.address_info.bss_start =
|
|
Packit Service |
a1973e |
( caddr_t ) begin;
|
|
Packit Service |
a1973e |
mdi->exe_info.address_info.bss_end =
|
|
Packit Service |
a1973e |
( caddr_t ) ( begin + size );
|
|
Packit Service |
a1973e |
b_index++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
} else if ( !counting ) {
|
|
Packit Service |
a1973e |
if ( ( perm[2] == 'x' ) && ( perm[0] == 'r' ) && ( inode != 0 ) ) {
|
|
Packit Service |
a1973e |
if ( strcmp( mdi->exe_info.fullname, mapname )
|
|
Packit Service |
a1973e |
!= 0 ) {
|
|
Packit Service |
a1973e |
t_index++;
|
|
Packit Service |
a1973e |
tmp[t_index - 1].text_start = ( caddr_t ) begin;
|
|
Packit Service |
a1973e |
tmp[t_index - 1].text_end = ( caddr_t ) ( begin + size );
|
|
Packit Service |
a1973e |
strncpy( tmp[t_index - 1].name, mapname, PAPI_MAX_STR_LEN );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
} else if ( ( perm[0] == 'r' ) && ( perm[1] == 'w' ) &&
|
|
Packit Service |
a1973e |
( inode != 0 ) ) {
|
|
Packit Service |
a1973e |
if ( ( strcmp
|
|
Packit Service |
a1973e |
( mdi->exe_info.fullname,
|
|
Packit Service |
a1973e |
mapname ) != 0 )
|
|
Packit Service |
a1973e |
&& ( t_index > 0 ) &&
|
|
Packit Service |
a1973e |
( tmp[t_index - 1].data_start == 0 ) ) {
|
|
Packit Service |
a1973e |
tmp[t_index - 1].data_start = ( caddr_t ) begin;
|
|
Packit Service |
a1973e |
tmp[t_index - 1].data_end = ( caddr_t ) ( begin + size );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
} else if ( ( perm[0] == 'r' ) && ( perm[1] == 'w' ) &&
|
|
Packit Service |
a1973e |
( inode == 0 ) ) {
|
|
Packit Service |
a1973e |
if ( ( t_index > 0 ) && ( tmp[t_index - 1].bss_start == 0 ) ) {
|
|
Packit Service |
a1973e |
tmp[t_index - 1].bss_start = ( caddr_t ) begin;
|
|
Packit Service |
a1973e |
tmp[t_index - 1].bss_end = ( caddr_t ) ( begin + size );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( counting ) {
|
|
Packit Service |
a1973e |
/* When we get here, we have counted the number of entries in the map
|
|
Packit Service |
a1973e |
for us to allocate */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
tmp =
|
|
Packit Service |
a1973e |
( PAPI_address_map_t * ) papi_calloc( t_index,
|
|
Packit Service |
a1973e |
sizeof
|
|
Packit Service |
a1973e |
( PAPI_address_map_t ) );
|
|
Packit Service |
a1973e |
if ( tmp == NULL ) {
|
|
Packit Service |
a1973e |
PAPIERROR( "Error allocating shared library address map" );
|
|
Packit Service |
a1973e |
fclose(f);
|
|
Packit Service |
a1973e |
return PAPI_ENOMEM;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
t_index = 0;
|
|
Packit Service |
a1973e |
rewind( f );
|
|
Packit Service |
a1973e |
counting = 0;
|
|
Packit Service |
a1973e |
goto again;
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
if ( mdi->shlib_info.map )
|
|
Packit Service |
a1973e |
papi_free( mdi->shlib_info.map );
|
|
Packit Service |
a1973e |
mdi->shlib_info.map = tmp;
|
|
Packit Service |
a1973e |
mdi->shlib_info.count = t_index;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
fclose( f );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return PAPI_OK;
|
|
Packit Service |
a1973e |
}
|