common.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2004 by Ralf Baechle
  7. */
  8. #include <linux/errno.h>
  9. #include <linux/init.h>
  10. #include <linux/oprofile.h>
  11. #include <linux/smp.h>
  12. #include <asm/cpu-info.h>
  13. #include "op_impl.h"
  14. extern struct op_mips_model op_model_mipsxx __attribute__((weak));
  15. extern struct op_mips_model op_model_rm9000 __attribute__((weak));
  16. static struct op_mips_model *model;
  17. static struct op_counter_config ctr[20];
  18. static int op_mips_setup(void)
  19. {
  20. /* Pre-compute the values to stuff in the hardware registers. */
  21. model->reg_setup(ctr);
  22. /* Configure the registers on all cpus. */
  23. on_each_cpu(model->cpu_setup, 0, 0, 1);
  24. return 0;
  25. }
  26. static int op_mips_create_files(struct super_block * sb, struct dentry * root)
  27. {
  28. int i;
  29. for (i = 0; i < model->num_counters; ++i) {
  30. struct dentry *dir;
  31. char buf[3];
  32. snprintf(buf, sizeof buf, "%d", i);
  33. dir = oprofilefs_mkdir(sb, root, buf);
  34. oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
  35. oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
  36. oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
  37. /* Dummies. */
  38. oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
  39. oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
  40. oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
  41. oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
  42. }
  43. return 0;
  44. }
  45. static int op_mips_start(void)
  46. {
  47. on_each_cpu(model->cpu_start, NULL, 0, 1);
  48. return 0;
  49. }
  50. static void op_mips_stop(void)
  51. {
  52. /* Disable performance monitoring for all counters. */
  53. on_each_cpu(model->cpu_stop, NULL, 0, 1);
  54. }
  55. void __init oprofile_arch_init(struct oprofile_operations *ops)
  56. {
  57. struct op_mips_model *lmodel = NULL;
  58. switch (current_cpu_data.cputype) {
  59. case CPU_24K:
  60. lmodel = &op_model_mipsxx;
  61. break;
  62. case CPU_RM9000:
  63. lmodel = &op_model_rm9000;
  64. break;
  65. };
  66. if (!lmodel)
  67. return;
  68. if (lmodel->init())
  69. return;
  70. model = lmodel;
  71. ops->create_files = op_mips_create_files;
  72. ops->setup = op_mips_setup;
  73. ops->start = op_mips_start;
  74. ops->stop = op_mips_stop;
  75. ops->cpu_type = lmodel->cpu_type;
  76. printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
  77. lmodel->cpu_type);
  78. }
  79. void oprofile_arch_exit(void)
  80. {
  81. model->exit();
  82. }