diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-06 17:49:42 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-06 17:49:42 (GMT) |
commit | 39eda2aba6be642b71f2e0ad623dcb09fd9d79cf (patch) | |
tree | cd0c8f547847641af73e38aab2478f3119dee490 /arch/powerpc/perf | |
parent | 2e515bf096c245ba87f20ab4b4ea20f911afaeda (diff) | |
parent | 9f24b0c9ef9b6b1292579c9e2cd7ff07ddc372b7 (diff) | |
download | linux-39eda2aba6be642b71f2e0ad623dcb09fd9d79cf.tar.xz |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc updates from Ben Herrenschmidt:
"Here's the powerpc batch for this merge window. Some of the
highlights are:
- A bunch of endian fixes ! We don't have full LE support yet in that
release but this contains a lot of fixes all over arch/powerpc to
use the proper accessors, call the firmware with the right endian
mode, etc...
- A few updates to our "powernv" platform (non-virtualized, the one
to run KVM on), among other, support for bridging the P8 LPC bus
for UARTs, support and some EEH fixes.
- Some mpc51xx clock API cleanups in preparation for a clock API
overhaul
- A pile of cleanups of our old math emulation code, including better
support for using it to emulate optional FP instructions on
embedded chips that otherwise have a HW FPU.
- Some infrastructure in selftest, for powerpc now, but could be
generalized, initially used by some tests for our perf instruction
counting code.
- A pile of fixes for hotplug on pseries (that was seriously
bitrotting)
- The usual slew of freescale embedded updates, new boards, 64-bit
hiberation support, e6500 core PMU support, etc..."
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (146 commits)
powerpc: Correct FSCR bit definitions
powerpc/xmon: Fix printing of set of CPUs in xmon
powerpc/pseries: Move lparcfg.c to platforms/pseries
powerpc/powernv: Return secondary CPUs to firmware on kexec
powerpc/btext: Fix CONFIG_PPC_EARLY_DEBUG_BOOTX on ppc32
powerpc: Cleanup handling of the DSCR bit in the FSCR register
powerpc/pseries: Child nodes are not detached by dlpar_detach_node
powerpc/pseries: Add mising of_node_put in delete_dt_node
powerpc/pseries: Make dlpar_configure_connector parent node aware
powerpc/pseries: Do all node initialization in dlpar_parse_cc_node
powerpc/pseries: Fix parsing of initial node path in update_dt_node
powerpc/pseries: Pack update_props_workarea to map correctly to rtas buffer header
powerpc/pseries: Fix over writing of rtas return code in update_dt_node
powerpc/pseries: Fix creation of loop in device node property list
powerpc: Skip emulating & leave interrupts off for kernel program checks
powerpc: Add more exception trampolines for hypervisor exceptions
powerpc: Fix location and rename exception trampolines
powerpc: Add more trap names to xmon
powerpc/pseries: Add a warning in the case of cross-cpu VPA registration
powerpc: Update the 00-Index in Documentation/powerpc
...
Diffstat (limited to 'arch/powerpc/perf')
-rw-r--r-- | arch/powerpc/perf/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/perf/core-book3s.c | 2 | ||||
-rw-r--r-- | arch/powerpc/perf/core-fsl-emb.c | 30 | ||||
-rw-r--r-- | arch/powerpc/perf/e6500-pmu.c | 121 |
4 files changed, 153 insertions, 2 deletions
diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile index 510fae1..60d71ee 100644 --- a/arch/powerpc/perf/Makefile +++ b/arch/powerpc/perf/Makefile @@ -9,7 +9,7 @@ obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \ obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o -obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o +obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o e6500-pmu.o obj-$(CONFIG_PPC64) += $(obj64-y) obj-$(CONFIG_PPC32) += $(obj32-y) diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index eeae308..29b89e8 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -24,7 +24,7 @@ #define BHRB_MAX_ENTRIES 32 #define BHRB_TARGET 0x0000000000000002 #define BHRB_PREDICTION 0x0000000000000001 -#define BHRB_EA 0xFFFFFFFFFFFFFFFC +#define BHRB_EA 0xFFFFFFFFFFFFFFFCUL struct cpu_hw_events { int n_events; diff --git a/arch/powerpc/perf/core-fsl-emb.c b/arch/powerpc/perf/core-fsl-emb.c index 106c533..d35ae52 100644 --- a/arch/powerpc/perf/core-fsl-emb.c +++ b/arch/powerpc/perf/core-fsl-emb.c @@ -70,6 +70,12 @@ static unsigned long read_pmc(int idx) case 3: val = mfpmr(PMRN_PMC3); break; + case 4: + val = mfpmr(PMRN_PMC4); + break; + case 5: + val = mfpmr(PMRN_PMC5); + break; default: printk(KERN_ERR "oops trying to read PMC%d\n", idx); val = 0; @@ -95,6 +101,12 @@ static void write_pmc(int idx, unsigned long val) case 3: mtpmr(PMRN_PMC3, val); break; + case 4: + mtpmr(PMRN_PMC4, val); + break; + case 5: + mtpmr(PMRN_PMC5, val); + break; default: printk(KERN_ERR "oops trying to write PMC%d\n", idx); } @@ -120,6 +132,12 @@ static void write_pmlca(int idx, unsigned long val) case 3: mtpmr(PMRN_PMLCA3, val); break; + case 4: + mtpmr(PMRN_PMLCA4, val); + break; + case 5: + mtpmr(PMRN_PMLCA5, val); + break; default: printk(KERN_ERR "oops trying to write PMLCA%d\n", idx); } @@ -145,6 +163,12 @@ static void write_pmlcb(int idx, unsigned long val) case 3: mtpmr(PMRN_PMLCB3, val); break; + case 4: + mtpmr(PMRN_PMLCB4, val); + break; + case 5: + mtpmr(PMRN_PMLCB5, val); + break; default: printk(KERN_ERR "oops trying to write PMLCB%d\n", idx); } @@ -462,6 +486,12 @@ static int fsl_emb_pmu_event_init(struct perf_event *event) int num_restricted; int i; + if (ppmu->n_counter > MAX_HWEVENTS) { + WARN(1, "No. of perf counters (%d) is higher than max array size(%d)\n", + ppmu->n_counter, MAX_HWEVENTS); + ppmu->n_counter = MAX_HWEVENTS; + } + switch (event->attr.type) { case PERF_TYPE_HARDWARE: ev = event->attr.config; diff --git a/arch/powerpc/perf/e6500-pmu.c b/arch/powerpc/perf/e6500-pmu.c new file mode 100644 index 0000000..3d877aa --- /dev/null +++ b/arch/powerpc/perf/e6500-pmu.c @@ -0,0 +1,121 @@ +/* + * Performance counter support for e6500 family processors. + * + * Author: Priyanka Jain, Priyanka.Jain@freescale.com + * Based on e500-pmu.c + * Copyright 2013 Freescale Semiconductor, Inc. + * Copyright 2008-2009 Paul Mackerras, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/string.h> +#include <linux/perf_event.h> +#include <asm/reg.h> +#include <asm/cputable.h> + +/* + * Map of generic hardware event types to hardware events + * Zero if unsupported + */ +static int e6500_generic_events[] = { + [PERF_COUNT_HW_CPU_CYCLES] = 1, + [PERF_COUNT_HW_INSTRUCTIONS] = 2, + [PERF_COUNT_HW_CACHE_MISSES] = 221, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 12, + [PERF_COUNT_HW_BRANCH_MISSES] = 15, +}; + +#define C(x) PERF_COUNT_HW_CACHE_##x + +/* + * Table of generalized cache-related events. + * 0 means not supported, -1 means nonsensical, other values + * are event codes. + */ +static int e6500_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { + [C(L1D)] = { + /*RESULT_ACCESS RESULT_MISS */ + [C(OP_READ)] = { 27, 222 }, + [C(OP_WRITE)] = { 28, 223 }, + [C(OP_PREFETCH)] = { 29, 0 }, + }, + [C(L1I)] = { + /*RESULT_ACCESS RESULT_MISS */ + [C(OP_READ)] = { 2, 254 }, + [C(OP_WRITE)] = { -1, -1 }, + [C(OP_PREFETCH)] = { 37, 0 }, + }, + /* + * Assuming LL means L2, it's not a good match for this model. + * It does not have separate read/write events (but it does have + * separate instruction/data events). + */ + [C(LL)] = { + /*RESULT_ACCESS RESULT_MISS */ + [C(OP_READ)] = { 0, 0 }, + [C(OP_WRITE)] = { 0, 0 }, + [C(OP_PREFETCH)] = { 0, 0 }, + }, + /* + * There are data/instruction MMU misses, but that's a miss on + * the chip's internal level-one TLB which is probably not + * what the user wants. Instead, unified level-two TLB misses + * are reported here. + */ + [C(DTLB)] = { + /*RESULT_ACCESS RESULT_MISS */ + [C(OP_READ)] = { 26, 66 }, + [C(OP_WRITE)] = { -1, -1 }, + [C(OP_PREFETCH)] = { -1, -1 }, + }, + [C(BPU)] = { + /*RESULT_ACCESS RESULT_MISS */ + [C(OP_READ)] = { 12, 15 }, + [C(OP_WRITE)] = { -1, -1 }, + [C(OP_PREFETCH)] = { -1, -1 }, + }, + [C(NODE)] = { + /* RESULT_ACCESS RESULT_MISS */ + [C(OP_READ)] = { -1, -1 }, + [C(OP_WRITE)] = { -1, -1 }, + [C(OP_PREFETCH)] = { -1, -1 }, + }, +}; + +static int num_events = 512; + +/* Upper half of event id is PMLCb, for threshold events */ +static u64 e6500_xlate_event(u64 event_id) +{ + u32 event_low = (u32)event_id; + if (event_low >= num_events || + (event_id & (FSL_EMB_EVENT_THRESHMUL | FSL_EMB_EVENT_THRESH))) + return 0; + + return FSL_EMB_EVENT_VALID; +} + +static struct fsl_emb_pmu e6500_pmu = { + .name = "e6500 family", + .n_counter = 6, + .n_restricted = 0, + .xlate_event = e6500_xlate_event, + .n_generic = ARRAY_SIZE(e6500_generic_events), + .generic_events = e6500_generic_events, + .cache_events = &e6500_cache_events, +}; + +static int init_e6500_pmu(void) +{ + if (!cur_cpu_spec->oprofile_cpu_type || + strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/e6500")) + return -ENODEV; + + return register_fsl_emb_pmu(&e6500_pmu); +} + +early_initcall(init_e6500_pmu); |