aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libpmc/Makefile1
-rw-r--r--lib/libpmc/libpmc.c118
-rw-r--r--lib/libpmc/pmc.33
-rw-r--r--lib/libpmc/pmc.atom.31
-rw-r--r--lib/libpmc/pmc.core.31
-rw-r--r--lib/libpmc/pmc.core2.31
-rw-r--r--lib/libpmc/pmc.corei7.31
-rw-r--r--lib/libpmc/pmc.corei7uc.31
-rw-r--r--lib/libpmc/pmc.iaf.31
-rw-r--r--lib/libpmc/pmc.k7.31
-rw-r--r--lib/libpmc/pmc.k8.31
-rw-r--r--lib/libpmc/pmc.mips24k.31
-rw-r--r--lib/libpmc/pmc.octeon.31
-rw-r--r--lib/libpmc/pmc.p4.31
-rw-r--r--lib/libpmc/pmc.p5.31
-rw-r--r--lib/libpmc/pmc.p6.31
-rw-r--r--lib/libpmc/pmc.sandybridge.31
-rw-r--r--lib/libpmc/pmc.sandybridgeuc.31
-rw-r--r--lib/libpmc/pmc.soft.3104
-rw-r--r--lib/libpmc/pmc.tsc.31
-rw-r--r--lib/libpmc/pmc.ucf.31
-rw-r--r--lib/libpmc/pmc.westmere.31
-rw-r--r--lib/libpmc/pmc.westmereuc.31
-rw-r--r--lib/libpmc/pmc.xscale.31
-rw-r--r--lib/libpmc/pmclog.c6
-rw-r--r--lib/libpmc/pmclog.h8
26 files changed, 234 insertions, 26 deletions
diff --git a/lib/libpmc/Makefile b/lib/libpmc/Makefile
index 95da88e6df1e..5edbfe6419ef 100644
--- a/lib/libpmc/Makefile
+++ b/lib/libpmc/Makefile
@@ -20,6 +20,7 @@ MAN+= pmc_read.3
MAN+= pmc_set.3
MAN+= pmc_start.3
MAN+= pmclog.3
+MAN+= pmc.soft.3
# PMC-dependent manual pages
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c
index 4323171e7443..3b7dc376ed27 100644
--- a/lib/libpmc/libpmc.c
+++ b/lib/libpmc/libpmc.c
@@ -77,11 +77,12 @@ static int tsc_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
static int xscale_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
#endif
-
#if defined(__mips__)
static int mips_allocate_pmc(enum pmc_event _pe, char* ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
#endif /* __mips__ */
+static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
+ struct pmc_op_pmcallocate *_pmc_config);
#if defined(__powerpc__)
static int ppc7450_allocate_pmc(enum pmc_event _pe, char* ctrspec,
@@ -156,6 +157,8 @@ PMC_CLASSDEP_TABLE(octeon, OCTEON);
PMC_CLASSDEP_TABLE(ucf, UCF);
PMC_CLASSDEP_TABLE(ppc7450, PPC7450);
+static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT];
+
#undef __PMC_EV_ALIAS
#define __PMC_EV_ALIAS(N,CODE) { N, PMC_EV_##CODE },
@@ -215,21 +218,22 @@ static const struct pmc_event_descr westmereuc_event_table[] =
PMC_CLASS_##C, __VA_ARGS__ \
}
-PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(core, IAP, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
-PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
-PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
-PMC_MDEP_TABLE(k7, K7, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(k8, K8, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(p4, P4, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(p5, P5, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(p6, P6, PMC_CLASS_TSC);
-PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_XSCALE);
-PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_MIPS24K);
-PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_OCTEON);
-PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_PPC7450);
+PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(core, IAP, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
+PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
+PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
+PMC_MDEP_TABLE(k7, K7, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(k8, K8, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(p4, P4, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(p5, P5, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(p6, P6, PMC_CLASS_SOFT, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE);
+PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K);
+PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON);
+PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450);
+PMC_MDEP_TABLE(generic, SOFT, PMC_CLASS_SOFT);
static const struct pmc_event_descr tsc_event_table[] =
{
@@ -279,16 +283,24 @@ PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc);
#if defined(__XSCALE__)
PMC_CLASS_TABLE_DESC(xscale, XSCALE, xscale, xscale);
#endif
-
#if defined(__mips__)
PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips);
PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips);
#endif /* __mips__ */
-
#if defined(__powerpc__)
PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, ppc7450);
#endif
+static struct pmc_class_descr soft_class_table_descr =
+{
+ .pm_evc_name = "SOFT-",
+ .pm_evc_name_size = sizeof("SOFT-") - 1,
+ .pm_evc_class = PMC_CLASS_SOFT,
+ .pm_evc_event_table = NULL,
+ .pm_evc_event_table_size = 0,
+ .pm_evc_allocate_pmc = soft_allocate_pmc
+};
+
#undef PMC_CLASS_TABLE_DESC
static const struct pmc_class_descr **pmc_class_table;
@@ -343,9 +355,12 @@ static const char * pmc_state_names[] = {
__PMC_STATES()
};
-static int pmc_syscall = -1; /* filled in by pmc_init() */
-
-static struct pmc_cpuinfo cpu_info; /* filled in by pmc_init() */
+/*
+ * Filled in by pmc_init().
+ */
+static int pmc_syscall = -1;
+static struct pmc_cpuinfo cpu_info;
+static struct pmc_op_getdyneventinfo soft_event_info;
/* Event masks for events */
struct pmc_masks {
@@ -2179,6 +2194,25 @@ tsc_allocate_pmc(enum pmc_event pe, char *ctrspec,
}
#endif
+static struct pmc_event_alias generic_aliases[] = {
+ EV_ALIAS("instructions", "SOFT-CLOCK.HARD"),
+ EV_ALIAS(NULL, NULL)
+};
+
+static int
+soft_allocate_pmc(enum pmc_event pe, char *ctrspec,
+ struct pmc_op_pmcallocate *pmc_config)
+{
+ (void)ctrspec;
+ (void)pmc_config;
+
+ if (pe < PMC_EV_SOFT_FIRST || pe > PMC_EV_SOFT_LAST)
+ return (-1);
+
+ pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
+ return (0);
+}
+
#if defined(__XSCALE__)
static struct pmc_event_alias xscale_aliases[] = {
@@ -2663,6 +2697,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
ev = ppc7450_event_table;
count = PMC_EVENT_TABLE_SIZE(ppc7450);
break;
+ case PMC_CLASS_SOFT:
+ ev = soft_event_table;
+ count = soft_event_info.pm_nevent;
+ break;
default:
errno = EINVAL;
return (-1);
@@ -2676,6 +2714,7 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
for (;count--; ev++, names++)
*names = ev->pm_ev_name;
+
return (0);
}
@@ -2780,11 +2819,34 @@ pmc_init(void)
pmc_class_table[n] = NULL;
/*
+ * Get soft events list.
+ */
+ soft_event_info.pm_class = PMC_CLASS_SOFT;
+ if (PMC_CALL(GETDYNEVENTINFO, &soft_event_info) < 0)
+ return (pmc_syscall = -1);
+
+ /* Map soft events to static list. */
+ for (n = 0; n < soft_event_info.pm_nevent; n++) {
+ soft_event_table[n].pm_ev_name =
+ soft_event_info.pm_events[n].pm_ev_name;
+ soft_event_table[n].pm_ev_code =
+ soft_event_info.pm_events[n].pm_ev_code;
+ }
+ soft_class_table_descr.pm_evc_event_table_size = \
+ soft_event_info.pm_nevent;
+ soft_class_table_descr.pm_evc_event_table = \
+ soft_event_table;
+
+ /*
* Fill in the class table.
*/
n = 0;
+
+ /* Fill soft events information. */
+ pmc_class_table[n++] = &soft_class_table_descr;
#if defined(__amd64__) || defined(__i386__)
- pmc_class_table[n++] = &tsc_class_table_descr;
+ if (cpu_info.pm_cputype != PMC_CPU_GENERIC)
+ pmc_class_table[n++] = &tsc_class_table_descr;
/*
* Check if this CPU has fixed function counters.
@@ -2867,6 +2929,9 @@ pmc_init(void)
pmc_class_table[n] = &p4_class_table_descr;
break;
#endif
+ case PMC_CPU_GENERIC:
+ PMC_MDEP_INIT(generic);
+ break;
#if defined(__XSCALE__)
case PMC_CPU_INTEL_XSCALE:
PMC_MDEP_INIT(xscale);
@@ -3035,18 +3100,19 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu)
evfence = xscale_event_table + PMC_EVENT_TABLE_SIZE(xscale);
} else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) {
ev = mips24k_event_table;
- evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k
-);
+ evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k);
} else if (pe >= PMC_EV_OCTEON_FIRST && pe <= PMC_EV_OCTEON_LAST) {
ev = octeon_event_table;
evfence = octeon_event_table + PMC_EVENT_TABLE_SIZE(octeon);
} else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) {
ev = ppc7450_event_table;
- evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450
-);
+ evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450);
} else if (pe == PMC_EV_TSC_TSC) {
ev = tsc_event_table;
evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc);
+ } else if (pe >= PMC_EV_SOFT_FIRST && pe <= PMC_EV_SOFT_LAST) {
+ ev = soft_event_table;
+ evfence = soft_event_table + soft_event_info.pm_nevent;
}
for (; ev != evfence; ev++)
diff --git a/lib/libpmc/pmc.3 b/lib/libpmc/pmc.3
index 0a537a593314..cf74f321076d 100644
--- a/lib/libpmc/pmc.3
+++ b/lib/libpmc/pmc.3
@@ -223,6 +223,8 @@ and
CPUs.
.It Li PMC_CLASS_TSC
The timestamp counter on i386 and amd64 architecture CPUs.
+.It Li PMC_CLASS_SOFT
+Software events.
.El
.Ss PMC Capabilities
Capabilities of performance monitoring hardware are denoted using
@@ -525,6 +527,7 @@ API is
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4 ,
diff --git a/lib/libpmc/pmc.atom.3 b/lib/libpmc/pmc.atom.3
index 2ebb80483c8a..f61a1415ec43 100644
--- a/lib/libpmc/pmc.atom.3
+++ b/lib/libpmc/pmc.atom.3
@@ -1176,6 +1176,7 @@ and the underlying hardware events used on these CPUs.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.core.3 b/lib/libpmc/pmc.core.3
index 512e4921c31b..73b2cea754de 100644
--- a/lib/libpmc/pmc.core.3
+++ b/lib/libpmc/pmc.core.3
@@ -792,6 +792,7 @@ may not count some transitions.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
diff --git a/lib/libpmc/pmc.core2.3 b/lib/libpmc/pmc.core2.3
index 56c015ba9391..5c6b533164f9 100644
--- a/lib/libpmc/pmc.core2.3
+++ b/lib/libpmc/pmc.core2.3
@@ -1107,6 +1107,7 @@ and the underlying hardware events used.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.corei7.3 b/lib/libpmc/pmc.corei7.3
index 8e092500e90a..aaf1f022615f 100644
--- a/lib/libpmc/pmc.corei7.3
+++ b/lib/libpmc/pmc.corei7.3
@@ -1559,6 +1559,7 @@ Counts number of segment register loads.
.Xr pmc.corei7uc 3 ,
.Xr pmc.westmere 3 ,
.Xr pmc.westmereuc 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.corei7uc.3 b/lib/libpmc/pmc.corei7uc.3
index c92698004e6b..3114c8ea9f6a 100644
--- a/lib/libpmc/pmc.corei7uc.3
+++ b/lib/libpmc/pmc.corei7uc.3
@@ -863,6 +863,7 @@ refreshed or needs to go into a power down mode.
.Xr pmc.corei7 3 ,
.Xr pmc.westmere 3 ,
.Xr pmc.westmereuc 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.iaf.3 b/lib/libpmc/pmc.iaf.3
index aa39a7cc9f74..7e623d6548ac 100644
--- a/lib/libpmc/pmc.iaf.3
+++ b/lib/libpmc/pmc.iaf.3
@@ -132,6 +132,7 @@ CPU, use the event specifier
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.k7.3 b/lib/libpmc/pmc.k7.3
index 59e64896cee0..646f35275149 100644
--- a/lib/libpmc/pmc.k7.3
+++ b/lib/libpmc/pmc.k7.3
@@ -249,6 +249,7 @@ and the underlying hardware events used.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
diff --git a/lib/libpmc/pmc.k8.3 b/lib/libpmc/pmc.k8.3
index e4eb081b4d7e..628137d7ffaf 100644
--- a/lib/libpmc/pmc.k8.3
+++ b/lib/libpmc/pmc.k8.3
@@ -783,6 +783,7 @@ and the underlying hardware events used.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
diff --git a/lib/libpmc/pmc.mips24k.3 b/lib/libpmc/pmc.mips24k.3
index dc49f09e8a77..4acb0a7eab94 100644
--- a/lib/libpmc/pmc.mips24k.3
+++ b/lib/libpmc/pmc.mips24k.3
@@ -392,6 +392,7 @@ and the underlying hardware events used.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.octeon.3 b/lib/libpmc/pmc.octeon.3
index d0ef3dedabe3..be38dd8c5786 100644
--- a/lib/libpmc/pmc.octeon.3
+++ b/lib/libpmc/pmc.octeon.3
@@ -232,6 +232,7 @@ and the underlying hardware events used.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.p4.3 b/lib/libpmc/pmc.p4.3
index 3d89fc140a6c..b273edd8b1e7 100644
--- a/lib/libpmc/pmc.p4.3
+++ b/lib/libpmc/pmc.p4.3
@@ -1208,6 +1208,7 @@ and the underlying hardware events used.
.Xr pmc.k8 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
diff --git a/lib/libpmc/pmc.p5.3 b/lib/libpmc/pmc.p5.3
index dae43e34894f..ebdd5054e2d5 100644
--- a/lib/libpmc/pmc.p5.3
+++ b/lib/libpmc/pmc.p5.3
@@ -444,6 +444,7 @@ and the underlying hardware events used.
.Xr pmc.k8 3 ,
.Xr pmc.p4 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
diff --git a/lib/libpmc/pmc.p6.3 b/lib/libpmc/pmc.p6.3
index 2033cce35fc0..3fa98a75a396 100644
--- a/lib/libpmc/pmc.p6.3
+++ b/lib/libpmc/pmc.p6.3
@@ -1010,6 +1010,7 @@ and the underlying hardware events used.
.Xr pmc.k8 3 ,
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
diff --git a/lib/libpmc/pmc.sandybridge.3 b/lib/libpmc/pmc.sandybridge.3
index d530d1573dff..e0c7eb9925c8 100644
--- a/lib/libpmc/pmc.sandybridge.3
+++ b/lib/libpmc/pmc.sandybridge.3
@@ -907,6 +907,7 @@ Split locks in SQ.
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
.Xr pmc.sandybridgeuc 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc.ucf 3 ,
.Xr pmc.westmere 3 ,
diff --git a/lib/libpmc/pmc.sandybridgeuc.3 b/lib/libpmc/pmc.sandybridgeuc.3
index 19904b37cd51..207848238732 100644
--- a/lib/libpmc/pmc.sandybridgeuc.3
+++ b/lib/libpmc/pmc.sandybridgeuc.3
@@ -208,6 +208,7 @@ Counts the number of core-outgoing entries in the coherent tracker queue.
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
.Xr pmc.sandybridge 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc.ucf 3 ,
.Xr pmc.westmere 3 ,
diff --git a/lib/libpmc/pmc.soft.3 b/lib/libpmc/pmc.soft.3
new file mode 100644
index 000000000000..f7d0cb05ee07
--- /dev/null
+++ b/lib/libpmc/pmc.soft.3
@@ -0,0 +1,104 @@
+.\" Copyright (c) 2012 Fabien Thomas. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 28, 2012
+.Os
+.Dt PMC.SOFT 3
+.Sh NAME
+.Nm pmc.soft
+.Nd measurements using software based events
+.Sh LIBRARY
+.Lb libpmc
+.Sh SYNOPSIS
+.In pmc.h
+.Sh DESCRIPTION
+Software events are used to collect various source of software events.
+.Ss PMC Features
+16 sampling counters using software events based on various sources.
+These PMCs support the following capabilities:
+.Bl -column "PMC_CAP_INTERRUPT" "Support"
+.It Em Capability Ta Em Support
+.It PMC_CAP_CASCADE Ta \&No
+.It PMC_CAP_EDGE Ta \&No
+.It PMC_CAP_INTERRUPT Ta Yes
+.It PMC_CAP_INVERT Ta \&No
+.It PMC_CAP_READ Ta Yes
+.It PMC_CAP_PRECISE Ta \&No
+.It PMC_CAP_SYSTEM Ta Yes
+.It PMC_CAP_TAGGING Ta \&No
+.It PMC_CAP_THRESHOLD Ta \&No
+.It PMC_CAP_USER Ta Yes
+.It PMC_CAP_WRITE Ta Yes
+.El
+.Ss Event Qualifiers
+There is no supported event qualifier.
+.Pp
+The event specifiers supported by software are:
+.Bl -tag -width indent
+.It Li CLOCK.HARD
+Hard clock ticks.
+.It Li CLOCK.STAT
+Stat clock ticks.
+.It Li LOCK.FAILED
+Lock acquisition failed.
+.It Li PAGE_FAULT.ALL
+All page fault type.
+.It Li PAGE_FAULT.READ
+Read page fault.
+.It Li PAGE_FAULT.WRITE
+Write page fault.
+.El
+.Sh SEE ALSO
+.Xr pmc 3 ,
+.Xr pmc.atom 3 ,
+.Xr pmc.core 3 ,
+.Xr pmc.iaf 3 ,
+.Xr pmc.ucf 3 ,
+.Xr pmc.k7 3 ,
+.Xr pmc.k8 3 ,
+.Xr pmc.p4 3 ,
+.Xr pmc.p5 3 ,
+.Xr pmc.p6 3 ,
+.Xr pmc.corei7 3 ,
+.Xr pmc.corei7uc 3 ,
+.Xr pmc.westmereuc 3 ,
+.Xr pmc.tsc 3 ,
+.Xr pmc_cpuinfo 3 ,
+.Xr pmclog 3 ,
+.Xr hwpmc 4
+.Sh HISTORY
+The
+.Nm pmc
+library first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Lb libpmc
+library was written by
+.An "Joseph Koshy"
+.Aq jkoshy@FreeBSD.org .
+Software PMC was written by
+.An "Fabien Thomas"
+.Aq fabient@FreeBSD.org .
diff --git a/lib/libpmc/pmc.tsc.3 b/lib/libpmc/pmc.tsc.3
index 1abda30f8ebe..269200549d69 100644
--- a/lib/libpmc/pmc.tsc.3
+++ b/lib/libpmc/pmc.tsc.3
@@ -68,6 +68,7 @@ maps to the TSC.
.Xr pmc.p4 3 ,
.Xr pmc.p5 3 ,
.Xr pmc.p6 3 ,
+.Xr pmc.soft 3 ,
.Xr pmclog 3 ,
.Xr hwpmc 4
.Sh HISTORY
diff --git a/lib/libpmc/pmc.ucf.3 b/lib/libpmc/pmc.ucf.3
index 5a908f52e5c0..15399e43d02e 100644
--- a/lib/libpmc/pmc.ucf.3
+++ b/lib/libpmc/pmc.ucf.3
@@ -96,6 +96,7 @@ offset C0H under device number 0 and Function 0.
.Xr pmc.corei7uc 3 ,
.Xr pmc.westmere 3 ,
.Xr pmc.westmereuc 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.westmere.3 b/lib/libpmc/pmc.westmere.3
index b80aefaf3c23..547ee71eff0f 100644
--- a/lib/libpmc/pmc.westmere.3
+++ b/lib/libpmc/pmc.westmere.3
@@ -1381,6 +1381,7 @@ Counts number of SID integer 64 bit shift or move operations.
.Xr pmc.corei7 3 ,
.Xr pmc.corei7uc 3 ,
.Xr pmc.westmereuc 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.westmereuc.3 b/lib/libpmc/pmc.westmereuc.3
index c322778cc18f..517c470fbe7d 100644
--- a/lib/libpmc/pmc.westmereuc.3
+++ b/lib/libpmc/pmc.westmereuc.3
@@ -1066,6 +1066,7 @@ disabled.
.Xr pmc.corei7 3 ,
.Xr pmc.corei7uc 3 ,
.Xr pmc.westmere 3 ,
+.Xr pmc.soft 3 ,
.Xr pmc.tsc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
diff --git a/lib/libpmc/pmc.xscale.3 b/lib/libpmc/pmc.xscale.3
index 25e78e25a72d..521cc9c9d065 100644
--- a/lib/libpmc/pmc.xscale.3
+++ b/lib/libpmc/pmc.xscale.3
@@ -134,6 +134,7 @@ and the underlying hardware events used.
.Xr pmc 3 ,
.Xr pmc_cpuinfo 3 ,
.Xr pmclog 3 ,
+.Xr pmc.soft 3 ,
.Xr hwpmc 4
.Sh HISTORY
The
diff --git a/lib/libpmc/pmclog.c b/lib/libpmc/pmclog.c
index d9ebc674ab65..26ec9ddaab02 100644
--- a/lib/libpmc/pmclog.c
+++ b/lib/libpmc/pmclog.c
@@ -369,6 +369,12 @@ pmclog_get_event(void *cookie, char **data, ssize_t *len,
== NULL)
goto error;
break;
+ case PMCLOG_TYPE_PMCALLOCATEDYN:
+ PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_pmcid);
+ PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_event);
+ PMCLOG_READ32(le,ev->pl_u.pl_ad.pl_flags);
+ PMCLOG_READSTRING(le,ev->pl_u.pl_ad.pl_evname,PMC_NAME_MAX);
+ break;
case PMCLOG_TYPE_PMCATTACH:
PMCLOG_GET_PATHLEN(pathlen,evlen,pmclog_pmcattach);
PMCLOG_READ32(le,ev->pl_u.pl_t.pl_pmcid);
diff --git a/lib/libpmc/pmclog.h b/lib/libpmc/pmclog.h
index b7c9c847628c..2a50945e372e 100644
--- a/lib/libpmc/pmclog.h
+++ b/lib/libpmc/pmclog.h
@@ -88,6 +88,13 @@ struct pmclog_ev_pmcallocate {
pmc_id_t pl_pmcid;
};
+struct pmclog_ev_pmcallocatedyn {
+ uint32_t pl_event;
+ char pl_evname[PMC_NAME_MAX];
+ uint32_t pl_flags;
+ pmc_id_t pl_pmcid;
+};
+
struct pmclog_ev_pmcattach {
pmc_id_t pl_pmcid;
pid_t pl_pid;
@@ -146,6 +153,7 @@ struct pmclog_ev {
struct pmclog_ev_map_out pl_mo;
struct pmclog_ev_pcsample pl_s;
struct pmclog_ev_pmcallocate pl_a;
+ struct pmclog_ev_pmcallocatedyn pl_ad;
struct pmclog_ev_pmcattach pl_t;
struct pmclog_ev_pmcdetach pl_d;
struct pmclog_ev_proccsw pl_c;