Initial Perfmon2 support for Cell. Add Cell to the kernel build files. Create
perfmon_cell.c with the PMC and PMD register layouts, probe_pmu() routine, and
other required data structures.

The field definitions of the pmX_event PMC registers in the pfm_cell_pmc_desc
structure may change. However, since no user-space tools actually use this
code yet, it shouldn't be a problem to change those definitions in the near
future.

Signed-off-by: Kevin Corry <[EMAIL PROTECTED]>
Signed-off-by: Carl Love <[EMAIL PROTECTED]>

Index: linux-2.6.21-arnd2-perfmon1/arch/powerpc/perfmon/Kconfig
===================================================================
--- linux-2.6.21-arnd2-perfmon1.orig/arch/powerpc/perfmon/Kconfig
+++ linux-2.6.21-arnd2-perfmon1/arch/powerpc/perfmon/Kconfig
@@ -29,4 +29,13 @@ config PERFMON_PPC32
        help
        Enables support for the PPC32 hardware performance counters
        If unsure, say M.
+
+config PERFMON_CELL
+       tristate "Support for Cell hardware performance counters"
+       depends on PERFMON && PPC_CELL
+       default n
+       help
+       Enables support for the Cell hardware performance counters.
+       If unsure, say M.
+
 endmenu
Index: linux-2.6.21-arnd2-perfmon1/arch/powerpc/perfmon/Makefile
===================================================================
--- linux-2.6.21-arnd2-perfmon1.orig/arch/powerpc/perfmon/Makefile
+++ linux-2.6.21-arnd2-perfmon1/arch/powerpc/perfmon/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_PERFMON)          += perfmon.o
 obj-$(CONFIG_PERFMON_POWER5)   += perfmon_power5.o
 obj-$(CONFIG_PERFMON_PPC32)    += perfmon_ppc32.o
