libports: Ported libpfm4 to Genode.

This commit is contained in:
Michael Mueller
2022-12-08 11:20:24 +01:00
parent 84a5e1ac0a
commit fb91e40f0c
12 changed files with 1508 additions and 1 deletions

View File

@@ -0,0 +1,68 @@
set build_components {
core init timer app/libpfm_test
}
source ${genode_dir}/repos/base/run/platform_drv.inc
append_platform_drv_build_components
build $build_components
create_boot_directory
set config {
<config>
<parent-provides>
<service name="LOG"/>
<service name="LOG"/>
<service name="PD"/>
<service name="CPU"/>
<service name="ROM"/>
<service name="RAM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="CAP"/>
<service name="RM"/>
<service name="SIGNAL"/>
<service name="TOPO"/>
</parent-provides>
<default-route>
<any-service><parent/><any-child/></any-service>
</default-route>
<default caps="200"/>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
<route>
<any-service><parent/><any-child/></any-service>
</route>
</start>
}
append config {
<start name="libpfm_test">
<resource name="RAM" quantum="10M"/>
<config>
<vfs> <dir name="dev"> <log/> <inline name="rtc">2022-07-20 14:30</inline> </dir> </vfs>
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
</config>
<route>
<service name="Timer"><child name="timer"/></service>
<any-service><parent/><any-child/></any-service>
</route>
</start>
</config>
}
install_config $config
set boot_modules {
core init timer vfs.lib.so ld.lib.so posix.lib.so libc.lib.so libm.lib.so stdcxx.lib.so libpfm_test
}
append_platform_drv_boot_modules
build_boot_image $boot_modules
append qemu_args "-nographic "
run_genode_until forever

View File

@@ -0,0 +1,174 @@
/*
* check_events.c - show event encoding
*
* Copyright (c) 2009 Google, Inc
* Contributed by Stephane Eranian <eranian@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* This file is part of libpfm, a performance monitoring support library for
* applications on Linux.
*/
#include <sys/types.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <perfmon/err.h>
#include <perfmon/pfmlib.h>
int pmu_is_present(pfm_pmu_t p)
{
pfm_pmu_info_t pinfo;
int ret;
memset(&pinfo, 0, sizeof(pinfo));
ret = pfm_get_pmu_info(p, &pinfo);
return ret == PFM_SUCCESS ? pinfo.is_present : 0;
}
int main(int argc, const char **argv)
{
pfm_pmu_info_t pinfo;
pfm_pmu_encode_arg_t e;
const char *arg[3];
const char **p;
char *fqstr;
pfm_event_info_t info;
int j, ret;
pfm_pmu_t i;
int total_supported_events = 0;
int total_available_events = 0;
unsigned long low, high, msr;
msr = 0xc0010200;
asm volatile("rdmsr"
: "=a"(low), "=d"(high)
: "c"(msr)); /*
* Initialize pfm library (required before we can use it)
*/
ret = pfm_initialize();
if (ret != PFM_SUCCESS)
errx(1, "cannot initialize library: %s\n", pfm_strerror(ret));
memset(&pinfo, 0, sizeof(pinfo));
memset(&info, 0, sizeof(info));
printf("Supported PMU models:\n");
for (i = PFM_PMU_NONE; i < PFM_PMU_MAX; i++)
{
ret = pfm_get_pmu_info(i, &pinfo);
if (ret != PFM_SUCCESS)
continue;
printf("\t[%d, %s, \"%s\"]\n", i, pinfo.name, pinfo.desc);
}
printf("Detected PMU models:\n");
for (i = PFM_PMU_NONE; i < PFM_PMU_MAX; i++)
{
ret = pfm_get_pmu_info(i, &pinfo);
if (ret != PFM_SUCCESS)
continue;
if (pinfo.is_present)
{
printf("\t[%d, %s, \"%s\"]\n", i, pinfo.name, pinfo.desc);
total_supported_events += pinfo.nevents;
}
total_available_events += pinfo.nevents;
}
printf("Total events: %d available, %d supported\n", total_available_events, total_supported_events);
/*
* be nice to user!
*/
if (argc < 2 && pmu_is_present(PFM_PMU_PERF_EVENT))
{
arg[0] = "PERF_COUNT_HW_CPU_CYCLES";
arg[1] = "PERF_COUNT_HW_INSTRUCTIONS";
arg[2] = NULL;
p = arg;
}
else
{
p = argv + 1;
}
if (!*p)
errx(1, "you must pass at least one event");
memset(&e, 0, sizeof(e));
while (*p)
{
/*
* extract raw event encoding
*
* For perf_event encoding, use
* #include <perfmon/pfmlib_perf_event.h>
* and the function:
* pfm_get_perf_event_encoding()
*/
fqstr = NULL;
e.fstr = &fqstr;
ret = pfm_get_os_event_encoding(*p, PFM_PLM0 | PFM_PLM3, PFM_OS_NONE, &e);
if (ret != PFM_SUCCESS)
{
/*
* codes is too small for this event
* free and let the library resize
*/
if (ret == PFM_ERR_TOOSMALL)
{
free(e.codes);
e.codes = NULL;
e.count = 0;
free(fqstr);
continue;
}
if (ret == PFM_ERR_NOTFOUND && strstr(*p, "::"))
errx(1, "%s: try setting LIBPFM_ENCODE_INACTIVE=1", pfm_strerror(ret));
errx(1, "cannot encode event %s: %s", *p, pfm_strerror(ret));
}
ret = pfm_get_event_info(e.idx, PFM_OS_NONE, &info);
if (ret != PFM_SUCCESS)
errx(1, "cannot get event info: %s", pfm_strerror(ret));
ret = pfm_get_pmu_info(info.pmu, &pinfo);
if (ret != PFM_SUCCESS)
errx(1, "cannot get PMU info: %s", pfm_strerror(ret));
printf("Requested Event: %s\n", *p);
printf("Actual Event: %s\n", fqstr);
printf("PMU : %s\n", pinfo.desc);
printf("IDX : %d\n", e.idx);
printf("Codes :");
for (j = 0; j < e.count; j++)
printf(" 0x%" PRIx64, e.codes[j]);
putchar('\n');
free(fqstr);
p++;
}
if (e.codes)
free(e.codes);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
TARGET = libpfm_test
SRC_CC = check_events.c
LIBS += base posix libm libc stdcxx libpfm4
CC_OPT += -Wno-error -Wno-permissive -fpermissive

View File

@@ -1,4 +1,4 @@
TARGET = thread_test
SRC_CC = thread_test.cc
LIBS += base stdcxx
LIBS += base libc stdcxx
CXXFLAGS += -Wno-error