source: trunk/packages/xen-3.1/xen-3.1/xen/arch/ia64/xen/oprofile/perfmon.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 4.5 KB
Line 
1/******************************************************************************
2 * perfmon.c for xenoprof
3 * This is based linux/arch/ia64/oprofile/perfmon.c, but heavily rewritten.
4 *
5 * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
6 *                    VA Linux Systems Japan K.K.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 *
22 */
23/**
24 * @file perfmon.c
25 *
26 * @remark Copyright 2003 OProfile authors
27 * @remark Read the file COPYING
28 *
29 * @author John Levon <levon@movementarian.org>
30 */
31
32#include <xen/config.h>
33#include <xen/sched.h>
34#include <xen/event.h>
35#include <xen/xenoprof.h>
36#include <asm/perfmon.h>
37#include <asm/ptrace.h>
38
39// XXX move them to an appropriate header file
40extern void xenoprof_log_event(struct vcpu *vcpu,
41                               unsigned long eip, int mode, int event);
42extern int is_active(struct domain *d);
43
44static int allow_virq;
45static int allow_ints;
46
47static int
48xenoprof_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg,
49                 struct pt_regs *regs, unsigned long stamp)
50{
51    unsigned long ip = regs->cr_iip;
52    int event = arg->pmd_eventid;
53 
54    arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1;
55    if (!allow_virq || !allow_ints)
56        return 0;
57
58    xenoprof_log_event(current, ip, xenoprofile_get_mode(task, regs), event);
59   
60    // send VIRQ_XENOPROF
61    if (is_active(current->domain) && !ring_0(regs))
62        send_guest_vcpu_virq(current, VIRQ_XENOPROF);
63
64    return 0;
65}
66
67// same as linux OPROFILE_FMT_UUID
68#define XENOPROF_FMT_UUID { \
69    0x77, 0x7a, 0x6e, 0x61, 0x20, 0x65, 0x73, 0x69, 0x74, 0x6e, 0x72, 0x20, 0x61, 0x65, 0x0a, 0x6c }
70
71static pfm_buffer_fmt_t xenoprof_fmt = {
72    .fmt_name    = "xenoprof_format",
73    .fmt_uuid    = XENOPROF_FMT_UUID,
74    .fmt_handler = xenoprof_handler,
75};
76
77static char * get_cpu_type(void)
78{
79    __u8 family = local_cpu_data->family;
80
81    switch (family) {
82        case 0x07:
83            return "ia64/itanium";
84        case 0x1f:
85            return "ia64/itanium2";
86        default:
87            return "ia64/ia64";
88    }
89}
90
91static int using_xenoprof;
92
93int __init
94xenprof_perfmon_init(void)
95{
96    int ret = pfm_register_buffer_fmt(&xenoprof_fmt);
97    if (ret)
98        return -ENODEV;
99    using_xenoprof = 1;
100    printk("xenoprof: using perfmon.\n");
101    return 0;
102}
103__initcall(xenprof_perfmon_init);
104
105#ifdef notyet
106void xenoprof_perfmon_exit(void)
107{
108    if (!using_xenoprof)
109        return;
110
111    pfm_unregister_buffer_fmt(xenoprof_fmt.fmt_uuid);
112}
113__exitcall(xenoprof_perfmon_exit);
114#endif
115
116///////////////////////////////////////////////////////////////////////////
117// glue methods for xenoprof and perfmon.
118int
119xenoprof_arch_init(int *num_events, int *is_primary, char *cpu_type)
120{
121    *num_events = 0;
122    strlcpy(cpu_type, get_cpu_type(), XENOPROF_CPU_TYPE_SIZE);
123
124    *is_primary = 0;
125    if (xenoprof_primary_profiler == NULL) {
126        /* For now, only dom0 can be the primary profiler */
127        if (current->domain->domain_id == 0) {
128            *is_primary = 1;
129        }
130    } else if (xenoprof_primary_profiler == current->domain)
131        *is_primary = 1;
132    return 0;
133}
134
135int
136xenoprof_arch_reserve_counters(void)
137{
138    // perfmon takes care
139    return 0;
140}
141
142int
143xenoprof_arch_counter(XEN_GUEST_HANDLE(void) arg)
144{
145    return -ENOSYS;
146}
147
148int
149xenoprof_arch_setup_events(void)
150{
151    // perfmon takes care
152    return 0;
153}
154
155//XXX SMP: sync by IPI?
156int
157xenoprof_arch_enable_virq(void)
158{
159    allow_virq = 1;
160    return 0;
161}
162
163//XXX SMP: sync by IPI?
164int
165xenoprof_arch_start(void)
166{
167        allow_ints = 1;
168    return 0;
169}
170
171//XXX SMP: sync by IPI?
172void
173xenoprof_arch_stop(void)
174{
175        allow_ints = 0;
176}
177
178//XXX SMP: sync by IPI?
179void
180xenoprof_arch_disable_virq(void)
181{
182    allow_virq = 0;
183}
184
185void
186xenoprof_arch_release_counters(void)
187{
188    // perfmon takes care
189}
190
191/*
192 * Local variables:
193 * mode: C
194 * c-set-style: "BSD"
195 * c-basic-offset: 4
196 * tab-width: 4
197 * indent-tabs-mode: nil
198 * End:
199 */
Note: See TracBrowser for help on using the repository browser.