|
@@ -30,27 +30,39 @@
|
|
#include "kernel.h"
|
|
#include "kernel.h"
|
|
#include "kstack.h"
|
|
#include "kstack.h"
|
|
|
|
|
|
-/* Sparc64 chips have two performance counters, 32-bits each, with
|
|
|
|
- * overflow interrupts generated on transition from 0xffffffff to 0.
|
|
|
|
- * The counters are accessed in one go using a 64-bit register.
|
|
|
|
|
|
+/* Two classes of sparc64 chips currently exist. All of which have
|
|
|
|
+ * 32-bit counters which can generate overflow interrupts on the
|
|
|
|
+ * transition from 0xffffffff to 0.
|
|
*
|
|
*
|
|
- * Both counters are controlled using a single control register. The
|
|
|
|
- * only way to stop all sampling is to clear all of the context (user,
|
|
|
|
- * supervisor, hypervisor) sampling enable bits. But these bits apply
|
|
|
|
- * to both counters, thus the two counters can't be enabled/disabled
|
|
|
|
- * individually.
|
|
|
|
|
|
+ * All chips upto and including SPARC-T3 have two performance
|
|
|
|
+ * counters. The two 32-bit counters are accessed in one go using a
|
|
|
|
+ * single 64-bit register.
|
|
*
|
|
*
|
|
- * The control register has two event fields, one for each of the two
|
|
|
|
- * counters. It's thus nearly impossible to have one counter going
|
|
|
|
- * while keeping the other one stopped. Therefore it is possible to
|
|
|
|
- * get overflow interrupts for counters not currently "in use" and
|
|
|
|
- * that condition must be checked in the overflow interrupt handler.
|
|
|
|
|
|
+ * On these older chips both counters are controlled using a single
|
|
|
|
+ * control register. The only way to stop all sampling is to clear
|
|
|
|
+ * all of the context (user, supervisor, hypervisor) sampling enable
|
|
|
|
+ * bits. But these bits apply to both counters, thus the two counters
|
|
|
|
+ * can't be enabled/disabled individually.
|
|
|
|
+ *
|
|
|
|
+ * Furthermore, the control register on these older chips have two
|
|
|
|
+ * event fields, one for each of the two counters. It's thus nearly
|
|
|
|
+ * impossible to have one counter going while keeping the other one
|
|
|
|
+ * stopped. Therefore it is possible to get overflow interrupts for
|
|
|
|
+ * counters not currently "in use" and that condition must be checked
|
|
|
|
+ * in the overflow interrupt handler.
|
|
*
|
|
*
|
|
* So we use a hack, in that we program inactive counters with the
|
|
* So we use a hack, in that we program inactive counters with the
|
|
* "sw_count0" and "sw_count1" events. These count how many times
|
|
* "sw_count0" and "sw_count1" events. These count how many times
|
|
* the instruction "sethi %hi(0xfc000), %g0" is executed. It's an
|
|
* the instruction "sethi %hi(0xfc000), %g0" is executed. It's an
|
|
* unusual way to encode a NOP and therefore will not trigger in
|
|
* unusual way to encode a NOP and therefore will not trigger in
|
|
* normal code.
|
|
* normal code.
|
|
|
|
+ *
|
|
|
|
+ * Starting with SPARC-T4 we have one control register per counter.
|
|
|
|
+ * And the counters are stored in individual registers. The registers
|
|
|
|
+ * for the counters are 64-bit but only a 32-bit counter is
|
|
|
|
+ * implemented. The event selections on SPARC-T4 lack any
|
|
|
|
+ * restrictions, therefore we can elide all of the complicated
|
|
|
|
+ * conflict resolution code we have for SPARC-T3 and earlier chips.
|
|
*/
|
|
*/
|
|
|
|
|
|
#define MAX_HWEVENTS 4
|
|
#define MAX_HWEVENTS 4
|
|
@@ -103,6 +115,8 @@ DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };
|
|
/* An event map describes the characteristics of a performance
|
|
/* An event map describes the characteristics of a performance
|
|
* counter event. In particular it gives the encoding as well as
|
|
* counter event. In particular it gives the encoding as well as
|
|
* a mask telling which counters the event can be measured on.
|
|
* a mask telling which counters the event can be measured on.
|
|
|
|
+ *
|
|
|
|
+ * The mask is unused on SPARC-T4 and later.
|
|
*/
|
|
*/
|
|
struct perf_event_map {
|
|
struct perf_event_map {
|
|
u16 encoding;
|
|
u16 encoding;
|