Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 979f8671 authored by Michael Cree's avatar Michael Cree Committed by Linus Torvalds
Browse files

alpha: implement HW performance events on the EV67 and later CPUs



This implements hardware performance events for the EV67 and later CPUs
within the Linux performance events subsystem.  Only using the performance
monitoring unit in HP/Compaq's so called "Aggregrate mode" is supported.

The code has been implemented in a manner that makes extension to other
older Alpha CPUs relatively straightforward should some mug wish to
indulge themselves.

Signed-off-by: default avatarMichael Cree <mcree@orcon.net.nz>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Jay Estabrook <jay.estabrook@hp.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 92484f10
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -2,8 +2,14 @@
#define __ASM_ALPHA_PERF_EVENT_H

/* Alpha only supports software events through this interface. */
static inline void set_perf_event_pending(void) { }
extern void set_perf_event_pending(void);

#define PERF_EVENT_INDEX_OFFSET 0

#ifdef CONFIG_PERF_EVENTS
extern void init_hw_perf_events(void);
#else
static inline void init_hw_perf_events(void)    { }
#endif

#endif /* __ASM_ALPHA_PERF_EVENT_H */
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_PCI)	+= pci.o pci_iommu.o pci-sysfs.o
obj-$(CONFIG_SRM_ENV)	+= srm_env.o
obj-$(CONFIG_MODULES)	+= module.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o

ifdef CONFIG_ALPHA_GENERIC

+3 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@

#include <asm/machvec.h>
#include <asm/dma.h>
#include <asm/perf_event.h>

#include "proto.h"
#include "irq_impl.h"
@@ -111,6 +112,8 @@ init_IRQ(void)
	wrent(entInt, 0);

	alpha_mv.init_irq();

	init_hw_perf_events();
}

/*
+842 −0

File added.

Preview size limit exceeded, changes collapsed.

+26 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include <linux/init.h>
#include <linux/bcd.h>
#include <linux/profile.h>
#include <linux/perf_event.h>

#include <asm/uaccess.h>
#include <asm/io.h>
@@ -82,6 +83,26 @@ static struct {

unsigned long est_cycle_freq;

#ifdef CONFIG_PERF_EVENTS

DEFINE_PER_CPU(u8, perf_event_pending);

#define set_perf_event_pending_flag()  __get_cpu_var(perf_event_pending) = 1
#define test_perf_event_pending()      __get_cpu_var(perf_event_pending)
#define clear_perf_event_pending()     __get_cpu_var(perf_event_pending) = 0

void set_perf_event_pending(void)
{
	set_perf_event_pending_flag();
}

#else  /* CONFIG_PERF_EVENTS */

#define test_perf_event_pending()      0
#define clear_perf_event_pending()

#endif /* CONFIG_PERF_EVENTS */


static inline __u32 rpcc(void)
{
@@ -175,6 +196,11 @@ irqreturn_t timer_interrupt(int irq, void *dev)
		update_process_times(user_mode(get_irq_regs()));
#endif

	if (test_perf_event_pending()) {
		clear_perf_event_pending();
		perf_event_do_pending();
	}

	return IRQ_HANDLED;
}