[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [POWERPC][XEN] Enable in-guest performance monitoring.



# HG changeset patch
# User Hollis Blanchard <hollisb@xxxxxxxxxx>
# Date 1184365695 18000
# Node ID 3867217d31555c6b8340eb48ce52838853fb13ae
# Parent  a69843c46641c35423e63c14a343c1a0651e49b4
[POWERPC][XEN] Enable in-guest performance monitoring.
- Lazily save and restore the performance monitor counters when switching
  domains.
- Control with the H_PERFMON PAPR hypercall.
- Ignore guest perfmon exceptions that land in Xen.
Signed-off-by: Christian Ehrhardt <ehrhardt@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx>
---
 xen/arch/powerpc/exceptions.h           |    3 
 xen/arch/powerpc/of_handler/papr.S      |    2 
 xen/arch/powerpc/papr/Makefile          |    1 
 xen/arch/powerpc/papr/h_perfmon.c       |  158 ++++++++++++++++++++++++++++++++
 xen/arch/powerpc/powerpc64/domain.c     |   46 +++++++++
 xen/arch/powerpc/powerpc64/exceptions.S |   25 ++++-
 xen/include/asm-powerpc/domain.h        |   21 ++++
 xen/include/asm-powerpc/papr.h          |    1 
 xen/include/asm-powerpc/processor.h     |  138 +++++++++++++++++++++++++++
 xen/include/asm-powerpc/reg_defs.h      |   27 +++++
 xen/include/asm-powerpc/xenoprof.h      |   76 +++++++++++++++
 11 files changed, 490 insertions(+), 8 deletions(-)

diff -r a69843c46641 -r 3867217d3155 xen/arch/powerpc/exceptions.h
--- a/xen/arch/powerpc/exceptions.h     Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/arch/powerpc/exceptions.h     Fri Jul 13 17:28:15 2007 -0500
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005
+ * Copyright IBM Corp. 2005, 2007
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
  */
@@ -39,6 +39,7 @@ extern  multiboot_info_t *boot_of_init(u
 
 extern void do_timer(struct cpu_user_regs *regs);
 extern void do_dec(struct cpu_user_regs *regs);
+extern void do_perfmon(struct cpu_user_regs *regs);
 extern void program_exception(
     struct cpu_user_regs *regs, unsigned long cookie);
 
diff -r a69843c46641 -r 3867217d3155 xen/arch/powerpc/of_handler/papr.S
--- a/xen/arch/powerpc/of_handler/papr.S        Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/arch/powerpc/of_handler/papr.S        Fri Jul 13 17:28:15 2007 -0500
@@ -67,7 +67,7 @@ PAPR(5, 1,papr_pci_config_read, H_PCI_CO
 PAPR(5, 1,papr_pci_config_read, H_PCI_CONFIG_READ)
 PAPR(5, 0,papr_pci_config_write, H_PCI_CONFIG_WRITE)
 
-       PAPR(5, 1,papr_grant_logical, H_GRANT_LOGICAL)
+PAPR(5, 1,papr_grant_logical, H_GRANT_LOGICAL)
 PAPR(1, 1,papr_accept_logical, H_ACCEPT_LOGICAL)
 PAPR(0, 2,papr_rescind_logical, H_RESCIND_LOGICAL)
 PAPR(3, 0,papr_register_vterm, H_REGISTER_VTERM)
diff -r a69843c46641 -r 3867217d3155 xen/arch/powerpc/papr/Makefile
--- a/xen/arch/powerpc/papr/Makefile    Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/arch/powerpc/papr/Makefile    Fri Jul 13 17:28:15 2007 -0500
@@ -8,3 +8,4 @@ obj-y += vtce.o
 obj-y += vtce.o
 obj-$(papr_vterm) += vterm.o
 obj-y += xlate.o
+obj-y += h_perfmon.o
diff -r a69843c46641 -r 3867217d3155 xen/arch/powerpc/papr/h_perfmon.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/powerpc/papr/h_perfmon.c Fri Jul 13 17:28:15 2007 -0500
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ *
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright IBM Corp. 2007
+ *
+ * Authors: Christian Ehrhardt <ehrhardt@xxxxxxxxxxxxxxxxxx>
+ */
+#undef DEBUG
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/sched.h>
+#include <xen/init.h>
+#include <xen/domain.h>
+#include <public/xen.h>
+#include <asm/current.h>
+#include <asm/msr.h>
+#include <asm/papr.h>
+#include <asm/hcalls.h>
+#include <asm/xenoprof.h>
+
+#define H_PERFMON_ENABLE (1UL << 63)
+#define H_PERFMON_THRESHOLDGRANULARITY (1UL << 62)
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/* FIXME workaround - these are just the default values, need the values set to
+ * linux via sysfs up-to-date. */
+int pmc_reset_val[NUM_PMCS] = { (0x8000000-0x0),
+                                (0x8000000-0x100000),
+                                (0x8000000-0x0),
+                                (0x8000000-0x0),
+                                (0x8000000-0x0),
+                                (0x8000000-0x0),
+                                (0x8000000-0x0),
+                                (0x8000000-0x0)};
+int perf_count_active_vcpu;
+perf_sprs_t perf_clear_sprs;
+static DEFINE_SPINLOCK(perf_pmu_lock);
+
+static inline int has_pmu(void) { return 1; }
+
+void do_perfmon(struct cpu_user_regs *regs)
+{
+    ulong mmcra = mfmmcra();
+    ulong mmcr0 = mfmmcr0();
+    int pmc,i;
+    
+    if ((mmcra & MMCRA_SAMPHV) && !(mmcra & MMCRA_SAMPPR)) {
+        /* TODO Hypervisor sample - support to sample xen, 
+         * pass the sample to the primary sampling domain via an event channel.
+         */
+        printk("do_perfmon - called with sample of xen space\n");
+        print_perf_status();
+        BUG();
+    } 
+
+    /* Dom sample postponed into xen space
+     * Currently just ignored (decreases accuracy) 
+     * TODO pass the Dom samples to the appropriate domain via an event channel
+     * TODO get access to the real pmc_reset_val currently used by the domain
+     * to reset counter safe and valid
+     */
+
+    for (i = 0; i < NUM_PMCS; ++i) {
+        pmc = ctr_read(i);
+        if (pmc < 0) {
+            DBG("postponed perfmon exception - PMC%d < 0 - reset to default "
+                "'0x%0x'\n", i, pmc_reset_val[i]);
+            ctr_write(i,pmc_reset_val[i]);
+        }
+    }
+
+    mmcr0 |= MMCR0_PMAE;
+    mmcr0 &= ~MMCR0_FC;
+    mtmmcr0(mmcr0);
+}
+
+static void h_perfmon(struct cpu_user_regs *regs)
+{
+    ulong mode_set   = regs->gprs[4];
+    ulong mode_reset = regs->gprs[5];
+    struct vcpu *v = get_current();
+    struct domain *d = v->domain;
+
+    if (!has_pmu()) {
+        regs->gprs[3] = H_Function;
+        return;
+    }
+
+    /* only bits 0&1 are supported by H_PERFMON */
+    if (((mode_set | mode_reset) & ~(H_PERFMON_ENABLE |
+            H_PERFMON_THRESHOLDGRANULARITY)) != 0) {
+        regs->gprs[3] = H_Parameter;
+        return;
+    }
+    /* enable or disable it, not both */
+    if ((mode_set & mode_reset) != 0) {
+        regs->gprs[3] = H_Resource;
+        return;
+    }
+
+    spin_lock(&perf_pmu_lock);
+    if (mode_set & H_PERFMON_ENABLE) {
+        if (v->arch.pmu_enabled) {
+            DBG("H_PERFMON call on already enabled PMU for domain '%d' on "
+                "vcpu '%d'\n", d->domain_id, v->vcpu_id);
+            goto success;
+        }
+
+        if (!perf_count_active_vcpu) {
+           save_pmc_sprs(&perf_clear_sprs);
+#ifdef DEBUG
+           DBG("H_PERFMON Saved initial clear performance special purpose "
+               "registers\n");
+           print_perf_status();
+#endif
+        }
+        v->arch.pmu_enabled = 1;
+        perf_count_active_vcpu++;
+        printk("H_PERFMON call enabled PMU for domain '%d' on vcpu '%d'\n",
+                d->domain_id, v->vcpu_id);
+    } else if (mode_reset & H_PERFMON_ENABLE) {
+        if (!v->arch.pmu_enabled) {
+            DBG("H_PERFMON call on already disabled PMU for domain '%d' on "
+                "vcpu '%d'\n", d->domain_id, v->vcpu_id);
+            goto success;
+        }
+        v->arch.pmu_enabled = 0;
+        perf_count_active_vcpu--;
+        printk("H_PERFMON call disabled PMU for domain '%d' on vcpu '%d'\n",
+                d->domain_id, v->vcpu_id);
+    } else {
+        regs->gprs[3] = H_Parameter;
+    }
+
+success:
+    regs->gprs[3] = H_Success;
+    spin_unlock(&perf_pmu_lock);
+}
+
+__init_papr_hcall(H_PERFMON, h_perfmon);
diff -r a69843c46641 -r 3867217d3155 xen/arch/powerpc/powerpc64/domain.c
--- a/xen/arch/powerpc/powerpc64/domain.c       Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/arch/powerpc/powerpc64/domain.c       Fri Jul 13 17:28:15 2007 -0500
@@ -13,16 +13,48 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005
+ * Copyright IBM Corp. 2005, 2007
  *
  * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ *          Christian Ehrhardt <ehrhardt@xxxxxxxxxxxxxxxxxx>
  */
 
 #include <xen/config.h>
 #include <xen/lib.h>
 #include <xen/sched.h>
 #include <xen/mm.h>
+#include <xen/domain.h>
 #include <asm/current.h>
+
+void save_pmc_sprs(perf_sprs_t *p_sprs)
+{
+    p_sprs->mmcr0 = mfmmcr0();
+    p_sprs->mmcr1 = mfmmcr1();
+    p_sprs->mmcra = mfmmcra();
+    p_sprs->pmc[0] = mfpmc1();
+    p_sprs->pmc[1] = mfpmc2();
+    p_sprs->pmc[2] = mfpmc3();
+    p_sprs->pmc[3] = mfpmc4();
+    p_sprs->pmc[4] = mfpmc5();
+    p_sprs->pmc[5] = mfpmc6();
+    p_sprs->pmc[6] = mfpmc7();
+    p_sprs->pmc[7] = mfpmc8();
+}
+
+void load_pmc_sprs(perf_sprs_t *p_sprs)
+{
+    mtpmc1(p_sprs->pmc[0]);
+    mtpmc2(p_sprs->pmc[1]);
+    mtpmc3(p_sprs->pmc[2]);
+    mtpmc4(p_sprs->pmc[3]);
+    mtpmc5(p_sprs->pmc[4]);
+    mtpmc6(p_sprs->pmc[5]);
+    mtpmc7(p_sprs->pmc[6]);
+    mtpmc8(p_sprs->pmc[7]);
+    mtmmcra(p_sprs->mmcra);
+    mtmmcr1(p_sprs->mmcr1);
+    mtmmcr0(p_sprs->mmcr0);
+}
 
 void save_sprs(struct vcpu *v)
 {
@@ -35,6 +67,11 @@ void save_sprs(struct vcpu *v)
 
     v->arch.dar = mfdar();
     v->arch.dsisr = mfdsisr();
+
+    if (v->arch.pmu_enabled) {
+        save_pmc_sprs(&(v->arch.perf_sprs));
+        v->arch.perf_sprs_stored = 1;
+    }
 
     save_cpu_sprs(v);
 }
@@ -49,6 +86,13 @@ void load_sprs(struct vcpu *v)
     mtsprg3(v->arch.sprg[3]);
     mtdar(v->arch.dar);
     mtdsisr(v->arch.dsisr);
+
+    if (v->arch.pmu_enabled) {
+        if (v->arch.perf_sprs_stored)
+            load_pmc_sprs(&(v->arch.perf_sprs));
+        else
+            load_pmc_sprs(&perf_clear_sprs);
+    }
 
     load_cpu_sprs(v);
 
diff -r a69843c46641 -r 3867217d3155 xen/arch/powerpc/powerpc64/exceptions.S
--- a/xen/arch/powerpc/powerpc64/exceptions.S   Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/arch/powerpc/powerpc64/exceptions.S   Fri Jul 13 17:28:15 2007 -0500
@@ -105,6 +105,12 @@ 1:
     nop
 .endm
 
+.macro PMU_SAVE_STATE scratch
+    mfspr \scratch,SPRN_MMCR0             /* ensure MMCR0[FCH] is 1 */
+    ori \scratch,\scratch,MMCR0_FCH
+    mtspr SPRN_MMCR0, \scratch
+.endm
+
 .macro EXCEPTION_HEAD parea continue
     /* make room for cpu_user_regs */
     subi r1, r1, STACK_VOLATILE_AREA + UREGS_sizeof
@@ -156,7 +162,7 @@ 1:
     ori r0, r0, MSR_RI@l
     mtmsrd r0
 
-
+    PMU_SAVE_STATE r0
 .endm
 
 /* For exceptions that use HSRR0/1 (preserving the OS's SRR0/1). */
@@ -183,6 +189,7 @@ 1:
     ori r0, r0, MSR_RI@l
     mtmsrd r0
 
+    PMU_SAVE_STATE r0
 .endm
 
 /* Hypervisor exception handling code; copied to physical address zero. */
@@ -328,6 +335,12 @@ ex_fp:
     li r0, 0xe00 /* exception vector for GDB stub */
     bctr
 
+    . = 0xf00
+ex_perfmon:
+    GET_STACK r13 SPRN_SRR1
+    EXCEPTION_HEAD r13 ex_perfmon_continued
+    bctr
+
     .align 3
     .globl exception_vectors_end
 
@@ -445,6 +458,16 @@ ex_dec_continued:
 ex_dec_continued:
     EXCEPTION_SAVE_STATE r1
     LOADADDR r12, do_dec
+    mr r3, r1                           /* pass pointer to cpu_user_regs */
+    subi r1, r1, STACK_FRAME_OVERHEAD   /* make a "caller" stack frame */
+    CALL_CFUNC r12
+
+    addi r1, r1, STACK_FRAME_OVERHEAD   /* restore stack to cpu_user_regs */
+    b fast_resume
+
+ex_perfmon_continued:
+    EXCEPTION_SAVE_STATE r1
+    LOADADDR r12, do_perfmon
     mr r3, r1                           /* pass pointer to cpu_user_regs */
     subi r1, r1, STACK_FRAME_OVERHEAD   /* make a "caller" stack frame */
     CALL_CFUNC r12
diff -r a69843c46641 -r 3867217d3155 xen/include/asm-powerpc/domain.h
--- a/xen/include/asm-powerpc/domain.h  Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/include/asm-powerpc/domain.h  Fri Jul 13 17:28:15 2007 -0500
@@ -16,6 +16,7 @@
  * Copyright IBM Corp. 2005, 2007
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ *          Christian Ehrhardt <ehrhardt@xxxxxxxxxxxxxxxxxx>
  */
 
 #ifndef _ASM_DOMAIN_H_
@@ -29,6 +30,17 @@
 #include <public/arch-powerpc.h>
 #include <asm/htab.h>
 #include <asm/powerpc64/ppc970.h>
+
+
+typedef struct {
+    ulong mmcr0;
+    ulong mmcr1;
+    ulong mmcra;
+    ulong pmc[NUM_PMCS];
+} perf_sprs_t;
+
+extern atomic_t perf_count_active;
+extern perf_sprs_t perf_clear_sprs;
 
 struct arch_domain {
     struct domain_htab htab;
@@ -84,7 +96,12 @@ struct arch_vcpu {
     ulong timebase;
     ulong dar;
     ulong dsisr;
-    
+
+    /* performance monitor sprs per vcpu */
+    int pmu_enabled;
+    int perf_sprs_stored;
+    perf_sprs_t perf_sprs;
+
     /* Segment Lookaside Buffer */
     struct slb_entry slb_entries[NUM_SLB_ENTRIES];
 
@@ -102,6 +119,8 @@ extern void full_resume(void);
 
 extern void save_sprs(struct vcpu *);
 extern void load_sprs(struct vcpu *);
+extern void save_pmc_sprs(perf_sprs_t *p_sprs);
+extern void load_pmc_sprs(perf_sprs_t *p_sprs);
 extern void save_segments(struct vcpu *);
 extern void load_segments(struct vcpu *);
 extern void save_float(struct vcpu *);
diff -r a69843c46641 -r 3867217d3155 xen/include/asm-powerpc/papr.h
--- a/xen/include/asm-powerpc/papr.h    Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/include/asm-powerpc/papr.h    Fri Jul 13 17:28:15 2007 -0500
@@ -66,6 +66,7 @@
 #define H_IPOLL                 0x0070  /* Crit Yes             int     */
 #define H_XIRR                  0x0074  /* Crit Yes             int     */
 #define H_MIGRATE_PCI_TCE       0x0078  /* Norm Yes-if LRDR     migrate */
+#define H_PERFMON               0x007c  /* Norm Yes-if PMU      perfmon */
 #define H_CEDE                  0x00e0  /* Crit Yes             splpar  */
 #define H_CONFER                0x00e4
 #define H_PROD                  0x00e8
diff -r a69843c46641 -r 3867217d3155 xen/include/asm-powerpc/processor.h
--- a/xen/include/asm-powerpc/processor.h       Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/include/asm-powerpc/processor.h       Fri Jul 13 17:28:15 2007 -0500
@@ -13,9 +13,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005, 2006
+ * Copyright IBM Corp. 2005, 2006, 2007
  *
  * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ *          Christian Ehrhardt <ehrhardt@xxxxxxxxxxxxxxxxxx>
  */
 
 #ifndef _ASM_PROCESSOR_H_
@@ -200,6 +201,141 @@ static inline ulong mfr1(void)
     return r1;
 }
 
+static inline void mtmmcr0(ulong val)
+{
+    asm volatile ("mtspr %0, %1" : : "i"(SPRN_MMCR0), "r"(val));
+}
+static inline ulong mfmmcr0(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_MMCR0));
+    return rval;
+}
+
+static inline void mtmmcr1(ulong val)
+{
+    asm volatile ("mtspr %0, %1" : : "i"(SPRN_MMCR1), "r"(val));
+}
+static inline ulong mfmmcr1(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_MMCR1));
+    return rval;
+}
+
+static inline void mtmmcra(ulong val)
+{
+    asm volatile ("mtspr %0, %1" : : "i"(SPRN_MMCRA), "r"(val));
+}
+static inline ulong mfmmcra(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_MMCRA));
+    return rval;
+}
+
+static inline void mtpmc1(ulong val)
+{
+    asm volatile ("mtspr %0, %1" : : "i"(SPRN_PMC1), "r"(val));
+}
+static inline ulong mfpmc1(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_PMC1));
+    return rval;
+}
+
+static inline void mtpmc2(ulong val)
+{
+    asm volatile ("mtspr %0, %1" : : "i"(SPRN_PMC2), "r"(val));
+}
+static inline ulong mfpmc2(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_PMC2));
+    return rval;
+}
+
+static inline void mtpmc3(ulong val)
+{
+    asm volatile ("mtspr %0, %1" : : "i"(SPRN_PMC3), "r"(val));
+}
+static inline ulong mfpmc3(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_PMC3));
+    return rval;
+}
+
+static inline void mtpmc4(ulong val)
+{
+    asm volatile ("mtspr %0, %1" : : "i"(SPRN_PMC4), "r"(val));
+}
+static inline ulong mfpmc4(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_PMC4));
+    return rval;
+}
+
+static inline void mtpmc5(ulong val)
+{
+    asm volatile ("mtspr %0, %1" : : "i"(SPRN_PMC5), "r"(val));
+}
+static inline ulong mfpmc5(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_PMC5));
+    return rval;
+}
+
+static inline void mtpmc6(ulong val)
+{
+    asm volatile ("mtspr %0, %1" : : "i"(SPRN_PMC6), "r"(val));
+}
+static inline ulong mfpmc6(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_PMC6));
+    return rval;
+}
+
+static inline void mtpmc7(ulong val)
+{
+    asm volatile ("mtspr %0, %1" : : "i"(SPRN_PMC7), "r"(val));
+}
+static inline ulong mfpmc7(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_PMC7));
+    return rval;
+}
+
+static inline void mtpmc8(ulong val)
+{
+    asm volatile ("mtspr %0, %1" : : "i"(SPRN_PMC8), "r"(val));
+}
+static inline ulong mfpmc8(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_PMC8));
+    return rval;
+}
+
+static inline ulong mfsdar(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_SDAR));
+    return rval;
+}
+
+static inline ulong mfsiar(void)
+{
+    ulong rval;
+    asm volatile ("mfspr %0, %1" : "=r"(rval) : "i"(SPRN_SIAR));
+    return rval;
+}
+
 static inline void mtsprg0(ulong val)
 {
     __asm__ __volatile__ ("mtspr %0, %1" : : "i"(SPRN_SPRG0), "r"(val));
diff -r a69843c46641 -r 3867217d3155 xen/include/asm-powerpc/reg_defs.h
--- a/xen/include/asm-powerpc/reg_defs.h        Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/include/asm-powerpc/reg_defs.h        Fri Jul 13 17:28:15 2007 -0500
@@ -13,9 +13,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005
+ * Copyright IBM Corp. 2005, 2007
  *
  * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ *          Christian Ehrhardt <ehrhardt@xxxxxxxxxxxxxxxxxx>
  */
 
 #ifndef _ASM_REG_DEFS_H_
@@ -166,8 +167,32 @@
 #define SPRN_LPCR   318
 #define SPRN_LPIDR  319
 
+/* Performance monitor spr encodings */
+#define SPRN_MMCRA  786
+#define   MMCRA_SAMPHV    UL(0x10000000) /* state of MSR HV when SIAR set */
+#define   MMCRA_SAMPPR    UL(0x08000000) /* state of MSR PR when SIAR set */
+#define   MMCRA_SAMPLE_ENABLE UL(0x00000001) /* enable sampling */
+#define NUM_PMCS 8
+#define SPRN_PMC1   787
+#define SPRN_PMC2   788
+#define SPRN_PMC3   789
+#define SPRN_PMC4   790
+#define SPRN_PMC5   791
+#define SPRN_PMC6   792
+#define SPRN_PMC7   793
+#define SPRN_PMC8   794
+#define SPRN_MMCR0  795
+#define   MMCR0_FC      UL(0x80000000) /* freeze counters */
+#define   MMCR0_FCS     UL(0x40000000) /* freeze in supervisor state */
+#define   MMCR0_FCP     UL(0x20000000) /* freeze in problem state */
+#define   MMCR0_FCM1    UL(0x10000000) /* freeze counters while MSR mark = 1 */
+#define   MMCR0_FCM0    UL(0x08000000) /* freeze counters while MSR mark = 0 */
+#define   MMCR0_PMAE    UL(0x04000000) /* performance monitor alert enabled */
+#define   MMCR0_PMAO    UL(0x00000080) /* performance monitor alert occurred */
+#define   MMCR0_FCH     UL(0x00000001) /* freeze conditions in hypervisor */
 #define SPRN_SIAR   796
 #define SPRN_SDAR   797
+#define SPRN_MMCR1  798
 
 /* As defined for PU G4 */
 #define SPRN_HID0   1008
diff -r a69843c46641 -r 3867217d3155 xen/include/asm-powerpc/xenoprof.h
--- a/xen/include/asm-powerpc/xenoprof.h        Fri Jul 13 15:23:24 2007 -0500
+++ b/xen/include/asm-powerpc/xenoprof.h        Fri Jul 13 17:28:15 2007 -0500
@@ -21,6 +21,80 @@
 #ifndef __ASM_PPC_XENOPROF_H__
 #define __ASM_PPC_XENOPROF_H__
 
-/* unimplemented */
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/sched.h>
+#include <public/xen.h>
+
+/* All the classic PPC parts use these */
+static inline unsigned int ctr_read(unsigned int i)
+{
+       switch(i) {
+       case 0:
+               return mfpmc1();
+       case 1:
+               return mfpmc2();
+       case 2:
+               return mfpmc3();
+       case 3:
+               return mfpmc4();
+       case 4:
+               return mfpmc5();
+       case 5:
+               return mfpmc6();
+       case 6:
+               return mfpmc7();
+       case 7:
+               return mfpmc8();
+       default:
+               return 0;
+       }
+}
+
+static inline void ctr_write(unsigned int i, unsigned int val)
+{
+       switch(i) {
+       case 0:
+               mtpmc1(val);
+               break;
+       case 1:
+               mtpmc2(val);
+               break;
+       case 2:
+               mtpmc3(val);
+               break;
+       case 3:
+               mtpmc4(val);
+               break;
+       case 4:
+               mtpmc5(val);
+               break;
+       case 5:
+               mtpmc6(val);
+               break;
+    case 6:
+        mtpmc7(val);
+        break;
+    case 7:
+        mtpmc8(val);
+        break;
+    default:
+        break;
+    }
+}
+
+static inline void print_perf_status()
+{
+    ulong mmcr0 = mfmmcr0();
+    ulong mmcr1 = mfmmcr1();
+    ulong mmcra = mfmmcra();
+    ulong sdar = mfsdar();
+    ulong siar = mfsiar();
+    printk("MMCR0 0x%0lX\n",mmcr0);
+    printk("MMCR1 0x%0lX\n",mmcr1);
+    printk("MMCRA 0x%0lX\n",mmcra);
+    printk("SIAR 0x%0lX\n",siar);
+    printk("SDAR 0x%0lX\n",sdar);
+}
 
 #endif

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.