+obj-$(CONFIG_PERFMON_CELL)     += perfmon_cell.o
Index: linux-2.6.21-arnd2-perfmon1/arch/powerpc/perfmon/perfmon_cell.c
===================================================================
--- /dev/null
+++ linux-2.6.21-arnd2-perfmon1/arch/powerpc/perfmon/perfmon_cell.c
@@ -0,0 +1,135 @@
+/*
+ * This file contains the Cell PMU register description tables
+ * and pmc checker used by perfmon.c.
+ *
+ * Copyright IBM Corporation 2007
+ *
+ * Based on other Perfmon2 PMU modules.
+ * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
+ * Contributed by Stephane Eranian <[EMAIL PROTECTED]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/perfmon.h>
+
+MODULE_AUTHOR("Kevin Corry <[EMAIL PROTECTED]>, "
+             "Carl Love <[EMAIL PROTECTED]>");
+MODULE_DESCRIPTION("Cell PMU description table");
+MODULE_LICENSE("GPL");
+
+/*
+ * Mapping from Perfmon logical control registers to Cell hardware registers.
+ */
+static struct pfm_reg_desc pfm_cell_pmc_desc[] = {
+       /* Per-counter control registers. */
+       PMC_D(PFM_REG_I, "pm0_control",       0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm1_control",       0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm2_control",       0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm3_control",       0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm4_control",       0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm5_control",       0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm6_control",       0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm7_control",       0, 0, 0, 0),
+
+       /* Per-counter RTAS arguments. Each of these registers has three fields.
+        *   bits 63-48: debug-bus word
+        *   bits 47-32: sub-unit
+        *   bits 31-0 : full signal number
+        *   (MSB = 63, LSB = 0)
+        */
+       PMC_D(PFM_REG_I, "pm0_event",         0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm1_event",         0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm2_event",         0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm3_event",         0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm4_event",         0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm5_event",         0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm6_event",         0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm7_event",         0, 0, 0, 0),
+
+       /* Global control registers. Same order as enum pm_reg_name. */
+       PMC_D(PFM_REG_I, "group_control",     0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "debug_bus_control", 0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "trace_address",     0, 0, 0, 0), /* KMC: Not sure if 
user-space needs access to this one. */
+       PMC_D(PFM_REG_I, "ext_trace_timer",   0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm_status",         0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm_control",        0, 0, 0, 0),
+       PMC_D(PFM_REG_I, "pm_interval",       0, 0, 0, 0), /* KMC: Does 
user-space also need read access to this one? */
+       PMC_D(PFM_REG_I, "pm_start_stop",     0, 0, 0, 0),
+};
+#define PFM_PM_NUM_PMCS        ARRAY_SIZE(pfm_cell_pmc_desc)
+
+/*
+ * Mapping from Perfmon logical data counters to Cell hardware counters.
+ */
+static struct pfm_reg_desc pfm_cell_pmd_desc[] = {
+       PMD_D(PFM_REG_C, "pm0", 0),
+       PMD_D(PFM_REG_C, "pm1", 0),
+       PMD_D(PFM_REG_C, "pm2", 0),
+       PMD_D(PFM_REG_C, "pm3", 0),
+       PMD_D(PFM_REG_C, "pm4", 0),
+       PMD_D(PFM_REG_C, "pm5", 0),
+       PMD_D(PFM_REG_C, "pm6", 0),
+       PMD_D(PFM_REG_C, "pm7", 0),
+};
+#define PFM_PM_NUM_PMDS        ARRAY_SIZE(pfm_cell_pmd_desc)
+
+/**
+ * pfm_cell_probe_pmu
+ *
+ * Simply check the processor version register to see if we're currently
+ * on a Cell system.
+ **/
+static int pfm_cell_probe_pmu(void)
+{
+       unsigned long pvr = mfspr(SPRN_PVR);
+
+       if (PVR_VER(pvr) != PV_BE)
+               return -1;
+
+       return 0;
+}
+
+static struct pfm_arch_pmu_info pfm_cell_pmu_info = {
+       .pmu_style = PFM_POWERPC_PMU_CELL,
+};
+
+static struct pfm_pmu_config pfm_cell_pmu_conf = {
+       .pmu_name = "Cell",
+       .version = "0.1",
+       .counter_width = 32,
+       .pmd_desc = pfm_cell_pmd_desc,
+       .pmc_desc = pfm_cell_pmc_desc,
+       .num_pmc_entries = PFM_PM_NUM_PMCS,
+       .num_pmd_entries = PFM_PM_NUM_PMDS,
+       .probe_pmu  = pfm_cell_probe_pmu,
+       .arch_info = &pfm_cell_pmu_info,
+       .flags = PFM_PMU_BUILTIN_FLAG,
+       .owner = THIS_MODULE,
+};
+
+static int __init pfm_cell_pmu_init_module(void)
+{
+       return pfm_pmu_register(&pfm_cell_pmu_conf);
+}
+
+static void __exit pfm_cell_pmu_cleanup_module(void)
+{
+       pfm_pmu_unregister(&pfm_cell_pmu_conf);
+}
+
+module_init(pfm_cell_pmu_init_module);
+module_exit(pfm_cell_pmu_cleanup_module);
Index: linux-2.6.21-arnd2-perfmon1/include/asm-powerpc/perfmon.h
===================================================================
--- linux-2.6.21-arnd2-perfmon1.orig/include/asm-powerpc/perfmon.h
+++ linux-2.6.21-arnd2-perfmon1/include/asm-powerpc/perfmon.h
@@ -39,6 +39,7 @@ enum powerpc_pmu_type {
        PFM_POWERPC_PMU_7400,
        PFM_POWERPC_PMU_7450,
        PFM_POWERPC_PMU_POWER5,
+       PFM_POWERPC_PMU_CELL,
 };
 
 struct pfm_arch_pmu_info {
_______________________________________________
perfmon mailing list
[email protected]
http://www.hpl.hp.com/hosted/linux/mail-archives/perfmon/

Reply via email to