📄 common.c
字号:
/** * @file arch/alpha/oprofile/common.c * * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING * * @author Richard Henderson <rth@twiddle.net> */#include <linux/oprofile.h>#include <linux/init.h>#include <linux/smp.h>#include <linux/errno.h>#include <asm/ptrace.h>#include <asm/system.h>#include "op_impl.h"extern struct op_axp_model op_model_ev4 __attribute__((weak));extern struct op_axp_model op_model_ev5 __attribute__((weak));extern struct op_axp_model op_model_pca56 __attribute__((weak));extern struct op_axp_model op_model_ev6 __attribute__((weak));extern struct op_axp_model op_model_ev67 __attribute__((weak));static struct op_axp_model *model;extern void (*perf_irq)(unsigned long, struct pt_regs *);static void (*save_perf_irq)(unsigned long, struct pt_regs *);static struct op_counter_config ctr[20];static struct op_system_config sys;static struct op_register_config reg;/* Called from do_entInt to handle the performance monitor interrupt. */static voidop_handle_interrupt(unsigned long which, struct pt_regs *regs){ model->handle_interrupt(which, regs, ctr); /* If the user has selected an interrupt frequency that is not exactly the width of the counter, write a new value into the counter such that it'll overflow after N more events. */ if ((reg.need_reset >> which) & 1) model->reset_ctr(®, which);} static intop_axp_setup(void){ unsigned long i, e; /* Install our interrupt handler into the existing hook. */ save_perf_irq = perf_irq; perf_irq = op_handle_interrupt; /* Compute the mask of enabled counters. */ for (i = e = 0; i < model->num_counters; ++i) if (ctr[i].enabled) e |= 1 << i; reg.enable = e; /* Pre-compute the values to stuff in the hardware registers. */ model->reg_setup(®, ctr, &sys); /* Configure the registers on all cpus. */ (void)smp_call_function(model->cpu_setup, ®, 0, 1); model->cpu_setup(®); return 0;}static voidop_axp_shutdown(void){ /* Remove our interrupt handler. We may be removing this module. */ perf_irq = save_perf_irq;}static voidop_axp_cpu_start(void *dummy){ wrperfmon(1, reg.enable);}static intop_axp_start(void){ (void)smp_call_function(op_axp_cpu_start, NULL, 0, 1); op_axp_cpu_start(NULL); return 0;}static inline voidop_axp_cpu_stop(void *dummy){ /* Disable performance monitoring for all counters. */ wrperfmon(0, -1);}static voidop_axp_stop(void){ (void)smp_call_function(op_axp_cpu_stop, NULL, 0, 1); op_axp_cpu_stop(NULL);}static intop_axp_create_files(struct super_block * sb, struct dentry * root){ int i; for (i = 0; i < model->num_counters; ++i) { struct dentry *dir; char buf[3]; snprintf(buf, sizeof buf, "%d", i); dir = oprofilefs_mkdir(sb, root, buf); oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); /* Dummies. */ oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask); } if (model->can_set_proc_mode) { oprofilefs_create_ulong(sb, root, "enable_pal", &sys.enable_pal); oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel); oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user); } return 0;}int __initoprofile_arch_init(struct oprofile_operations *ops){ struct op_axp_model *lmodel = NULL; switch (implver()) { case IMPLVER_EV4: lmodel = &op_model_ev4; break; case IMPLVER_EV5: /* 21164PC has a slightly different set of events. Recognize the chip by the presence of the MAX insns. */ if (!amask(AMASK_MAX)) lmodel = &op_model_pca56; else lmodel = &op_model_ev5; break; case IMPLVER_EV6: /* 21264A supports ProfileMe. Recognize the chip by the presence of the CIX insns. */ if (!amask(AMASK_CIX)) lmodel = &op_model_ev67; else lmodel = &op_model_ev6; break; } if (!lmodel) return -ENODEV; model = lmodel; ops->create_files = op_axp_create_files; ops->setup = op_axp_setup; ops->shutdown = op_axp_shutdown; ops->start = op_axp_start; ops->stop = op_axp_stop; ops->cpu_type = lmodel->cpu_type; printk(KERN_INFO "oprofile: using %s performance monitoring.\n", lmodel->cpu_type); return 0;}voidoprofile_arch_exit(void){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -