It is a main body of pfm_cell_reset_signals() and pfm_cell_activate_signals().
(in the new file: perfmon_cell_signals.c) Moreover, this patch includes
pfm_cell_pmc_check() too.

-- Takaki Azuma

Signed-off-by: Takaki Azuma <[EMAIL PROTECTED]>
Signed-off-by: Takayuki Uchikawa <[EMAIL PROTECTED]>

Index: linux-2.6/arch/powerpc/perfmon/perfmon_cell_signals.c
===================================================================
--- linux-2.6.git/arch/powerpc/perfmon/perfmon_cell_signals.c
+++ linux-2.6/arch/powerpc/perfmon/perfmon_cell_signals.c
@@ -0,0 +1,270 @@
+/*
+ * This file contains the Cell performance monitor signal setting
+ * used by perfmon_cell.c.
+ *
+ * (C) Copyright 2007 TOSHIBA CORPORATION
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110, USA
+ */
+#ifndef __PERFMON_CELL_SIGNALS_C__
+#define __PERFMON_CELL_SIGNALS_C__
+
+#include <linux/module.h>
+#include <linux/perfmon.h>
+#include <asm/cell-pmu.h>
+#include <asm/io.h>
+#include <asm/spu.h>
+#include <asm/machdep.h>
+#include "../platforms/cell/cbe_regs.h"
+
+#define        HID1_RESET_MASK                 (~0x00000001fffffffful)
+#define        PPU_IU1_WORD0_HID1_EN_MASK      (~0x00000001f0c0802cul)
+#define        PPU_IU1_WORD0_HID1_EN_WORD      ( 0x00000001f0400000ul)
+#define        PPU_IU1_WORD1_HID1_EN_MASK      (~0x000000010fc08023ul)
+#define        PPU_IU1_WORD1_HID1_EN_WORD      ( 0x000000010f400001ul)
+#define        PPU_XU_WORD0_HID1_EN_MASK       (~0x00000001f038402cul)
+#define        PPU_XU_WORD0_HID1_EN_WORD       ( 0x00000001f0080008ul)
+#define        PPU_XU_WORD1_HID1_EN_MASK       (~0x000000010f074023ul)
+#define        PPU_XU_WORD1_HID1_EN_WORD       ( 0x000000010f030008ul)
+
+struct cell_rtas_arg {
+       u16 cpu;
+       u16 sub_unit;
+       s16 signal_group;
+       u8 bus_word;
+       u8 bit;
+};
+
+#define        GET_BUS_WORD(x)                 ((u8)(((x) >> 48) & 0x0ff))
+#define        GET_SIGNAL_GROUP_NUMBER(x)      ((s16)(((x) & 0x0ffff) / 100))
+
+enum {
+       BUS_WORD_0 = 1,
+       BUS_WORD_1 = 2,
+       BUS_WORD_2 = 4,
+       BUS_WORD_3 = 8,
+};
+
+enum {
+       SIG_GROUP_NONE = 0,
+
+       /* 2. PowerPC Processor Unit (PPU) Signal Selection */
+       SIG_GROUP_PPU_IU1 = 21,
+       SIG_GROUP_PPU_XU = 23,
+};
+
+#define        rmw_spr(spr_id, a_mask, o_mask) \
+       do { \
+               u64 value = mfspr(spr_id); \
+               value &= (u64)(a_mask); \
+               value |= (u64)(o_mask); \
+               mtspr(spr_id, value); \
+       } while (0)
+
+#define rmwb_mmio_reg64(mem, bitN, bit) \
+       rmw_mmio_reg64(mem, ~((bit) << (63 - (bitN))), ((bit) << (63 - (bitN))))
+
+#define        rmw_mmio_reg64(mem, a_mask, o_mask) \
+       do { \
+               u64 value = in_be64(&mem); \
+               value &= ((u64)(a_mask)); \
+               value |= ((u64)(o_mask)); \
+               out_be64(&mem, value); \
+       } while (0)
+
+#define        passthrough_enable(cpu)         passthrough(cpu, 1ul)
+#define        passthrough_disable(cpu)        passthrough(cpu, 0ul)
+
+static inline int passthrough(u32 cpu, u64 bit)
+{
+       struct cbe_ppe_priv_regs __iomem * ppe_priv_regs;
+       struct cbe_pmd_regs __iomem * pmd_regs;
+       struct cbe_mic_tm_regs __iomem * mic_tm_regs;
+
+       ppe_priv_regs = cbe_get_cpu_ppe_priv_regs(cpu);
+       pmd_regs = cbe_get_cpu_pmd_regs(cpu);
+       mic_tm_regs = cbe_get_cpu_mic_tm_regs(cpu);
+
+       if (!ppe_priv_regs || !pmd_regs || !mic_tm_regs) {
+               PFM_DBG("Not found cbe_regs_map -> %ph,%ph,%ph",
+                       ppe_priv_regs, pmd_regs, mic_tm_regs);
+               return -EINVAL;
+       }
+
+       rmwb_mmio_reg64(ppe_priv_regs->L2_debug1, 61, bit);
+       rmwb_mmio_reg64(ppe_priv_regs->ciu_dr1, 5, bit);
+       rmwb_mmio_reg64(pmd_regs->on_ramp_trace, 39, bit);
+       rmwb_mmio_reg64(mic_tm_regs->MBL_debug, 20, bit);
+
+       return 0;
+}
+
+static inline int reset_signal_registers(u32 cpu)
+{
+       rmw_spr(SPRN_HID1, HID1_RESET_MASK, 0ul);
+
+       return 0;
+}
+
+/*
+ * pfm_cell_reset_signals
+ */
+int pfm_cell_reset_signals(u32 cpu)
+{
+       passthrough_disable(cpu);
+       reset_signal_registers(cpu);
+       return 0;
+}
+
+static int ppu_selection(struct cell_rtas_arg * signal)
+{
+       u64 hid1_enable_word = 0ul;
+       u64 hid1_enable_mask = 0ul;
+
+       BUG_ON(!signal);
+
+       switch (signal->signal_group) {
+       default:
+               PFM_DBG("Not implemented signal_group(%d), now",
+                       signal->signal_group);
+               return -EINVAL;
+
+       case SIG_GROUP_PPU_IU1: /* 2.1 PPU Instruction Unit - Group 1 */
+               switch (signal->bus_word) {
+               default:
+                       PFM_DBG("Invalid bus_word(%xh)", signal->bus_word);
+                       return -EINVAL;
+               case BUS_WORD_0:
+                       hid1_enable_mask = PPU_IU1_WORD0_HID1_EN_MASK;
+                       hid1_enable_word = PPU_IU1_WORD0_HID1_EN_WORD;
+                       break;
+               case BUS_WORD_1:
+                       hid1_enable_mask = PPU_IU1_WORD1_HID1_EN_MASK;
+                       hid1_enable_word = PPU_IU1_WORD1_HID1_EN_WORD;
+                       break;
+               }
+               break;
+
+       case SIG_GROUP_PPU_XU:  /* 2.3 PPU Execution Unit */
+               switch (signal->bus_word) {
+               default:
+                       PFM_DBG("Invalid bus_word(%xh)", signal->bus_word);
+                       return -EINVAL;
+               case BUS_WORD_0:
+                       hid1_enable_mask = PPU_XU_WORD0_HID1_EN_MASK;
+                       hid1_enable_word = PPU_XU_WORD0_HID1_EN_WORD;
+                       break;
+               case BUS_WORD_1:
+                       hid1_enable_mask = PPU_XU_WORD1_HID1_EN_MASK;
+                       hid1_enable_word = PPU_XU_WORD1_HID1_EN_WORD;
+                       break;
+               }
+               break;
+       }
+
+       rmw_spr(SPRN_HID1, hid1_enable_mask, hid1_enable_word);
+
+       return 0;
+}
+
+/*
+ * pfm_cell_activate_signals
+ */
+int pfm_cell_activate_signals(struct cell_rtas_arg * signals, int num_signals)
+{
+       int err = 0;
+       int i;
+
+       BUG_ON((0 < num_signals) && !signals);
+
+       for (i = 0; i < num_signals; i++) {
+
+               switch (signals[i].signal_group) {
+               default:
+                       PFM_DBG("Not implemented signal_group(%d), now",
+                               signals[i].signal_group);
+                       return -EINVAL;
+
+               /* 2. PowerPC Processor Unit (PPU) Signal Selection */
+               case SIG_GROUP_PPU_IU1:
+               case SIG_GROUP_PPU_XU:
+                       err = ppu_selection(&signals[i]);
+                       if (err != 0)
+                               return err;
+                       break;
+               }
+
+               passthrough_enable(signals[i].cpu);
+
+               break;
+       }
+
+       return err;
+}
+
+/*
+ *  pfm_cell_pmc_check
+ */
+int pfm_cell_pmc_check(struct pfm_context * ctx,
+                      struct pfm_event_set * set,
+                      struct pfarg_pmc * req)
+{
+       u64 cnum;
+       u64 reg_num;
+       s16 signal_group;
+       u8 bus_word;
+
+       BUG_ON(!ctx || !set || !req);
+
+       reg_num = req->reg_num;
+       bus_word = GET_BUS_WORD(req->reg_value);
+       signal_group = GET_SIGNAL_GROUP_NUMBER(req->reg_value);
+
+       BUG_ON((reg_num < NR_CTRS) || ((NR_CTRS * 2) <= reg_num));
+
+       switch (signal_group) {
+       default:
+               PFM_DBG("Not implemented signal_group(%d), now", signal_group);
+               return -EINVAL;
+
+       case SIG_GROUP_PPU_IU1:
+       case SIG_GROUP_PPU_XU:
+               if ((bus_word != 0) && (bus_word != 1)) {
+                       PFM_DBG("invalid bus word. (%x,%d)",
+                               bus_word, signal_group);
+                       return -EINVAL;
+               }
+               break;
+       }
+
+       for (cnum = NR_CTRS; cnum < (NR_CTRS * 2); cnum++) {
+               if (!test_bit(cnum, cast_ulp(set->used_pmcs)))
+                       continue;
+               if (bus_word != GET_BUS_WORD(set->pmcs[cnum]))
+                       continue;
+               if (signal_group == GET_SIGNAL_GROUP_NUMBER(set->pmcs[cnum]))
+                       continue;
+
+               PFM_DBG("impossible combination. (%lu,%u,%d) (%lu,%u,%d)",
+                        reg_num, bus_word, signal_group, cnum,
+                        GET_BUS_WORD(set->pmcs[cnum]),
+                        GET_SIGNAL_GROUP_NUMBER(set->pmcs[cnum]));
+               return  -EBUSY;
+       }
+
+       return 0;
+}
+
+#endif /* __PERFMON_CELL_SIGNALS_C__ */
Index: linux-2.6/arch/powerpc/perfmon/perfmon_cell_signals.h
===================================================================
--- linux-2.6.git/arch/powerpc/perfmon/perfmon_cell_signals.h
+++ linux-2.6/arch/powerpc/perfmon/perfmon_cell_signals.h
@@ -0,0 +1,31 @@
+/*
+ * This file contains the Cell performance monitor signal setting
+ * used by perfmon_cell.h.
+ *
+ * (C) Copyright 2007 TOSHIBA CORPORATION
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110, USA
+ */
+#ifndef __PERFMON_CELL_SIGNALS_H__
+#define __PERFMON_CELL_SIGNALS_H__
+
+extern int pfm_cell_reset_signals(u32 cpu);
+extern int pfm_cell_activate_signals(struct cell_rtas_arg * signals,
+                                    int num_signals);
+extern int pfm_cell_pmc_check(struct pfm_context * ctx,
+                             struct pfm_event_set * set,
+                             struct pfarg_pmc * req);
+
+#endif  /* __PERFMON_CELL_SIGNALS_H__ */

_______________________________________________
perfmon mailing list
[email protected]
http://www.hpl.hp.com/hosted/linux/mail-archives/perfmon/

Reply via email to